Herkese merhabaa. 😊 Bu yazıda Array, Multidimensional Array, Jagged Array ve foreach döngüsünün kullanımını inceleyeceğiz. Şu anda değişkenler içerisinde sadece bir adet değer tutabiliyoruz. Ama gerçek programları düşündüğümüzde birden fazla veri tutmak zorundayız. Bu noktada yardımımıza Array’ler yetişiyor. Array kullanarak aynı tipe sahip birden fazla veriyi bir arada tutabiliriz. Daha basit bir anlatımla anlatacak olursak; int tipinde 5 adet veri tutacağımızı varsayalım. Daha uzatmadan C# Diziler konusuna giriş yapalım. 😊

Bellekte bize 5 adet int tipinin sığacağı büyüklükte bir alan ayrılır. Örnek vermek gerekirse;

Dizi Bellek Depolaması

5 adet veri depolayan int tipinde bir dizi tanımladığımızda bellekte bu şekilde yer ayrılır. Dizinin ilk elemanı 5 ve son elemanı da 0 değerine sahip. Hepsi int tipinde olduğu için bu verileri bir arada saklayabiliyoruz. Konunun biraz daha derinlerine inebiliriz.

C# Diziler

C# üzerinde dizi tanımlarken uymamız gereken bir takım kurallar var. Dizinin tanımlamasını yaparken mutlaka kaç değer tanımlayacağını belirtmeliyiz. Diziler, tanımlanırken verilen tip dışında değer taşıyamazlar. C#’ta dizi tanımlarken 4 farklı seçeneğimiz bulunuyor.

int[] dizi = new int[5]; //boş bir dizi oluşturur
dizi[0] = 5;
dizi[1] = -3;
dizi[2] = 325;
dizi[3] = 14;
dizi[4] = 0;
int[] dizi1 = new int[] { 1, -9, -20 }; //3 elemanlı bir dizi oluşturur
string[] dizi2 = { "ali", "ahmet", "ayşe", "fatma" }; //4 elemanlı bir dizi oluşturur
object[] dizi3 = new object[3] { 2, "üç", false }; //3 elemanlı bir dizi oluşturur

Dizi tanımlamalarında ilk eleman 0. indeksten başlar. Yukarıdaki örnekte de olduğu gibi 5 elemanlı bir dizinin elemanları 0,1,2,3,4 indeksleri şeklinde ilerler.

Diziler ve Döngüler

Dizi içerisindeki verileri görebilmek için döngü yapılarını kullanmamız gerekir. Daha önceden gördüğümüz for, while ve do while döngülerinin yanı sıra foreach döngüsünü de kullanabiliriz. Önce klasik döngüler ile dizi içerisinde gezinelim daha sonrasında foreach yapısına daha yakından bakarız.

Console.WriteLine("For Döngüsü:");
for (int i = 0; i < 5; i++)
{
    Console.WriteLine($"{i}. eleman = {dizi[i]}");
}

Console.WriteLine("----------------------");
Console.WriteLine("While döngüsü:");

int k = 0;

while(k < 5)
{
    Console.WriteLine($"{k}. eleman = {dizi[k]}");
    k++;
}

int l = 0;

Console.WriteLine("\t----------------------");
Console.WriteLine("\tDo While döngüsü:");

do
{
    Console.WriteLine($"\t{l}. eleman = {dizi[l]}");
    l++;
} while (l < 5);

C# Diziler Döngü Ile Dizi Icinde Gezinme

Gördüğünüz gibi bütün döngüler aynı sonucu veriyor. Diziler içerisinde en yaygın kullanılan döngü for döngüsüdür. Dizinin indeksleri içerisinde gezinmek için tanımlayacağımız değişkenin mutlaka tam sayı türünde olması gerekir. byte, short, int, long gibi veri türlerini kullanabiliriz. Bu veri türlerini seçerken sınırlarını unutmamak gerekir. Mesela 300 elemanlı bir dizi içinde gezinirken byte türünü kullanamayız. 255’ten sonraki 45 elemanı göremeyiz. 😅

Bunun dışında döngü yazarken dizinin sınırlarını aşmamamız gerekiyor. Örneğin for döngüsünde i <= 5 şartını koyalım ve neler olacağına bakalım.

Dizi Sınırını Aşmak

