Pointerlar
ve kullanımları
Yazan :
Şadi Evren ŞEKER
Pointer (gösterici) basitçe bir değişkenin bir hafıza alanını göstermesi
demektir. C dilinde pointerlar:
Veritipi *pointeradi;
Şeklinde tanımlanır. Burada veritipi int, char, float
gibi değişken tipleridir. Pointer adı ise bir değişken
adının taşıması gereken özellikleri taşıyan ve tanımlandığı scope
(geçerlilik alanında) yaşayacak olan değişken adıdır.
Bir değişkenin başına & işareti geldiğinde ise bu değişkenin adresini
temsil eder. Yani değişken hafızada nereye konulduysa bu konulan yerin adresine
bu işaret ile ulaşılabilir.
Örneğin,
int *p;
int a=10;
p=&a;
satırından sonra hafızada integer
değer gösteren p isminde bir pointer tanımlanmış
olur. Bunu hafızda temsili olarak gösterecek olursak:
Adres
değeri |
içeriği |
matıksal ismi |
A101 |
|
|
A102 |
|
|
A103 |
|
|
A104 |
|
|
A105 |
|
|
A106 |
|
|
A107 |
A116 |
p |
A108 |
|
|
A109 |
|
|
A110 |
|
|
A111 |
|
|
A112 |
|
|
A113 |
|
|
A114 |
|
|
A115 |
|
|
A116 |
10 |
a |
A117 |
|
|
A118 |
|
|
A119 |
|
|
A120 |
|
|
Yukarıdaki temsili resimde, ilk sütun adres değerlerini temsil
etmektedir, buna göre hafızanın a101 ile a120 numaralı adresleri arasındaki
bilgiler gösterilmiştir ( bu değerler hexadecimal
olup temsili olarak yazılmıştır)
Kodda bulunan p ve a değerlerinin hafızda hangi bölüme atanacağı
çalıştırma sırasında ( execution time ) belirlenir dolayısıyla
tam olarak nerede bulunacağı bilinemez ancak p tanımlnadıktan
sonra a107 adresine ve a tanımlandıktan sonra a116 adresinin ayrıldığını kabul
edelim. Bu durumda p’nin değeri a107 numaralı adreste
olacaktır.
Kodda a değerine 10 konulmuştur bu durumda a’nın
değerinin durduğu a116 numaralı adreste sayısal olarak 10 yazacaktır.
Kodda a’nın taşıdığı adres değeri, p’nin içine atılmıştır. Bu durumda p’nin
değeri a’nın adresi olacaktır.
Aşağıdaki örnek kodu çalıştırınız ve yorumlayınız:
#include
<stdio.h>
int
main(){
int a=10;
int *p;
p=&a;
printf("%d\n",*p); //
p’nin gösterdiği yeri basar
printf("%d\n",p); // p’nin değerini yani, p’nin
gösterdiği yerin adresini basar
printf("%d\n",a); // a’nın değerini basar
printf("%d\n",&a);
//a’nın adresini basar
printf("%d\n",&p);
//p’nin adresini basar
}
C dilinde her dizi bir pointer her pointer da doğal bir dizidir.
char str[80], *p1;
p1 = str;
Burada p1, str dizisinin - stringinin
- ilk elamaninin adresinin degerini
alir. Yani string adi, aslinda o stringin hafizadaki baslangiç adresini = stringin ilk karakterinin adresini tutmaktadir.
str dizisinin 5. elemanina erismek için ise;
str[4] veya *(p1+4)
ifadelerini kullaniriz. Her ikisinin de anlami aynidir.
C’de dizi elemanlarina 2 sekilde ulasilir: pointer kullanimi ile ve indis kullanimi ile. Indis kullanimi gelistirme ve anlama bakimindan bir kolaylik saglasa da, hiz önemli bir konu oldugundan C programcilari
genelde dizi erisimini pointer
kullanarak yaparlar. Asagida ayni isi yapan iki
fonksiyon yeralmaktadir:
void
putstr(char *s)
{
int t;
for (t=0; s[t]; ++t) putchar(s[t]);
}
void putstr(char *s)
{
while (*s) putchar(*s++);
}
C dilinde bir pointer’ı array gibi kullanmak için:
int *p = (int *) malloc ( sizeof(int)*10);
şeklinde bir satır yazmak yeterlidir. Burada klasik dizi tanımından farksız bir işlem yapılmış, hafızada 10’luk bir alan açılmış ve tipi integer olarak tanımlanmıştır.
Pointer’ın farkı bu alana erişim şeklindedir. Yani dizi tanımlarında olduğu gibi köşeli parantezle (a[3] gibi) erişmek yerine pointer üzerinde işlem yapmak gereki ancak yöntem bir önceki örnekte olduğu gibi
printf(“%d\n”,*(p+4)) şeklinde işleyebilmektedir.