Derecelendirme operatörü * ve adres alma operatörü & — C dilinde bellek ile çalışmanın temel araçlarından biridir. Bu operatörler, bellekteki verilerle doğrudan araç elde etmeyi sağlar, bu da C'yi sistem programlama için popüler bir dil haline getirmiştir.
Konuya Giriş:
C dilinin ortaya çıkmasından (1970'ler) itibaren felsefesi düşük seviyeli bellek yönetimi ile sıkı bir şekilde bağlıdır. * ve & operatörleri, işlemci düzeyinde kullanılan dolaylı adresleme tekniğini uygulayarak işaretçilerle çalışmayı, dinamik bellek tahsisi yapmayı ve etkili veri yapıları oluşturmaya olanak tanır.
Problem: Bu operatörlerin yanlış kullanımında oluşan hatalar sayısız hata yaratır: bellek sızıntıları, veri bozulmaları ve segment hataları. Derleyici, özellikle işaretçilerin boyutları uyumlu olduğunda ama içerikleri farklı olduğunda bu hataları her zaman açıkça bildirmeyebilir.
Çözüm: İşaretçilerin türüne dikkat etmek, tahsis edilen belleğin yaşam döngüsünü izlemek, başlatma ve doğru bir şekilde serbest bırakma yapmak ve ayrıca derecelendirme işlemleri ve kullanılan adreslerin doğruluğunu kontrol etmek gerekir.
Kod örneği:
int x = 10; int *p = &x; // adres alma int y = *p; // derecelendirme (adresteki değeri alıyoruz) // Dizi işaretçisi ile çalışma int arr[3] = {1,2,3}; int *pa = arr; printf("%d", *(pa+1)); // dizinin ikinci elemanı
Anahtar özellikler:
Geçici bir değişkenin adresini alabilir miyiz, örneğin: & (x + y)?
Hayır, ifadelerin adresi alınamaz çünkü ifadenin sonucu — bir bellek nesnesi değildir. Adres sadece bir değişken, dizi veya yapıdan alınabilir.
Kod örneği:
int z = 5; int p = &(z + 1); // Derleme hatası
void işaretçisinin derecelendirilmesi nasıl farklıdır?
void * türündeki işaretçi doğrudan derecelendirilemez, önce belirli bir tipe dönüştürülmesi gerekir. Bu evrensel bir işaretçidir, ancak derecelendirme işlemleri tür bağımsız hale ancak açık dönüşümden sonra gerçekleştirilebilir:
void *pv = &x; int value = *(int*)pv; // TAMAM
Boş işaretçiyi (NULL) derecelendirebilir miyiz?
Hayır, bu belirsiz bir davranışa yol açar — bellek hasarı veya çöküş. Derecelendirmeden önce her zaman işaretçiyi kontrol edin:
int *ptr = NULL; if (ptr) { *ptr = 10; // Asla çalışmayacak }
Geliştirici, işlevde bir yerel değişkenin adresini alır, bunu geri döndürür ve ardından çağıran kodda işaretçiyi derecelendirir.
Artılar:
Eksiler:
Değişken için dinamik bellek tahsisi yapılır, adres çağıran koda geri döndürülür ve sonunda free ile serbest bırakılır.
Artılar:
Eksiler: