Egy tömb vagy angol nevén array egy adatszerkezet, ami fix darab ugyanolyan típusú objektumot képes tárolni.
Létrehozás
Például, létre tudunk hozni egy 10 elemű egész számokból álló tömböt és ezt eltárolni egy int tömb típusú változóba a következőképp:
int[] myArray; // Deklarálok egy int tömb típusú változót: típus[]
myArray = new int[10]; // Létrehozok egy 10 elemű int tömböt és eltárolom a változóban
// Ebben a tömbben tehát nem csak egy, de 10 int értéket is el tudunk tárolni.
A tömbök használata adott típusok tömeges tárolására biztosítja a programozóknak.
Egy újonnan létrehozott tömb elemei, mindig az adott típus alapértelmezett (default) értékei lesznek. Egy int tömb elemei például 0-k lesznek.
int[] myArray = new int[10];
// A myArray elemei az alábbiak lennének:
// { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
Emellett tömböt úgy is létre tudunk hozni, hogy nem a hosszát adjuk meg, hanem a kezdeti elemeket egyenként.
// Létrehozok egy 3 elemű string tömböt
string[] myFruits = new string[] { "Alma", "Körte", "Barack" };
// Előre feltöltött tömb egyszerűbb szintaktikával is létrehozhat:
// Létrehozok egy 5 elemű int tömböt
int[] myLottoNumbers = { 1, 5, 37, 55, 90 };
Indexelés
Fontos tulajdonsága a tömbnek, hogy egyes elemei nincsenek nevesítve, csak egy index-nek nevezett sorszámon keresztül tudunk hozzáférni.
Az indexek 0-ás értéktől kezdődnek, és az utolsó elem indexe mindig eggyel kevesebb, mint a tömb mérete. Például, egy 10 elemű tömb utolsó elemének indexe 9 lesz.
Az index-t lehet használni a tömb elemeihez való hozzáférésre:
int[] myArray = new int[10];
myArray[0] = 3; // A tömbünk első (0-ás indexű) elemének értékét beállítjuk 3-ra.
// Új értékek { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
myArray[4] = 86; // A tömbünk ötödik (4-es indexű) elemének értékét beállítjuk 86-ra.
// Új értékek { 3, 0, 0, 0, 86, 0, 0, 0, 0, 0 }
int myInt = myArray[2] // A harmadik (2-es indexű) elemet eltároljuk külön változóba.
Console.WriteLine(myIntArray[7]); // A nyolcadik (7-es indexű) elemet kiírjuk.
Tömböket fel lehet tölteni akár ciklusok segítségével is.
Ehhez tudni kell, hogy milyen hosszú a tömb, azaz hány elemből áll. Ez minden tömb esetén lekérdezhető a Length
property-vel. Pl.: int length = myArray.Length;
Például, ha szeretnénk egy int tömböt feltölteni úgy, hogy 0-val kezdődik, és minden elemének értékét 2-vel növekszik, akkor a következő megoldást használhatjuk:
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = i * 2;
}
// Új értékek egy 10 elemű tömb esetén { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 }
A ciklusok használatával tömböket lehet feltölteni komplexebb logikával is, ami lehetővé teszi a tömb elemeinek egymáshoz képesti feltöltését.
A tömbök elemei a memóriában mindig szorosan egymás mellett helyezkednek el. Mikor egy tömböt létrehozunk, akkor mindig pont akkora memóriaterület foglal le a program, az adat számára, amekkora egy elem mérete szorozva a tömb hosszával.
Tehát minden egyes elem memória beli pozíciója megkapható így: tömb memóriahelye + (index * egy elem mérete a memóriában)
Ez az oka, hogy a tömb indexelése 0-val kezdődik nem 1-gyel. Ez majdnem minden programozási nyelvben hasonlóan működik.
Túlindexelés
Ha hibás indexet adunk meg egy tömbhöz, például egy negatív számot, vagy olyat, ami nagyobb (vagy egyenlő) mint a tömb hossza, akkor azt túlindexelésnek nevezzük. Ez a programban futás közbeni hibát fog okozni, hiszen a olyan memóriaterülethez próbálunk hozzáférni, ami nem tartozik az adott tömbhöz.
Az error, amit ekkor kapunk az IndexOutOfRangeException
nevet fogja viselni.
A tömb hossza
A tömbök mindig fix méretűek, ezt jelenti az, hogy a tömb létrehozásakor megadott hosszt később nem lehet meg változtatni.
Ahhoz, hogy egy tömb méretét megváltoztassuk, új tömböt kell létrehozni és az eredeti tömb adatait át kell másolni.
string[] myFruits = new string[]{ "Alma", "Körte", "Barack" }; // Eredeti tömb
// Új töm létrehozása 1-gyel több elemszámmal
string[] myFruits2 = new string[myFruits.Length + 1];
// Átmásolom az eredeti tömb tartalmát az újba:
for (int i = 0; i < myFruits.Length; i++)
{
myFruits2[i] = myFruits[i];
}
// Utolsó elem egy új érték:
myFruits2[myFruits.Length - 1] = "Szilva";
Erre a gyakorlatban általában Listát használunk, ami egy rugalmasabb változata a tömbnek.
Lásd: Listák és a Foreach ciklus
Kiegészítő anyag: Tömb indexelése hátulról és tartomány indexelés
A tömb hosszának lekérdezése segítségével lehetséges hátulról indexelni egy tömböt. Ne feledjük, ilyenkor a (tömb hossza - 1)-es index fogja jelölni az utolsó elemet!
var item = array[array.Length - 1]; // Utolsó elem
A C# 8-adik verziójától kezdődően lehetséges hátulról indexelni. (A C# 8 a Unity 2020-tól kezdve támogatott)
var item = array[array.Length - 3]; // Hátulról harmadik elem
var item = array[^3]; // Ugyanaz egyszerűbben leírva (C# 8-tól)
//Példa:
string[] words =
{ // index from start index from end
"indexing", // 0 ^6
"is", // 1 ^5
"easier", // 2 ^4
"than", // 3 ^3
"it", // 4 ^2
"looks", // 5 ^1
};
Ugyanezen C# verziótól kezdődően lehetőség van tartomány-indexelésre, aminek eredménye egy tömb lesz. Ehhez a ..
operátort használjuk, ami elé és mögé is írhatunk indexet.
- A
..
bal oldalára kerül, hogy melyik indextől indulunk. (Inclusive index) - A
..
jobb oldalára kerül, hogy melyik indexig már nem megyünk el. (Exclusive index)
// Példák a fenti tesz lista alapján:
string[] a1 = words[1..4]; // { "is", "easier", "than" }
string[] a2 = words[2..6]; // { "easier", "than", "it", "looks" }
string[] a3 = words[2..3]; // { "easier"}
// A két operandus elhagyható. Ekkor automatikusan a legszélső elemtől számolunk:
string[] a4 = words[..3]; // { "indexing", "is", "easier" }
string[] a5 = words[2..]; // { "easier", "than", "it", "looks" }
string[] a6 = words[..]; // { "indexing", "is", "easier", "than", "it", "looks" }
// A tartomány indexelés kombinálható a hátulról indexeléssel:
string[] a7 = words[0..^0]; // { "indexing", "is", "easier", "than", "it", "looks" }
string[] a8 = words[4..^0]; // { "it", "looks" }
string[] a9 = words[^3..^1]; // { "than", "it" }
A string mint karaktertömb
A char
típus egy primitív (C#-ba beépített), egy karakter hosszúságú értéktípus.
A char
nem fogalma nem egyezik meg a betű fogalmával char
objektum lehet nem csak betű, de szám vagy bármilyen különleges karakter is.
char myChar1 = 'A', myChar2 = 'f', myChar3 = '1', myChar4 = '!', myChar5 = '$';
// A char típusú elemeket aposztrófok közé írjuk.
Egy string
gyakorlatilag char
típusok tömbje. Átalakítani a két típus közt a következőképp lehet:
string myString = "Bear"; // 🐻
char[] myCharArray = myString.ToCharArray(); // String-et char tömbbé alakítjuk
myCharArray[2] = 'e'; // 🍺
string myNewString = new string(myCharArray); // Char tömböt stringgé alakítjuk
Pár hasznos tömb művelet:
IndexOf()
: Megkeresi egy tömbben egy adott elem indexét.
Visszatérési értéke az elem indexe, ha megtalálta, különben -1.
string[] array = { "Aa", "Bb", "Cc", "Dd", "Ee" };
int index = Array.IndexOf(array, "Bb"); // Megkeresi egy elem indexét
// Használható arra is, hogy megállapítsuk, egy lista tartalmaz-e egy adott elemet.
bool containsItem = Array.IndexOf(array, "Ee") != -1;
Reverse()
: A tömb elemeinek megfordítása
numbers[] = {1, 2, 3, 4, 5};
Array.Reverse(numbers);
Sort()
: A lista elemeit rendezi.
numbers[] = {3, 7, 5, 1, 4};
Array.Sort(numbers);
Utóbbi két művelet (Reverse()
és Sort()
) csak olyan típusokon működik, amiken valami módon értelmezett a kisebb-nagyobb viszony. Pl.: számok, sztringek (ABC sorrend)
(A sorba rendezésről bővebben itt: Sorozatok rendezése)
Copy()
Tömb elemeinek másolás egy másik tömbbe.
Három paraméteres metódus: 1. Honnan? 2. Hová? 3. Milyen hosszan?
string[] array = { "Aa", "Bb", "Cc", "Dd", "Ee" };
string[] copy = new string[3];
Array.Copy(array, copy, 3); // { "Aa", "Bb", "Cc" }