Programlama Temelleri

6 - Diziler - Bölüm 1: Sayısal Diziler

Emre Can Yılmaz

Ondokuz Mayıs Üniversitesi

2024

Diziler: Veri Koleksiyonları

  • Diziler, aynı veri tipinde birden fazla değeri depolamak için kullanılan yapılardır.
  • Tek bir değişken yerine, bir dizi kullanarak birden fazla değeri tek bir isim altında toplayabilir ve düzenleyebiliriz.
  • Örneğin, bir sınıftaki öğrencilerin notlarını saklamak için bir dizi kullanabiliriz.
  • Diziler bellekte ardışık bir şekilde saklanır.

Dizi Tanımlama

Sözdizimi:

veri_tipi dizi_adı[dizi_boyutu];
  • veri_tipi: Dizinin saklayacağı verilerin tipi (int, float, char vb.).
  • dizi_adı: Diziye verilen isim.
  • dizi_boyutu: Dizinin kaç eleman saklayacağını belirten bir tam sayı. Sabit dizilerde dizi boyutu, derleme zamanında belirlenir ve değiştirilemez.

Örnekler:

int sayilar[5];      // 5 tam sayı saklayabilen bir dizi
float notlar[10];   // 10 ondalık sayı saklayabilen bir dizi
double uzunluklar[3]; // 3 double sayı saklayabilen bir dizi.

Dizilere Değer Atama ve Erişim

  • Dizilere değer atamak için, dizi adını, indeks numarasını ve atama operatörünü (=) kullanırız.
  • İndeks numaraları 0’dan başlar. Yani, ilk elemanın indeksi 0, ikinci elemanın indeksi 1, ve böyle devam eder.

Örnek:

int sayilar[5];

sayilar[0] = 10;
sayilar[1] = 25;
sayilar[2] = 30;
sayilar[3] = 45;
sayilar[4] = 50;

printf("Dizinin ilk elemanı: %d\n", sayilar[0]); // Çıktı: 10
printf("Dizinin üçüncü elemanı: %d\n", sayilar[2]); // Çıktı: 30

Dizileri İlklendirme

  • Dizileri tanımlarken değerleri ile birlikte ilklendirebiliriz.

Örnek 1:

int sayilar[5] = {10, 25, 30, 45, 50};

Örnek 2:

float notlar[] = {85.5, 90.0, 78.2};
// Boyut otomatik olarak 3 olarak atanır.

Dikkat!

Bir dizinin boyutu ve türü, tanımlandıktan sonra değiştirilemez!

Dizi Elemanlarının Değerini Değiştirme

int sayilar[5] = { 1, 2, 3, 4, 5 };
// ucuncu elemanın degerini -1 yap
sayilar[2] = -1;// besinci elemanın degerini 0 yap
sayilar[4] = 0;

Dizi elemanlarının indislerini kullanarak yukarıdaki gibi değiştirebiliriz.

Dizilerle Döngüler: Elemanlara Erişme

  • Dizilerle çalışırken döngüler sıkça kullanılır.
  • Döngüler, dizinin her bir elemanına sırayla erişmemizi ve işlem yapmamızı sağlar.

Örnek 1: Dizinin Elemanlarını Yazdırma

#include <stdio.h>

int main() {
  int sayilar[5] = {10, 25, 30, 45, 50};

  for (int i = 0; i < 5; i++) {
    printf("sayilar[%d]: %d\n", i, sayilar[i]);
  }
  return 0;
}

Örnek 2: Dizinin Elemanlarını Toplama

#include <stdio.h>

int main() {
  int sayilar[5] = {10, 25, 30, 45, 50};
  int toplam = 0;

  for (int i = 0; i < 5; i++) {
    toplam += sayilar[i];
  }

  printf("Toplam: %d\n", toplam);
  return 0;
}

Örnek 3: Kullanıcıdan Dizi Elemanlarını Alma

#include <stdio.h>

int main() {
  int sayilar[5];

  printf("5 tane sayı girin:\n");
  for (int i = 0; i < 5; i++) {
    printf("%d. sayı: ", i + 1);
    scanf("%d", &sayilar[i]);
  }

  printf("Girdiğiniz sayılar:\n");
  for (int i = 0; i < 5; i++) {
    printf("%d ", sayilar[i]);
  }
  printf("\n");
  return 0;
}

sizeof Operatörü: Dizilerin Boyutunu Hesaplama

  • sizeof operatörü, bir değişkenin veya veri tipinin bellekte kapladığı bayt sayısını döndürür.
  • Dizilerle kullanıldığında, dizinin toplam boyutunu bayt cinsinden verir.
  • Dizinin eleman sayısını bulmak için, dizinin toplam boyutunu bir elemanın boyutu ile bölebiliriz. Yani:
  • dizi_boyutu = sizeof(dizi) / sizeof(dizi[0])

Örnek

#include <stdio.h>

int main() {
    int sayilar[] = {10,20,30,40,50};

    int dizi_boyutu = sizeof(sayilar) / sizeof(sayilar[0]);
    printf("Dizinin boyutu: %d\n", dizi_boyutu);
}

sayilar bellekte 20 baytlık bir alanda saklansın. Bu dizi içerisindeki ilk eleman yani 10 sayısı 4 bayt’lık yer kaplıyorsa. 20 / 4 = 5 sonucunu verecektir. Yani sayilar dizisi 5 elemanlıdır diyebileceğiz.

sizeof Operatörü: Kullanım Alanları

  • sizeof ile dizinin eleman sayısını bulma işlemi, özellikle bir dizinin uzunluğuna göre işlemler yaparken veya bir döngüde tüm elemanları işlemek gerektiğinde kullanışlıdır.

  • Bu yöntemle, dizinin uzunluğunu elde etmek için ek bir değişken veya sabit kullanmak zorunda kalmazsınız, yani dizinin uzunluğu doğrudan program içinde dinamik olarak belirlenir.

  • Ancak bu yöntemin bazı sınırlamaları da vardır. İşte kullanım alanları ve dikkat edilmesi gereken noktalar:

Döngülerde Diziyi Tamamen Gezinmek İçin

Eğer bir diziyi baştan sona dolaşmak istiyorsanız, dizinin boyutunu hesaplayarak döngüyü bu uzunluk kadar çalıştırabilirsiniz.

int array[] = {1, 2, 3, 4, 5};
int length = sizeof(array) / sizeof(array[0]);

for (int i = 0; i < length; i++) {
    printf("%d ", array[i]);
}
// Çıktı: 1 2 3 4 5

Fonksiyonlara Dizinin Boyutunu Geçmek İçin

sizeof operatörü ile dizinin uzunluğunu hesaplayarak bir fonksiyona bu değeri gönderebilirsiniz. Bu sayede fonksiyon, dizinin boyutunu bilerek işlem yapabilir.

void printArray(int array[], int length) {
    for (int i = 0; i < length; i++) {
        printf("%d ", array[i]);
    }
}

int main() {
    int array[] = {10, 20, 30, 40};
    int length = sizeof(array) / sizeof(array[0]);
    printArray(array, length);
    return 0;
}

Diziler ve Fonksiyonlar

  • Dizileri fonksiyonlara parametre olarak geçirebiliriz.
  • Bir fonksiyona dizi gönderildiğinde, fonksiyon dizinin bir kopyasını değil, bellekteki adresini alır. Yani, fonksiyon içinde yapılan değişiklikler, orijinal diziyi de etkiler.

Örnek: Dizinin Elemanlarını İkiye Katlayan Fonksiyon

#include <stdio.h>

void ikiyeKatla(int dizi[], int boyut) {
  for (int i = 0; i < boyut; i++) {
    dizi[i] *= 2;
  }
}

int main() {
  int sayilar[5] = {1, 2, 3, 4, 5};

  ikiyeKatla(sayilar, 5);

  for (int i = 0; i < 5; i++) {
    printf("%d ", sayilar[i]);
  }
  printf("\n"); // Çıktı: 2 4 6 8 10
  return 0;
}

Dizi Sınırları Dışına Çıkma Hatası

Dikkat!

Dizilerle çalışırken, dizinin boyutunu aşan bir indekse erişmeye çalışmak, dizi sınırları dışına çıkma hatasına (out of bounds error) neden olur. Bu, programın çökmesine veya beklenmedik sonuçlar üretmesine yol açabilir. Bu yüzden, dizilerle çalışırken indeks değerlerine dikkat etmek çok önemlidir.

Dizi Sınırları Dışına Çıkma Hatası

Örnek

int sayilar[5] = {1, 2, 3, 4, 5};

printf("%d\n", sayilar[5]); // Hata! Geçersiz indeks değeri
  • Bu örnekte, sayilar dizisi 5 eleman içerir (indeksleri 0’dan 4’e kadardır). sayilar[5] ifadesi, dizinin sınırları dışında bir elemana erişmeye çalıştığı için hata oluşturacaktır.

  • Dizilerle çalışırken döngü kullanıyorsanız, döngü koşulunuzu dizinin boyutuna göre doğru bir şekilde ayarlamalısınız. Örneğin, 5 elemanlı bir dizi için döngü koşulu i < 5 olmalıdır.

Alıştırmalar

  1. Kullanıcının girdiği sayıların ortalamasını hesaplayan kodu dizileri kullanarak yaz. İlk önce kullanıcının kaç adet sayı gireceğini sor. Sayıları kullanıcıdan alırken döngü kullan.
  2. 5 elemanlı bir dizinin içini rastgele sayılarla dolduran (0-100 arasında) ve bu diziyi ekrana yazdıran bir fonksiyon yazın. Sayıları yazdırmak için ayrı bir döngü kullanın.
  3. Bir önceki soruya ek olarak rastgele üretilen sayılardan en büyüğünü, en küçüğünü ve sayların ortalamasını hesaplayan kodu yazın.
  4. int sayilar[5] = { 1,2,3,4,5 }; şeklindeki sayilar dizisindeki tek sayıların toplamını hesaplayan kodu döngü kullanarak yazın.
  5. Kullanıcıdan alınan bir diziyi tersine çeviren bir fonksiyon yazın. (Örneğin, {1, 2, 3} dizisi {3, 2, 1} haline gelsin.)

Özet

  • Diziler: Aynı tipteki birden fazla veriyi saklamak için kullanılır.
  • İndeks: Dizinin elemanlarına erişmek için kullanılır. 0’dan başlar.
  • Dizi Tanımlama: veri_tipi dizi_adı[boyut];
  • Dizi Başlatma: {değer1, değer2, ...}
  • sizeof: Dizinin boyutunu bayt cinsinden verir.
  • Diziler ve Fonksiyonlar: Diziler fonksiyonlara adresleri ile geçirilir.

Gelecek Hafta

  • Diziler - Bölüm 2: Karakter Dizileri