1. Diqqətli massivlər ikiölçülü massivlərdən nə ilə fərqlənir
Bax indi gəldik bir mövzuya ki, çoxları buna "massivlərin massivi" və ya "diqqətli massivlər" deyir — ingiliscə jagged arrays. İkiölçülü massivlərdən fərqli olaraq, diqqətli massivlərdə sütunların uzunluğu fərqli ola bilər. Bu elə bil ki, sənin bir neçə binadan ibarət kompleksin var və hər binada fərqli sayda mənzil var — birində 5, digərində 20, üçüncüdə isə cəmi bir dənə.
Diqqətli massiv — elə bir massivdir ki, onun hər bir elementi özü də massivdir. Və bu daxili massivlər (onlara "submassivlər" də deyirlər) müxtəlif uzunluqda ola bilər.
Əsas fərq:
- İkiölçülü massivdə hər "sətir"də (və hər "sütunda") elementlərin sayı eynidir. Məsələn: int[,] grid = new int[3, 5]; — həmişə 3 sətir, hərəsində 5 element.
- Diqqətli massivdə isə hər sətir fərqli uzunluqda ola bilər! Məsələn: int[][] jagged = new int[3][]; — və yalnız sonra hər sətiri (submassivi) özünə uyğun inicializasiya edirsən.
Vizual olaraq belə görünür:
| İkiölçülü massiv | Diqqətli massiv | |
|---|---|---|
| Elementlərin sayı | Sərt sabit (məsələn, 3x5) | Fərqli sətirlərdə fərqli ola bilər |
| İndeksləmə | |
|
| Elastiklik | Aşağı | Yüksək |
| Tətbiq sahəsi | Cədvəllər, riyaziyyat | Qeyri-bərabər məlumatlar: fərqli sayda qiymətləri olan tələbə siyahıları, üçbucaqlar |
Vizualizasiya: ikiölçülü və diqqətli massivləri müqayisə edək
İkiölçülü massiv (3x3):
┌───┬───┬───┐
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┴───┴───┘
Diqqətli massiv (fərqli uzunluqlar):
┌───┬───┐
│ 1 │ 2 │
├───┼───┼───┬───┐
│ 3 │ 4 │ 5 │ 6 │
├───┼───┴───┴───┘
│ 7 │
└───┘
2. Diqqətli massivlərin elan və inicializasiya sintaksisi
Diqqətli massiv elan etmək əvvəlki tiplərdən qorxulu deyil! İkiqat kvadrat mötərizələrdən qorxma:
int[][] jaggedArray = new int[3][];
Bu o deməkdir ki, səndə 3 elementdən ibarət massiv var və onların hər biri də int massividir. Amma hələlik daxili massivlər yaradılmayıb! Daha yaxşı başa düşmək üçün gəlin bunu addım-addım baxaq.
Diqqətli massivlərin addım-addım inicializasiyası
Addım 1 — əsas (xarici) massiv yaratmaq:
int[][] jaggedArray = new int[3][];
İndi 3 "sətirimiz" var, amma onların hamısı hələ null-dır.
Addım 2 — daxili massivləri (submassivləri) yaratmaq və doldurmaq:
Məsələn, birinci sətir 2 uzunluqda, ikinci 4, üçüncü isə 3 olsun:
jaggedArray[0] = new int[2]; // birinci sətirdə 2 element
jaggedArray[1] = new int[4]; // ikinci sətirdə 4 element
jaggedArray[2] = new int[3]; // üçüncü sətirdə 3 element
Addım 3 — dəyərlərlə doldurmaq:
Daxili massivlər adi massivlərdir! Məsələn:
jaggedArray[0][0] = 1;
jaggedArray[0][1] = 2;
jaggedArray[1][0] = 3;
jaggedArray[1][1] = 4;
jaggedArray[1][2] = 5;
jaggedArray[1][3] = 6;
jaggedArray[2][0] = 7;
jaggedArray[2][1] = 8;
jaggedArray[2][2] = 9;
Diqqətli massivlərin qısa inicializasiyası
Əgər dəyərləri əvvəlcədən bilirsənsə, diqqətli massivi birbaşa yaratmaq və doldurmaq olar:
int[][] jaggedArray = new int[][]
{
new int[] { 1, 2 },
new int[] { 3, 4, 5, 6 },
new int[] { 7, 8, 9 }
};
Və ya bir az daha qısa, daxili massivlərin tipini yazmadan:
int[][] jaggedArray = {
new[] { 1, 2 },
new[] { 3, 4, 5, 6 },
new[] { 7, 8, 9 }
};
3. Diqqətli massivlərdə dövr və işləmə
Diqqətli massivdə dövr etmək ikiölçülü massivdən çətin deyil, sadəcə xarici dövr sətirlərlə, daxili dövr isə sətirdəki elementlərlə işləyir (onlar fərqli uzunluqda ola bilər):
for (int i = 0; i < jaggedArray.Length; i++)
{
Console.WriteLine($"Sətir {i}:");
for (int j = 0; j < jaggedArray[i].Length; j++)
{
Console.Write($"{jaggedArray[i][j]} ");
}
Console.WriteLine();
}
Ekranda nəticə:
Sətir 0:
1 2
Sətir 1:
3 4 5 6
Sətir 2:
7 8 9
foreach istifadə edə bilərsən ki, indeksləri düşünməyəsən:
foreach (int[] row in jaggedArray)
{
foreach (int value in row)
{
Console.Write($"{value} ");
}
Console.WriteLine();
}
4. Massivlərin massivi necə qurulub
İndi isə sən öyrənəcəksən ki, massivlərin massivi əslində necə işləyir. Hazırsan?
Adi massivdə "massiv dəyişəni konteynerə istinad saxlayır, o da massiv elementlərini saxlayır". Diqqətli massivdə isə vəziyyət bir az daha maraqlıdır: massivlərin massivi dəyişəni konteynerə istinad saxlayır, o da birölçülü massivlərə istinadlar saxlayır. Bunu bir dəfə görmək, yüz dəfə izah etməkdən yaxşıdır:
Solda bizdə "massivlərin massivi dəyişəni" var, o "massivlər konteyneri obyektinə" istinad saxlayır. Ortada "massivlər konteyneri obyekti" var, onun hüceyrələrində birölçülü massivlərə istinadlar saxlanılır — diqqətli massivimizin sətirləri. Sağda isə dörd birölçülü massiv görürsən — bizim diqqətli massivimizin sətirləri.
Bax, diqqətli massivlər əslində belə işləyir. Bu yanaşma C# proqramçısına bir neçə üstünlük verir:
Birincisi, çünki "konteynerlərin konteyneri" "sətir-massivlərə" istinadlar saxlayır, biz sətirləri çox tez və rahat dəyişə bilərik. "Konteynerlərin konteynerinə" çıxış üçün sadəcə bir indeks göstərmək kifayətdir. Məsələn:int[][] data = new int[2][];
data[0] = new int[5]; // birinci sətir — 5 elementlik massiv
data[1] = new int[5]; // ikinci sətir — 5 elementlik massiv
int[] row1 = data[0];
int[] row2 = data[1];
Belə kodla sətirləri yerlə dəyişmək olar:
// Vacib matris məlumatlarla
int[][] matrix = {
new int[] {1, 2, 3, 4, 5},
new int[] {5, 4, 3, 2, 1}
};
int[] tmp = matrix[0];
matrix[0] = matrix[1];
matrix[1] = tmp;
Əgər ikiölçülü massivdəki hüceyrəyə müraciət edirsənsə, amma massiv adından sonra yalnız bir indeks yazırsansa, sən əslində konteynerlərin konteynerinə müraciət edirsən, orada isə adi birölçülü massivlərə istinadlar saxlanılır.
5. Diqqətli massivlərin tipik istifadə ssenariləri
Diqqətli massiv nə vaxt ikiölçülü massivdən daha faydalı ola bilər?
- Əgər hər istifadəçi üçün fərqli sayda hansısa məlumat saxlayırsansa: fənlər üzrə qiymətlər, alışlar, şərhlər və s.
- Əgər məlumatların üçbucaq və ya pilləli strukturu varsa (məsələn, piramidalar, Paskal üçbucaqları və s. üçün).
- Əgər yaddaşa qənaət etmək istəyirsənsə: ikiölçülü massivdə bütün sətirlər sabitdir, diqqətli massivdə isə yalnız lazım olan qədər element var.
Həyatdan nümunə: tələbə qiymətləri meneceri
Gəlin tədris layihəmizi genişləndirək! Tutaq ki, hər tələbənin hər fənn üzrə fərqli sayda qiyməti ola bilər. Məsələn, kimsə daha çox iş verir, kimsə az. Bunun üçün diqqətli massiv əladır.
Tutaq ki, bizdə üç tələbə var və onların riyaziyyat üzrə müxtəlif tapşırıqlara görə qiymətləri belədir:
| Tələbə | Qiymətlər |
|---|---|
| 0 | 5, 4 |
| 1 | 3, 4, 4 |
| 2 | 5 |
Belə massiv elan edək:
int[][] studentMarks = new int[3][];
studentMarks[0] = new int[] { 5, 4 }; // Birinci tələbə - 2 qiymət
studentMarks[1] = new int[] { 3, 4, 4 }; // İkinci tələbə - 3 qiymət
studentMarks[2] = new int[] { 5 }; // Üçüncü tələbə - 1 qiymət
Hər tələbənin qiymətlərini ekrana çıxaraq:
for (int i = 0; i < studentMarks.Length; i++)
{
Console.Write($"Tələbə {i}: ");
for (int j = 0; j < studentMarks[i].Length; j++)
{
Console.Write(studentMarks[i][j] + " ");
}
Console.WriteLine();
}
Diqqətli massivləri başqa tiplərlə istifadə etmək
Diqqətli massiv istənilən şeyin massivi ola bilər: sətir, başqa massivlərin massivi (daha dərin!), hətta öz obyektlərin.
Nümunə: sətir massivləri
string[][] groups = new string[][]
{
new string[] { "İvan", "Pyotr" },
new string[] { "Mariya", "Aleksey", "Sergey" },
new string[] { "Vasilisa" }
};
6. Xüsusiyyətlər və ola biləcək səhvlər
Diqqətli massivlər elastikdir, amma hər addımda tələlər var.
- Əgər hansısa daxili massivi inicializasiya etməmisənsə (jaggedArray[1] = ...), ona müraciət etmək NullReferenceException verəcək. Hər daxili massivi inicializasiya etməyi unutma!
- Bütün sətirlər (submassivlər) eyni uzunluqda deyil. İkinci ölçüdə sabit indeks istifadə etsən, onun sərhəddindən kənara çıxa bilərsən.
- İkiölçülü massivlə qarışdırma! İndeksləmə belədir: array[i][j], yoxsa array[i, j] deyil.
GO TO FULL VERSION