Aşağıdaki C programı çalıştırıldığında bu programın çıktısı ne olur?
#include <stdio.h>
int main()
{
char *a[] = { "necati", "kagan", "oguz", "gurbuz" };
char **ptr[] = { a + 3, a + 2, a + 1, a }, ***p;
p = ptr;
++p;
printf("%s", **p + 1);
return 0;
}
Yanıt:
Ilk olarak a ile ptr ve p göstericilerinin farklı türden olduğunu bilmek gerekir. a pointeri bir değişkenin adresini taşımaktadır. Yani a pointerinin içeriği bir değerdir.
ptr ve p göstergeleri ise a pointeri gibi bir pointerin adresini tutan pointerdır. ptr ve p göstergeleri başka bir göstergenin adresini taşır ve dolayısı ile ptr ve p pointer içeriği de taşıdıkları pointer adresinin taşıdığı adrestir.
Yukarıdaki şekil üzerinde değişkenleri yerine koyalım. V değer taşıyan bir değişken ve taşıdığı değer 5. Ayrıca bu değişkenin adresi 0x35 adresinde. ad bir pointer olup v değişkeninin adresini taşıyor. Dolayısı ile ad pointerinin içeriği v değişkenin değeridir ve bu değer 5 dir. Ayrıca ad pointerinin kendi adresi 0x66 dır. Add ise ad pointerinin adresini taşıyan bir pointerdır. ad adresi 0x66 olduğu için add pointeri 0x66 adres değerini taşır. add pointerini içeriği ise add taşıdığı adres durumundadır.
Int V; int *ad; int **add; → Tanımlamalar bu şekilde yapılır.
V = 5;
ad = &V; → ad pointerine V adresi atandı.
add = &ad; → add pointerine ad pointerinin kendi adresi atandı.
Aşağıdaki örnek uygulamayı çalıştırarak daha net anlayabilirsiniz.
#include <stdio.h>
int main()
{
int v; int *ad; int **add;
v = 5;
ad = &v;
add = &ad;
printf("v adresi %p \n", &v); // bu iki satırın çıktıları aynı olacaktır.
printf("ad tasidigi adres %p \n\n", ad);
printf("ad kendi adresi %p \n", &ad); // bu iki satırın çıktıları aynı olacaktır.
printf("add tasidigi adres %p \n\n", add);
printf("add kendi adresi %p \n\n", &add);
printf(" v degeri: %d \n", v); // bu iki satırın çıktıları aynı olacaktır.
printf("ad tasidigi adresin degeri %d \n\n", *ad);
printf("add tasidigi adresin icerigi %p \n", *add); // ad adresini verecektir
printf("add tasidigi adresin iceriginin icerigi %d \n", **add); // ad adresine ulaşır ve onun taşıdığı adrese de gider
return 0;
}
char *a[] = { "necati", "kagan", "oguz", "gurbuz" };
char **ptr[] = { a + 3, a + 2, a + 1, a }, ***p;
p = ptr;
++p;
printf("%s", **p + 1);
Bu bilgiler ile soruyu ele alalım. ilk olarak a pointeri char *a; şeklinde bir pointerdır. a nın taşıdığı değer ilk olarak “necati” dizisini başlangıç değeridir.
ptr pointerinin ilk taşıdığı değer a+3 adresidir.
p = ptr; bu atama sonrasında p pointeri de a+3 adresini taşıyor.++p; ile p nin taşıdığı adres bir arttırıldı. Yukarıdaki işlemde p pointerine ptr taşıdığı adres atanmıştı. ++p işlemi ptr dizisinde bir eleman ilerlemeye neden olur. Dolayısı ile ptr dizisinde bulunan a+2 adresine ulaşmış olduk. p pointeri a+2 adresini taşıyor. a+2 demek a pointerin taşıdığı adrese 2 eklemek demektir. Yani adres değiştirmektir. a pointeri “necati” adresini tutarken a+2 ise “oguz” stringinin başlangıç adresini tutar. p pointeri şu an a+2 adresini taşıdığını anladığımıza göre **p + 1 işlemine bakabiliriz. **p işlemi ile içeriğe ulaşılır. Bu içerik “oguz” stringinin başlangıç adresidir. Daha sonra +1 işlemi ile bu stringin başlangıç adresinden bir sonraki adrese gidiyoruz. Yani “oguz” stringinin 2. Üyesine ulaşmış oluruz. Sonuç olarak çıktı “guz” olur.