Array-uri
Array-ul reprezintă un set de date de același tip. Declarația unui array este similară cu declarația unei variabile, cu excepția că după specificarea tipului se folosesc paranteze pătrate:
tip_variabilă[] nume_array;
De exemplu, să definim un array de numere întregi:
int[] numbers;
După definirea variabilei array, îi putem atribui o anumită valoare:
int[] nums = new int[4];
Aici am declarat array-ul nums, care va stoca date de tip int. Apoi, folosind operația new, am alocat memorie pentru 4 elemente ale array-ului: new int[4]. Numărul 4 este numit lungimea array-ului. În cazul unei astfel de declarații, toate elementele primesc valoarea implicită prevăzută pentru tipul lor. Pentru tipul int, valoarea implicită este 0.
De asemenea, putem specifica imediat valorile pentru aceste elemente:
int[] nums2 = new int[4] { 1, 2, 3, 5 };
int[] nums3 = new int[] { 1, 2, 3, 5 };
int[] nums4 = new[] { 1, 2, 3, 5 };
int[] nums5 = { 1, 2, 3, 5 };
Toate metodele menționate mai sus sunt echivalente.
În mod similar, putem defini array-uri de alte tipuri, de exemplu, un array de valori de tip string:
string[] people = { "Tom", "Sam", "Bob" };
Începând cu versiunea C# 12, pentru definirea array-urilor se pot folosi expresii de colecții, care presupun plasarea elementelor array-ului între paranteze pătrate:
int[] nums1 = [ 1, 2, 3, 5 ];
int[] nums2 = []; // array gol
Indexuri și obținerea elementelor din array
Pentru accesarea elementelor din array se folosesc indexuri. Indexul reprezintă numărul elementului în array, iar numerotarea începe de la zero, astfel încât indexul primului element va fi 0, indexul celui de-al patrulea element - 3.
Folosind indexuri, putem obține elementele array-ului:
int[] numbers = { 1, 2, 3, 5 };
// obținerea unui element din array
Console.WriteLine(numbers[3]); // 5
// obținerea unui element din array într-o variabilă
var n = numbers[1]; // 2
Console.WriteLine(n); // 2
De asemenea, putem modifica un element din array folosind indexul:
int[] numbers = { 1, 2, 3, 5 };
// modificăm al doilea element din array
numbers[1] = 505;
Console.WriteLine(numbers[1]); // 505
Și, deoarece array-ul nostru este definit doar pentru 4 elemente, nu putem accesa, de exemplu, al șaselea element. Dacă încercăm să facem acest lucru, vom primi o eroare în timpul execuției:
int[] numbers = { 1, 2, 3, 5 };
Console.WriteLine(numbers[6]); // ! Eroare - în array sunt doar 4 elemente
Proprietatea Length și lungimea array-ului
Fiecare array are proprietatea Length, care stochează lungimea array-ului. De exemplu, să obținem lungimea array-ului numbers:
int[] numbers = { 1, 2, 3, 5 };
Console.WriteLine(numbers.Length); // 4
Pentru obținerea lungimii array-ului, după numele array-ului se folosește punctul urmat de proprietatea Length: numbers.Length.
Obținerea elementelor de la sfârșitul array-ului
Datorită existenței proprietății Length, putem calcula indexul ultimului element al array-ului - aceasta este lungimea array-ului minus 1. De exemplu, dacă lungimea array-ului este 4 (adică array-ul are 4 elemente), indexul ultimului element va fi 3. Și, folosind proprietatea Length, putem obține cu ușurință elementele de la sfârșitul array-ului:
int[] numbers = { 1, 2, 3, 5 };
Console.WriteLine(numbers[numbers.Length - 1]); // 5 - primul de la sfârșit sau ultimul element
Console.WriteLine(numbers[numbers.Length - 2]); // 3 - al doilea de la sfârșit sau penultimul element
Console.WriteLine(numbers[numbers.Length - 3]); // 2 - al treilea element de la sfârșit
Totuși, în acest mod, expresiile de tipul numbers.Length - 1, al căror scop este să obțină un anumit element de la sfârșitul array-ului, îngreunează codul. Și, începând cu versiunea C# 8.0, a fost adăugat un operator special ^, care permite specificarea indexului relativ la sfârșitul colecției.
Să rescriem exemplul anterior folosind operatorul ^:
int[] numbers = { 1, 2, 3, 5 };
Console.WriteLine(numbers[^1]); // 5 - primul de la sfârșit sau ultimul element
Console.WriteLine(numbers[^2]); // 3 - al doilea de la sfârșit sau penultimul element
Console.WriteLine(numbers[^3]); // 2 - al treilea element de la sfârșit
Parcurgerea array-urilor
Pentru parcurgerea array-urilor putem folosi diferite tipuri de cicluri. De exemplu, ciclul foreach:
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int i în numbers)
{
Console.WriteLine(i);
}
Aici, array-ul de date de tip int acționează ca un container. Prin urmare, declarăm o variabilă de tip int.
Acțiuni similare putem face și folosind ciclul for:
int[] numbers = { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
În același timp, ciclul for este mai flexibil în comparație cu foreach. Dacă foreach extrage secvențial elementele containerului și doar pentru citire, în ciclul for putem sărim peste câteva elemente înainte, în funcție de incrementul contorului, și putem modifica elementele:
int[] numbers = { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = numbers[i] * 2;
Console.WriteLine(numbers[i]);
}
De asemenea, putem folosi și alte tipuri de cicluri, de exemplu, while:
int[] numbers = { 1, 2, 3, 4, 5 };
int i = 0;
while (i < numbers.Length)
{
Console.WriteLine(numbers[i]);
i++;
}
Array-uri multidimensionale
Array-urile sunt caracterizate de un concept numit rang sau numărul de dimensiuni. Mai sus, am discutat despre array-uri care au o singură dimensiune (adică rangul lor este 1) - astfel de array-uri pot fi reprezentate ca un rând (linie sau coloană) de elemente. Dar array-urile pot fi și multidimensionale. Astfel de array-uri au un număr de dimensiuni (adică rangul) mai mare de 1.
Array-urile care au două dimensiuni (rangul este 2) sunt numite bidimensionale. De exemplu, să creăm array-uri unidimensionale și bidimensionale, care au aceleași elemente:
int[] nums1 = new int[] { 0, 1, 2, 3, 4, 5 };
int[,] nums2 = { { 0, 1, 2 }, { 3, 4, 5 } };
Vizual, ambele array-uri pot fi reprezentate astfel:
- Array unidimensional nums1:

- Array bidimensional nums2:

Deoarece array-ul nums2 este bidimensional, el reprezintă un tabel simplu. Toate metodele posibile de definire a array-urilor bidimensionale:
int[,] nums1;
int[,] nums2 = new int[2, 3];
int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums4 = new int[,] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums5 = new [,]{ { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums6 = { { 0, 1, 2 }, { 3, 4, 5 } };
Array-urile pot avea și mai multe dimensiuni. Declarația unui array tridimensional ar putea arăta astfel:
int[,,] nums3 = new int[2, 3, 4];
Prin urmare, pot exista array-uri cu patru dimensiuni și array-uri cu un număr mai mare de dimensiuni. Dar în practică, de obicei sunt folosite array-uri unidimensionale și bidimensionale.
O anumită dificultate poate fi reprezentată de parcurgerea unui array multidimensional. În primul rând, trebuie să ținem cont că lungimea unui astfel de array este numărul total de elemente.
int[,] numbers = { { 1, 2, 3 }, { 4, 5, 6 } };
foreach (int i în numbers)
Console.Write($"{i} ");
În acest caz, lungimea array-ului numbers este 6. Și ciclul foreach afișează toate elementele array-ului într-un rând:
1 2 3 4 5 6
Dar ce se întâmplă dacă dorim să parcurgem fiecare rând al tabelului separat? În acest caz, trebuie să obținem numărul de elemente din dimensiune. În special, fiecare array are metoda GetUpperBound(număr_dimensiune), care returnează indexul ultimului element dintr-o anumită dimensiune. Și dacă vorbim despre un array bidimensional, prima dimensiune (cu indexul 0) este de fapt tabelul. Și cu ajutorul expresiei:
numbers.GetUpperBound(0) + 1
Putem obține numărul de rânduri ale tabelului reprezentat de array-ul bidimensional. Iar prin:
numbers.Length / număr_rânduri
P utem obține numărul de elemente din fiecare rând:
int[,] numbers = { { 1, 2, 3 }, { 4, 5, 6 } };
int rows = numbers.GetUpperBound(0) + 1; // numărul de rânduri
int columns = numbers.Length / rows; // numărul de coloane
// sau așa
// int columns = numbers.GetUpperBound(1) + 1;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
Console.Write($"{numbers[i, j]} \t");
}
Console.WriteLine();
}
1 2 3
4 5 6
Array de array-uri
Array-urile multidimensionale trebuie deosebite de array-urile de array-uri sau așa-numitele "array-uri zimțate":
int[][] nums = new int[3][];
nums[0] = new int[2] { 1, 2 }; // alocăm memorie pentru primul subarray
nums[1] = new int[3] { 1, 2, 3 }; // alocăm memorie pentru al doilea subarray
nums[2] = new int[5] { 1, 2, 3, 4, 5 }; // alocăm memorie pentru al treilea subarray
Aici, două grupuri de paranteze pătrate indică faptul că este un array de array-uri, adică un astfel de array care, la rândul său, conține alte array-uri. Lungimea array-ului este specificată doar în primele paranteze pătrate, toate celelalte paranteze pătrate trebuie să fie goale: new int[3][]. În acest caz, array-ul nums conține trei array-uri. Dimensiunea fiecăruia dintre aceste array-uri poate să nu coincidă.
Definirea alternativă a unui array de array-uri:
int[][] numbers = {
new int[] { 1, 2 },
new int[] { 1, 2, 3 },
new int[] { 1, 2, 3, 4, 5 }
};
- Array zimțat nums:

Folosind cicluri imbricate, putem parcurge array-uri zimțate. De exemplu:
int[][] numbers = new int[3][];
numbers[0] = new int[] { 1, 2 };
numbers[1] = new int[] { 1, 2, 3 };
numbers[2] = new int[] { 1, 2, 3, 4, 5 };
foreach (int[] row în numbers)
{
foreach (int number în row)
{
Console.Write($"{number} \t");
}
Console.WriteLine();
}
// parcurgerea folosind ciclul for
for (int i = 0; i < numbers.Length; i++)
{
for (int j = 0; j < numbers[i].Length; j++)
{
Console.Write($"{numbers[i][j]} \t");
}
Console.WriteLine();
}
Principalele concepte ale array-urilor
Să sumarizăm principalele concepte ale array-urilor:
- Rang (rank): numărul de dimensiuni ale array-ului
- Lungimea dimensiunii (dimension length): lungimea unei dimensiuni a array-ului
- Lungimea array-ului (array length): numărul total de elemente ale array-ului
De exemplu, să luăm array-ul:
int[,] numbers = new int[3, 4];
Array-ul numbers este bidimensional, adică are două dimensiuni, astfel că rangul său este 2. Lungimea primei dimensiuni este 3, lungimea celei de-a doua dimensiuni este 4. Lungimea array-ului (adică numărul total de elemente) este 12.