3.2. Göstergeler Ve Diziler
Şimdi, gelin aşağıdakini inceleyelim
int z[N], i;
…
for (i=0; i<N; i++)
*(z+i) = 0;
Buradaki atama bir önceki kısmın başında
verilenle tamamen aynıdır. Neden? z
ile &z[0]
aynı şey olduğunu zaten biliyorsunuz. Böylece *(z+i)
ile
*(&z[0]+i)
aynı şeydir. Yukarıda gösterge
toplama işlemleri ile ilgili anlatılanlara göre, aynı zamanda
*(&z[i])
ile eşdeğerdir. Şimdi, *
ile
&
birbirinin aksi işlemleri olduğuna göre, birbirlerini
götürürler. Böylece ifade z[i]
olur. Aslında, derleyici
z[i]
şeklindeki bir ifadeyi hemen *(z+i)
şekline
dönüştürür, yani ilk şekil programcının rahatlığı için dilde sağlanan bir
kısaltma gibi düşünülebilir. Hatta z[i]
yerine, biraz garip
olan, i[z]
ifadesini de kullanabilirsiniz.
Dizi isimlerinin gerçekte gösterge olduğunu bildiğinize göre,
float z[N];
ile
float *g;
arasındaki fark nedir, diye sorabilirsiniz.
g = z
ataması bir yapıldı mı,
g
, &z[0]
, ve z
,
kendi aralarında,
g+i
, &z[i]
, ve z+i
,
ve
*(g+i)
, z[i]
, ve *(z+i)
de, aynı şekilde, kendi aralarında eşdeğerdir.
Fakat önemli bir fark var:
z = g;
yazamazsınız çünkü g
bir değişken
gösterge, oysa z
bir değişmez göstergedir.
Şimdi değişken tanımlamalarına geri dönelim.
float z[N];
derleyicinin, ana bellekte N
adet
float
değişken için gerekli yer ayırmasına yol
açacaktır. (Birçok sistemde bu alan 4×N
bayttır.)
Bu bellek öbeğinin başlangıç adresi z
değişmezinin
(gösterge) değeri olur. z
bir değişken değildir, çünkü
bu (değişmez) adresi saklamak için bellekte ayrıca yer ayrılmamıştır.
Diğer yandan,
float *g;
bir adres tutacak genişlikte bir yerin ayrılmasını
sağlar (32 bitlik sistemlerde 4 bayt, 64 bitlik sistemlerde 8 bayt).
Programın yürütülmesi esnasında, bu g
değişkeni
değişik zamanlarda değişik değerler tutabilir. Başlangıçta ise, şimdiye
kadar gördüğümüz değişken türleri için, değeri belirsizdir.