Program daha derleme aşamasında Index Out Of Range (Dizi sınırları dışında) hatası veriyor. Dizileri yan yana sıralı kutular olarak düşünürsek, dizinin son elemanı 4. kutuda yer alıyor. 5. kutu olmadığı için o kutuya erişemiyor ve hata veriyor. Bu hatayı alıyorsanız dizi sınırı dışından bir elemana ulaşmaya çalışıyorsunuz demektir.

Foreach döngüsüne geçmeden önce kullanıcıdan kaç adet sayı gireceğini alıp girdiği sayıların toplamlarını ekrana yazdıralım.

int[] array;
Console.WriteLine();

Console.WriteLine("Kaç adet sayı girmek istiyorsunuz?");
int count = int.Parse(Console.ReadLine());
array = new int[count];

for (int i = 0; i < count; i++)
{
    Console.Write($"{i + 1}. sayı: ");
    array[i] = int.Parse(Console.ReadLine());
}

int sum = 0;

for (int i = 0; i < count; i++)
{
    sum += array[i];
}

Console.WriteLine("Girdiğiniz sayıların toplamı: {0}", sum);

Girilen Sayıların Toplamını Bulan Program

foreach Döngüsü

Foreach döngüsü anlaşılması en kolay döngülerden birisidir. Foreach döngüsünü C# diziler ya da koleksiyon içerisinde normal veri türleri ile ya da kendi yazdığımız tipler ile de kullanabiliriz. Foreach dizi içerisinde gezinirken dizinin indeksi üzerinden değil de içerdiği elemanlar üzerinden gezinir.

foreach (tip değişken in dizi)
{
         yapılacak işler
}

Daha iyi anlamak için isimleri depolayan bir dizinin içerisinde gezinelim.

string[] names = { "Chloe", "Ralph", "Yusuf", "Megan", "Ella" };
foreach (string item in names)
{
    Console.WriteLine(item);
}

Foreach Döngüsü Örnek

Örnekte olduğu gibi string dizisi içerisinde gezindiğimiz için tip kısmını string olarak veriyoruz. item kısmı değişkenimizin adı. Yani oraya istediğimiz herhangi bir ismi verebiliriz. Döngüyü debug modda çalıştırdığınızda çok kolay bir mantığa sahip olduğunu göreceksiniz. Elemanlar arası iterasyon yaparken çok tercih ediliyor.

C# Diziler: String Yapısı

String veri türü de aslında karakter depolayan bir dizidir. En basitinden örnek verecek olursak isim tanımlamak için kullandığımız string name değişkeni bir char[] dizisi ile aynı özellikleri taşır. For döngüsü ile string içerisinde gezinebiliriz.

string ad = "Derya";
for (int i = 0; i < ad.Length; i++) //length metodu bize o dizinin boyutunu verir
{
    Console.WriteLine(ad[i]);
}

C# Diziler String Yapısı

Değişkeni for döngüsü içerisine koyduğumuzda Derya kelimesinin bütün karakterlerini alt alta yazıyor. Girilen isimde her harften kaç tane bulunduğunu hesaplayan program tasarlayalım

Console.WriteLine("Lütfen bir isim giriniz: ");
string name = Console.ReadLine();
char[] letters = name.ToCharArray(); 
//Bu metot sayesinde isim içerisindeki harfleri bir char dizisi olarak alabileceğiz.
byte[] counter = new byte[name.Length];

for (int i = 0; i < letters.Length; i++)
{
    for (int j = 0; j < name.Length; j++)
    {
        if (letters[i] == name[j])
        {
            counter[i]++;
        }
    }
}

Console.WriteLine($"{name} isminde ");

for (int i = 0; i < name.Length; i++)
{
    Console.WriteLine($"{counter[i]} adet {letters[i]} harfi bulunmaktadır.");
}

C# Diziler String Örneği

Şimdi de kullanıcının girdiği kelimedeki sesli harfleri bulan programı tasarlayalım.

Console.WriteLine("Bir kelime giriniz");
string word = Console.ReadLine();

char[] vowelLetters = { 'a', 'e', 'ı', 'i', 'o', 'ö', 'u', 'ü' };

byte counterValue = 0;

for (int i = 0; i < word.Length; i++)
{
    for (int j = 0; j < vowelLetters.Length; j++)
    {
        if (word[i] == vowelLetters[j])
        {
            counterValue++;
        }
    }
}

C# Diziler String Örneği1

C# Çok Boyutlu Diziler

Çok boyutlu diziler bir diğer adıyla matrisler aynı veri türünden birden fazla değer tutmak istiyorsak kullanabiliriz. Örneğin farklı aylara göre çikolata satışlarını içeren bir tablomuz olsun.

