25 : Pointer ile Dizi Elemanlarına Ulaşma

Bir dizi, bellekte aynı tip verilerden oluşan bloğu ifade eder. Önceki örnekte bir işaretçinin bellekte verinin tutulduğu bir adresi ifade ettiğini söylemiştik. Aynı şekilde dizinin ismi de bu veri bloğunun başlangıç adresini ifade eder. Bir dizi değişkeni ile bir pointer değişkeni arasında benzerlikler bulunur.

Aşağıdaki örnekte bir dizi tanımlayacağız ve bunu print ettireceğiz. Daha sonra tekrar pointer kullanarak ulaşıp print ettireceğiz ki fark olmadığını görelim.


dizi_pointer.c
#include <stdio.h>
int main()
{
   int data[7] = {12, 2, 4, 55, 132, 1567, 43};
   int i = 0;
 
   printf("-- Girilen sayilar -- \n");
   printf("Dizi ile: \n");
   for(i = 0; i < 7; ++i)
   {
      printf("%d ", data[i]);
   }
   printf("\nPointer ile: \n");
   for(i = 0; i < 7; ++i)
   {
      printf("%d ", *(data + i));
   }
   printf("\n");
   return 0;
}

Burada dikkat edilmesi gereken nokta *data ifadesinin data dizisinin ilk elemanını (data[0] yani) vermesidir.  Daha sonra data[1] elemanına ulaşmak için *(data+1) şeklinde kullanıyoruz. * ifadesi işaretçinin gösterdiği adresin içeriğini verir demiştik. Burada data+1, data işaretçisinin gösterdiği adresten bir sonraki adresi ifade etmiş oluyor.

Şu örnekte bir fonksiyona bir diziyi parametre olarak geçirip bir değişiklik yapmak istediğimizde işaretçileri kullanmamız gerektiğinden bahsetmiştik. Şimdi benzer bir örnek ile bu konuyu tekrar ele alacağız.

Örnek olarak yukarıdaki gibi bir dizi tanımlayalım. Her elemanı 10 ile toplayıp, geri dönüp main fonksiyonunda bu değerleri yazdıralım. Böylece bir fonksiyonda diziler üzerinde işlem yaptıktan sonra nasıl dönüş yapacağımızı görmüş olacağız.

 #include <stdio.h>

void onIleTopla(int *dizi, int n);
int main()
{
   int data[7] = {12, 2, 4, 55, 132, 1567, 43};
   int i = 0;
 
   printf("-- Girilen sayilar -- \n");
   printf("Dizi ile: \n");
   for(i = 0; i < 7; ++i)
   {
      printf("%d ", data[i]);
   }
   printf("\nPointer ile: \n");
   for(i = 0; i < 7; ++i)
   {
      printf("%d ", *(data + i));
   }

   onIleTopla(data , 7);
   printf("\nYeni degerler \n");
   for(i = 0; i < 7; ++i)
   {
      printf("%d ", *(data +i));
   }  
   printf("\n");
   return 0;
}

void onIleTopla(int *dizi, int n)
{
   int i = 0;
   for(i = 0; i < n; ++i)
   {
      dizi[i] += 10;
   }  
}

Burada onIleTopla fonksiyonunda bir dizi üzerinde işlem yaptıktan sonra diziyi return ile geri döndürmüyoruz çünkü pointer özelliğinden faydalanıyoruz. Başka bir veri üzerine yazılmadığı sürece bilgiler o adreste tutulmuş oluyor. Bir başka nokta ise fonksiyona sınır değerini göndermemiz. Dizinin sınırlarını taşırıp bellekteki verileri bozmamak için dizinin kaç elemanlı olduğunu da geçiriyoruz. Bu şekilde hata olasılığı düşüyor.

Bu fonksiyona elle i < 7 yazabilirdik ancak daha sonra bu fonksiyonu kullanırken parametre olarak kullandığımız dizi bir hata sonucu 7 den az elemana sahip ise bellekte istenmeyen bölgelere dalmış olurduk. Bu da hiç istemediğimiz bir hatadır ve genelde programın sonlanmasına sebep olur.

Yorumlar

Bu blogdaki popüler yayınlar

31 : Fonksiyonda Struct Kullanımı

Structure - 29 : Yapılar ile Öğrenci Bilgileri Tutma

23 : İki Karakter Dizisini Birleştirme