pointerlar etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
pointerlar etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

16 Kasım 2016 Çarşamba

Her Yönüyle Pointerlar - 2

Dizilerde pointer kullanımı biraz farklıdır. Tanımlanmış bir dizi için atanan adreslerin hepsi atanan pointer ile tutulabilir.

int dizi[5]={1,2,3,4,5};
   
    int *p;
   
    p = dizi;

Dizinin tüm elemanlarını adresleri p pointerına aktarılmış olur. İndis değerlerine göre p, p+1, p+2 şeklinde tüm dizi elemanlarına ulaşılabilir.

Aşağıdaki örneğe bakalım;

 #include <iostream>  
 int main() {  
      int dizi[5]={1,2,3,4,5};  
      int *p;  
      p = dizi;  
      printf("%u \n",p);  
      printf("%u \n",p+1);  
      printf("%u \n",p+2);  
      printf("%u \n",p+3);  
      printf("%u \n",p+4);  
      //adresteki veri yazdırılmak istenirse  
      printf("\nDizinin 3. elemaninin adresindeki veri = %d \n",*p+2);  
      //pointerlara istenirse dizinin ilk ve ikinci elemanları da atanabilir  
      p = &dizi[0]; // burada sadece dizinin ilk elemanının adresi tutulur  
      printf("\n\n%u ",p);  
 }  

Alt satırda p =&dizi[0] diyerek istersek dizinin tek bir elemanını da pointera aktarabiliriz. Programın çıktısı aşağıdaki gibi olacaktır.


Pointer ile String Kullanımı

Pointer ile string kullanım mantığı normal diziler ile aynı şekildedir. Herhangi bir karakter dizisinin başlangıç adresi pointer değişkende saklanır, her karakter için pointer indeksi artırılabilir.

char yazi[]="karakter";
    char *p;
   
    p=yazi;

Aşağıdaki örneği inceleyelim;

 #include <iostream>  
 int main() {  
      char yazi[]="karakter";  
      char *p;  
      p=yazi;  
      printf("%u adresindeki karakter: %c\n",p,*p);  
      printf("%u adresindeki karakter: %c\n",p+1,*p+1);  
      printf("%u adresindeki karakter: %c\n",p+2,*p+2);  
 }  

Her bir karakter için bir byte alan tuttuğu için pointerların işaret ettiği adresler birer artacaktır. Programın çıktısı aşağıdaki gibi olacaktır.



Her Yönüyle Pointerlar - 1

Bilgisayar programcılığında tanımlanan her değişken Ram üzerindeki bellek gözlerinde bulunur. Bu bellek gözlerininde birer adresi mevcuttur. Derleme işlemi sonrasında bu değişkenler makine koduna dönüştürüldüğünde adresleri de derlenir böylece işlemci gerekli olduğunda o adrese giderek değişken değerini alır. 

int b=5;

şeklinde tanımlanan b değişkeni aslında RAM üzerinde bir bellek gözünde yer tutar.

b değişkeni için ram organizasyonu
Yukarıda tanımlanan b değişkeni şekilde gösterildiği gibi belleğin 10548 nolu gözünde tutulsun. Derlenen program b değişkenine ulaşmak için bu adresi kullanacaktır. Bu gözde tutulan veri ise 5 değeridir. İşte tam bu noktada pointer tipi değişkenler işin içine girmektedir. Pointer tipi değişkenler herhangi bir değişkenin adresini tutarlar, istenildiğinde o göze giderek oradaki değeri getirirler. Unmanaged programlama ve performans gerektiren işlerde pointer tipi değişkenler sıklıkla kullanılır.

Pointer tipi değişkenler başlarında * işareti ile tanımlanırlar. Aşağıdaki resimde  gösterileni örnek verirsek;

int *a;
int b;

a=&b

Şeklinde tanımlanan *a ve b değişkenleri için b'nin adresi (1008) a değişkeninim bellek gözüne yazılmıştır. Programın ilerleyen aşamalarında *a şeklinde çağrılan  a değişkeni her zaman 1008 numaralı gözüne gidecektir. O gözde hangi değer varsa onu getirecektir.
Bir pointer örneği
Şimdi küçük bir kod yazıp sonuca bakalım;

 #include <iostream>  
 int main() {  
      int b=5;       
      int *a;  
      a=&b; //b değişkeninin adresi a'nın bellek gözüne yazılır  
      printf("%d",a); // a değişkeni b değişkeninin adresini tutar  
      printf("\n%p",*a); // *a ise bu adresteki datayı alır.  
      printf("\n%u",*a); // pointerlar %p ve %u formatlarıyla ekrana bastırılır.  
 }  

Programın çıktısı şu şekilde olacaktır;


a pointerına b değişkeninin adresi a=&b ifadesi ile aktarılır.  Bundan sonra a değişkeni * işareti konulmadan yazdırılırsa direk bellek gözündeki veri, ki bu b'nin adresidir. Bu değer Ram'in 7339588 nolu adresidir. Alttaki %p ve %u şeklinde yazdırılırsa b'nin adresini işaret eder. Bu aşamadan sonra derleyici b'nin adresine gider ve oradaki 5 değerini yazar. Kısaca * karakteri işaretçidir, bellek gözünde eğer adres varsa, o adrese gider ve ordaki datayı alır.

 Bir diğer örnek;

 #include <iostream>  
 int main() {  
      int b,a=1;  
      int *pa1, *pa2;  
      pa1 = &a;  
      pa2 = pa1;  
      b= ++(*pa1);  
      *pa1 = *pa2 + b;  
      printf("b degiskeni : %d\n", b);   
      printf("a degiskeni : %d\n", a);   
      printf("pa1 degiskeni : %u yonlendirdigi adres %d\n", *pa1,pa1);  
      printf("pa2 degiskeni : %u yonlendirdigi adres %d", *pa2,pa2);  
 }  

Yukarıdaki programda değişkenler tanımlandıktan sonra pa1 içine &a ifadesi ile a değişkeninin adresi kopyalanıyor. Daha sonra pa1 ve pa2 birbirine eşitleniyor, bu aşamada her iki pointer değişkenimizde a değişkeninin adresini tutmaya başlıyor. b = ++(*pa1) ifadesinde ise pa1'in tuttuğu adresteki veriyi bir artırıyor yani a değişkenini 1 artırıp b'yi 2 yapıyor. *pa1 = *pa2 +b ifadesi aslına a değişkeni ile b değişkeninin toplamıdır ve sonuç 4 oluyor. Bu değer a'nın adresini tutan pa1 ile a'nın bellek gözüne yazılıyor. Program çıktısı ve değişkenler aşağıdaki gibi olacaktır;