Tarihsel olarak, işaretçiler C dilinde bellekle çalışma temellerini oluşturmuş ve dizi elemanlarına ve dinamik yapılara etkili erişim sağlamak için esnek bir mekanizma sunmuştur. Ancak, işaretçilerin dizi işaretçileri ve işaretçi dizileri ile olan sözdizimi ve anlamsal yapısı sıkça kafa karışıklığına yol açmaktadır.
Sorun: Yeni başlayan programcılar genellikle dizi işaretçisi (pointer to array) ile işaretçi dizisini (array of pointers) karıştırmakta ve bu da bellek hatalarına, parametre aktarımı hatalarına ve karmaşık sözdizim hatalarına yol açmaktadır.
Çözüm:
Tanım ve kullanım örneği:
// 10 int'lik bir dizi işaretçisi: int (*p)[10]; int arr[10]; p = &arr; // 10 int'lik işaretçi dizisi int *ap[10]; for (int i = 0; i < 10; ++i) { ap[i] = &arr[i]; } // Bir dizi işaretçisi kullanarak bir elemana nasıl erişilir: (*p)[2] = 5; // arr'in üçüncü elemanı // İşaretçi dizisini kullanarak bir değer nasıl elde edilir: *ap[2] = 8; // ap üzerinden arr'in üçüncü elemanı
Anahtar özellikler:
**int p[10] ve int (p)[10] aynı mı?
Hayır. int *p[10], int için 10 işaretçiden oluşan bir dizidir. int (*p)[10] ise 10 int'den oluşan bir dizi işaretçisidir. Parantezler olmadan büyük bir kafa karışıklığı ortaya çıkar!
Kod örneği:
int arr[10]; int *p[10]; // işaretçi dizisi int (*q)[10] = &arr; // dizi işaretçisi
*Normal bir int işaretçisini int (p)[10] türündeki bir değişkene serbestçe atayabilir miyim?
Hayır. Normal int *, tek bir elemana işaret ederken, int (*p)[10], 10 tam sayılı bir diziye işaret eder; türler açık bir dönüştürme olmadan uyumsuzdur.
İki boyutlu bir diziyi bir fonksiyona nasıl doğru bir şekilde iletebilirim?
İkinci boyutun boyutunu açıkça belirtmek gerekir:
void foo(int a[][4], int n); // 4 elemanlı n satırlık dizi
veya dizi işaretçisi kullanarak:
void bar(int (*a)[4], int n);
Mühendis, değişkeni int *p[10] olarak tanımlıyor, &arr'ye atamaya çalışıyor, burada arr int arr[10] ve dizi olarak erişim sağlamaya çalışıyor, derleme hatası veya geçersiz davranış alıyor.
Artıları:
Eksileri:
Geliştirici dikkatlice parantezleri kullanıyor: int (*p)[10], farkı net bir şekilde anlıyor, dizileri fonksiyonlara düzgün bir şekilde iletiyor, tanımın basitleştirilmesi için typedef kullanıyor.
Artıları:
Eksileri: