Temel C Programlama -32- Çift İşaretçiler

Önceki başlıkta işaretçileri en basit yoldan anlatmaya çalıştık. Bütün işaretçi eğitimlerinde işaretçiler kutu şeması ile anlatılmaya çalışılır. Biz de bu yöntemi faydalı gördüğümüz için kendimiz böyle bir şema hazırladık. Bu şemalarla öncelikle basit bir işaretçiyi sonrasında ise işaretçiyi gösteren işaretçiyi anlatacağız.

Basit Bir İşaretçi

Bizim bir tam sayı değişkenimiz olsun ve tekrardan onu bir işaretçi vasıtasıyla işaretleyelim. Bunun için şöyle bir kod yazacağız.

int d = 55;
int *p;
p = &d;

Öncelikle d tamsayı değişkenini tanımlayıp buna 55 değerini aktarıyoruz. Sonrasında p adında bir işaretçi değişkeni tanımlayıp d değişkeninin adresini buna aktarıyoruz. Kodlar işletildikten sonra hafızadaki görünümü şu şekilde olacaktır.

Burada d değişkeninin değeri kutu içerisinde gösterilmiştir. Kutuyu bir hafıza hücresi olarak düşünebilirsiniz. Her kutunun değeri olduğu gibi adres değeri de vardır. Bu değer ile adres değeri birbiriyle alakasızdır. Kısacası değer kutunun içerisinde yer alır ve adres çağırılarak veri yolundan okunur. İşaretçi değişkeni ise diğer değişkenlerden farklı olarak içinde adres değerini bulundurabilir. Bu adres değeri de bir değişkenin, fonksiyonun veya dizinin adres değeri olabilir. Bu durumda &d dediğimiz zaman 0xF0 değeri geri dönmektedir ve bu da p işaretçisine aktarılmaktadır. Artık p işaretçisinin içine baktığımızda bize d değişkeninin adresini “göstermektedir.” Böylelikle bizi d değişkenine yönlendirecek bir kılavuzumuz olmuş olur.

Çift İşaretçiler

Şimdi işi biraz daha karmaşık hale getirelim ve işaretçinin işaretçisi olur mu buna bakalım. Yukarıdaki gibi bir kod yazacağız fakat bir değişkenin ve işaretçinin yanı sıra işaretçiyi gösteren çift işaretçi yer alacak. Bu çift işaretçi meselesi uygulamada kafanızı karıştırabilse de bunu en basit şekliyle anlatmaya çalışacağız. Şimdi kodu inceleyelim.

int d = 55;
int *p;
p = &d;
int **pp; // çift işaretçi
pp = &p; // işaretçinin adresi

Burada pp diyerek işaretçiyi gösteren bir işaretçi tanımladık. İşaretçiyi gösteren işaretçiler diğer işaretçilerden farklı olarak “” belirtecini alırlar. Sonrasında ise işaretçinin adresini yine adressof (&) operatörü ile çift işaretçiye aktardık. Dikkat edin, işaretçinin bulundurduğu adres değerini değil işaretçinin kendi adresini aktardık. Çünkü işaretçiler adres verisi depolayan birer değişkendi. Bu değişkenler de hafızada bir yer işgal edecek ve bu yerin de muhakkak bir adresi olacaktır.

Burada **pp diye tanımladığımız pp çift işaretçinin de kendi adresi bulunmaktadır. Ama değer olarak normal bir değişkenin değil bir işaretçi değişkeninin adresini bulundurmaktadır. İşaretçi değişkeni ise bizi bir normal değişkene götürmektedir. Burada bütün işaretçilerin ve değişkenlerin birer değeri olduğu gibi adres değerlerinin olduğunu da unutmayalım. Değer yani veri programlamada bizi ilgilendiren kısım olduğu için sürekli içli dışlı oluruz. Adres ise donanım ve makine dili ile alakalı kısım olduğu için gözümüzün önüne gelmez. Aslında bizden saklanmaktadır. Bunu daha öncesinde size söylemiştik. Bizden saklanan bu adresi ise bazen bizim bilmemiz gerekebilir. İşte burada işaretçileri kullanmaktayız.