Tür Ocak Şubat Mart
Bitter 520 600 450
Sütlü 700 250 300
Beyaz 400 600 250

Bu tablo üzerindeki verileri çok boyutlu diziler sayesinde depolayabiliriz. Önce çok boyutlu dizilerin tanımlamasının nasıl yapıldığına bakalım. 2 satır 3 kolondan oluşan bir veri depolamak için;

string[,] values = new string[2, 3];
values[0, 0] = "A";
values[0, 1] = "B";
values[0, 2] = "C";
values[1, 0] = "Ç";
values[1, 1] = "D";
values[1, 2] = "E";

for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 3; j++)
    {
        Console.WriteLine($"values[{i},{j}] = {values[i, j]}");
    }
}

şeklinde tanımlıyoruz. Şimdi örnek verilerimizi depolayalım ve sütlü çikolatanın ortalama 3 aylık satış miktarını hesaplayalım. Çikolata türleri için 3 satır ve 3 ay için 3 kolona ihtiyacımız var.

int[,] satisMiktari = new int[3, 3];
//Bitter
satisMiktari[0, 0] = 520; //Ocak
satisMiktari[0, 1] = 600; //Şubat
satisMiktari[0, 2] = 450; //Mart
//Sütlü
satisMiktari[1, 0] = 700; //Ocak
satisMiktari[1, 1] = 250; //Şubat
satisMiktari[1, 2] = 300; //Mart
//Beyaz
satisMiktari[2, 0] = 400; //Ocak
satisMiktari[2, 1] = 600; //Şubat
satisMiktari[2, 2] = 250; //Mart

//Sütlü Çikolatanın 3 aylık otalama satış miktarı
double ort = 0;

for (int i = 0; i < 3; i++)
{
    ort += satisMiktari[1, i];
}

ort /= 3;

Console.WriteLine($"Ortalama satış miktarı: {ort}");

Matris Örneği 1

Tüm çikolata türleri için 3 aylık satış toplamlarını hesaplayalım.

int[,] satisMiktari = new int[3, 3];
//Bitter
satisMiktari[0, 0] = 520; //Ocak
satisMiktari[0, 1] = 600; //Şubat
satisMiktari[0, 2] = 450; //Mart
//Sütlü
satisMiktari[1, 0] = 700; //Ocak
satisMiktari[1, 1] = 250; //Şubat
satisMiktari[1, 2] = 300; //Mart
//Beyaz
satisMiktari[2, 0] = 400; //Ocak
satisMiktari[2, 1] = 600; //Şubat
satisMiktari[2, 2] = 250; //Mart

int[] tur = new int[3];

for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)
    {
        tur[i] += satisMiktari[i, j];
    }
}

for (int i = 0; i < 3; i++)
{
    switch (i)
    {
        case 0:
            Console.WriteLine($"Bitter çikolata satış toplamı: {tur[i]}");
            break;
        case 1:
            Console.WriteLine($"Sütlü çikolata satış toplamı: {tur[i]}");
            break;
        case 2:
            Console.WriteLine($"Beyaz çikolata satış toplamı: {tur[i]}");
            break;
    }
}

Matris Örneği 2

Jagged Arrays (İç İçe Geçmiş Diziler)

İç içe geçmiş diziler, dizi içeren dizilerdir. Tek boyutlu dizinin elemanı olarak dizi verildiğinde oluşur. Çok fazla kullanılmaz çünkü iç içe diziler performans açısından çok da iyi bir seçenek değildir. Örnek kullanımına bakalım.

int[][] jaggedArray = new int[2][];
jaggedArray[0] = new int[] { 1, 2, 3 };
jaggedArray[1] = new int[] { -1, 0, 2, 6, 9, 3 };

for (int i = 0; i < jaggedArray.Length; i++)
{
    for (int j = 0; j < jaggedArray[i].Length; j++)
    {
        Console.WriteLine($"jaggedArray[{i}][{j}] = {jaggedArray[i][j]}");
    }
}

İç İçe Geçmiş Diziler

Diziler konusu bu kadar. Diziler bütün dillerde bulunan ortak bir veri türüdür. Bu nedenle farklı diller arasında bağlantı kurulacağında genellikle diziler kullanılır. Dizilerin mantığını anlarsanız koleksiyonların yapısını daha kolay bir şekilde kavrayabilirsiniz. Bir sonraki yazıya kadar kendinize çok iyi bakın. 😊