====== Adatszerkezetek ====== Alapfogalmak: adat konstans változó típus Referencia vs. Érték /.NET típusok és megfeleltetések/ struktura, osztály (partial class .NET 2.0) tömb, láncolt lista (generikus osztályok .NET 2.0) Adattárolás változókban. Minden változónak típusa és értéke van. Változó neve: * unicode kódolású betű, számjegy, "_" jel * első karaktere: betű, esetleg "_" * kis- és nagybetűk különbözőek (case-sensitive) * kulcsó nem lehet változónév Ajánlás: beszédes neveket használj, egy [[oktatas:informatika:programozas:dotnet:c-sharp:nevkonvencio]]hoz ragaszkodj. - Változó bevezetése (memória foglalás, típus deklarálás): adattípusNév változóNév; - Értékadás az értékadó operátorral: = (1 egyenlőségjel): változóNév = érték; vagy bevezetés közvetlen értékadással:adattípusNév változóNév = kezdőérték; ===== .NET beépítettnek megfelelő c# típusai ===== A keretrendszer (pontosabban a [[oktatas:informatika:programozas:dotnet:cts]]) erősen típusos, így minden objektumnak megköveteli a pontos típusát. A típus meghatározza a tárolás formáját, és a rajtuk végezhető műveleteket. ''???Szükséges és elégséges feltétel ez típuskompatibilitáshoz...???'' Alapvetően kétféle típust különböztet meg, melyek közti különbség igen jelentős és nem ismeretük érdekes meglepetéseket hordozhat magában. [[informatika:programozas:dotnet:c-sharp:ertek_tipus]]ok: - számváltozók (strukturák) - egészek: ''(u)int, (u)short, (u)long, (s)byte, char'' - lebegőpontosok((A nullához közeli osztás pontossága rossz. Lásd: D. E. Knuth: A számítógép-programozás művészete)): ''float'' (7 tizedesig), ''double'' (15 tizedesig) - tizedestörtek: ''double'' (28 tizedesjegyig) - logikai értékek: ''bool'' D={true, false} - stringek: ''string'' ~ System.[[oktatas:informatika:programozas:dotnet:c-sharp:string]]. A string System.Char strukturák egymásutánjából (gyűjteményéből) álló beépített [[informatika:programozas:dotnet:c-sharp:lezart]] osztály. Csak-olvashatónak nevezik, mert a karakterek közvetlenül nem változtathatók meg az értékadás után benne((bővebben: ''System.Text.StringBuilder''))! - konstansok: fordítási időben kapnak értéket, amit futás közben már nem változtathatnak. Gyakran [[literálok]]kal adunk értéket, melyek típusát utótagokkal ([[oktatas:informatika:programozas:dotnet:c-sharp:suffix]]) határozhatjuk meg. - felsorolás: ''[[#enum]]'' - struktúrák: ''[[#struct]]'' public const double PI = 3.1415M; // egyébként System.Math.PI adattag. System.Int32 i = 2; // .NET típus int j = 3; // System.Int32 decimal d = 2M; /* M: utótaggal (suffix) jelöljük, hogy 2 most nem egész értelmű. Megjegyzés: lehetne 2 is, ekkor a fordító implicit konvertálja az intből a bővebb decimal típusra. */ char c = '\n'; // ' aposztrof bool igaz = true; string s = "szöveg"; // " idézőjel **Tipikus hiba: figyelj az [[informatika:programozas:dotnet:c-sharp:implicit_konverzio]]ra!** Referencia/hivatkozási típusok: - osztályok - interface-ek - tömbök - delegáltak **Tipikus hiba: figyelj arra, hogy mi ref, és mi érték típusú!** ... ===== Felsorolás ===== Az enumeration típusokkal olyan változókat hozhatunk létre, melyek értéke egy általunk meghatározott halmaz egy eleme. Így például a napok sorszáma helyett a nevükkel hivatkozhatunk rájuk. (pl. //1// helyett //Napok.Hétfő//) A felsorolás alapja nem csak az alapértelmezett int típus lehet: (s)byte, (u)int, (u)short, (u)long. Alapjául a System.Enum osztály szolgál. using System; public class EnumTest { enum Napok { Hétfő=1, Kedd, Szerda, Csütörtök, Péntek, Szombat, Vasárnap } // Figyelem, a felsorolás típus is 0-tól indexelődik! // Mi most módosítottuk az első elem indexét 1-re. enum Flag : sbyte { Ki, Be } // a felsorolás alapja most int helyett byte static void Main() { int x = (int)Napok.Hétfő; // =1 lásd még explicit konvertálás (cast) Napok ma = (Napok)3; // =Szerda } } megj: speciálisan System.FlagsAttribute attributummal módosítható az enum viselkedése, és maszkolhatóra változik (bitenkénti or, xor). ===== Tömb ===== A tömb változó azonos típusú adatok tárolását valóstja meg. A memóriában a tömb elemei egymás után helyezkednek el, elérésük így gyors (szorzás --> shiftelés) és egyszerű. Indexelése 0-tól indul. Deklaráció után példányosítani kell (hogy a tényleges memóriafoglalás is megtörténjen). Példányosításkor kötelezően méretet kell adni, ami később dinamikusan nem változtatható. (Ez olykor hátrányos is lehet, lásd láncolt listák). class TömbPélda { public void Main() { string[] T; T = new string[2]; T[0] = "a nulladik indexű tömb elem"; T[1] = "az első indexű tömb elem, több nem lehet, a T két elemű"; // T[2] = "itt kivétel váltódna ki, hiszen ez már a tömb harmadik eleme"; uint elemszám = T.Length; // a tömb elemszáma az objektum Length adattagjával is elérhető /* rövidebben így írható: */ string[] T2 = new T[2] { "nulladik", "első" }; /* egy tipikus bejárási mód */ int összeg = 0; for( int i = 0; i Kettő-, három- vagy többdimenziós tömbök is deklarálhatók, de használatuk nem javasolt. Álalában saját adatszerkezettel egyszerűbb, átláthatóbb és kevesebb memóriát foglaló megoldások születnek. Természetesen ez az ajánlás nem általános érvényű. ===== Láncolt Lista ===== using System.Collections.Generic; class LLPélda { public void Main() { List Prímek = new List(); Prímek.Add(2); Prímek.Add(3); Prímek.Add(5); Prímek.Add(7); foreach( int p in Prímek ) { System.Console.Write(p.ToString()+"\n"); } } } ===== Szöveges állomány ===== ==== Szöveges állomány olvasása ==== Olvasás szöveges állományból soronként: int counter = 0; string line; // Read the file and display it line by line. System.IO.StreamReader file = new System.IO.StreamReader("c:\\test.txt"); while((line = file.ReadLine()) != null) { Console.WriteLine(line); counter++; } file.Close(); // Suspend the screen. Console.ReadLine(); Teljes szöveges állomány beolvasása egy stirngbe, vagy egy string-eket tartalmazó tömbbe: class ReadFromFile { static void Main() { // The files used in this example are created in the topic // How to: Write to a Text File. You can change the path and // file name to substitute text files of your own. // Example #1 // Read the file as one string. string text = System.IO.File.ReadAllText(@"C:\Users\Public\TestFolder\WriteText.txt"); // Display the file contents to the console. Variable text is a string. System.Console.WriteLine("Contents of WriteText.txt = {0}", text); // Example #2 // Read each line of the file into a string array. Each element // of the array is one line of the file. string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Public\TestFolder\WriteLines2.txt"); // Display the file contents by using a foreach loop. System.Console.WriteLine("Contents of WriteLines2.txt = "); foreach (string line in lines) { // Use a tab to indent each line of the file. Console.WriteLine("\t" + line); } // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } } Szöveges állomány beolvasása kivétel-kezeléssel: using System; using System.IO; class Test { public static void Main() { try { using (StreamReader sr = new StreamReader("TestFile.txt")) { String line = sr.ReadToEnd(); Console.WriteLine(line); } } catch (Exception e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); } } } ==== Szöveges állomány írása ==== Írás szöveges állományba soronként: // Compose a string that consists of three lines. string lines = "First line.\r\nSecond line.\r\nThird line."; // Write the string to a file. System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test.txt"); file.WriteLine(lines); file.Close(); Esetleg keletkező kivételek: * Ha az állomány létezik, de csak olvasható (IOException). * Ha az elérési út túl hosszú (PathTooLongException). * Ha a lemez megtelt (IOException). Ha az esetleg már létező állományt nem akarjuk felülírni, hanem inkább hozzáfűznénk (append) újabb adatokat, akkor meg kell adni a konstruktor hívásakor a második, logikai típusú paraméterben az igaz értéket. System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test.txt", true);