Şimdi bu çift işaretçinin nasıl çalıştığını görmek için bir program yazalım ve deneyelim.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
	int d = 55;
	int *p;
	p = &d;
	int **pp; // çift işaretçi
	pp = &p; // işaretçinin adresi		
	printf("Bizim Degiskenin Degeri: %i \n", d);
	printf("Bizim Degiskenin Adresi: %p \n", &d); // Burada işaretçi yok sadece adres var.
	printf("Isaretcinin Adresi: %p \n", p);
	printf("Isaretcinin Isaret Ettigi Deger:%i \n", *p);
	printf("Cift Isaretcinin Isaret Ettigi Deger:%i\n", **pp);
	printf("Cift Isaretcinin Kendi Degeri: %p \n", pp);
	printf("Cift Isaretcinin Adresi %p", &pp);
	return 0;
}

Burada önceki kısmı daha önce anlattığımız için sadece çift işaretçi ile alakalı olan kısımları size açıklayacağım. *pp diyerek çift işaretçinin işaret ettiği değeri gösteriyoruz. Bu işaret ettiği değer işaret ettiği işaretçinin işaret ettiği değer olmaktadır. Yani bizi zincirin en sonundaki işaret edilen tam sayı değişkeninin değerine götürmektedir. Bu değer ise 55 sayısıdır. Sonrasında ise çift işaretçinin kendi değerini %p formatı ile doğrudan pp yazarak görmekteyiz. Bu da p işaretçisinin adresinden başka bir şey değildir. Sonrasında ise pp işaretçisinin kendi adresini ekrana yazdırdık. Bu değer pp işaretçisinin kendi adres değeri olup geri kalan değişkenler ve işaretçilerle alakalı değildir. Bilgi vermek için size gösterdik.

C dilinde &* ve *& operatörlerini beraber yazmanız aynı çarpma ve bölme işlemlerinin birbirini götürmesi gibi birbirini sıfırlayacaktır.

Şimdi programın çıktısına göz atalım ve 64 bitlik bir sistemde nasıl göründüğünü görelim.

Unutmayın çift işaretçiye tek “*” operatörü koyduğunuz zaman sizi işaret ettiği işaretçiye götürür. Eğer çift yıldız operatörü “**” koyarsanız işaret ettiği işaretçinin işaret ettiği değere götürür. Burada çift işaretçinin gösterdiği işaretçinin gösterdiği değere götürmüştür.

İşaretçiler daha önce bahsettiğimiz gibi bellek adreslerinin tamamına erişmemizi sağlayan bir özelliktir. Fakat günümüzde kullandığımız Windows gibi işletim sistemlerinde her program (görev) için belli bir bellek bölümlendirmesi bulunmaktadır. Bir program kendine ayrılmış bellek bölümünde çalışabilir fakat belleğin tamamında çalışamaz. Bu yüzden biz belleğin önemli noktalarına veya donanımla alakalı özelliklere erişememekteyiz. Eğer ben bunu MS-DOS gibi bir işletim sisteminde yapsaydım işaretçilerle çok ilginç gösteriler sunabilirdim. Fakat bir programcı olarak bilmeniz gerekir ki artık işletim sistemleri donanım ile aranızda büyük bir bariyer olmaktadır. Siz asla doğrudan ses kartına veya ekran kartına erişemezsiniz. İşletim sistemi bile donanıma erişmek için sürücüleri kullanır. Siz ise işletim sisteminin sağlamış olduğu kütüphaneleri kullanırsınız. Örneğin grafik için DirectX veya OpenGL ya da Windows elementleri ve özellikleri için Windows API bunların başlıcalarıdır.

Last updated