Sunuyu indir
Sunum yükleniyor. Lütfen bekleyiniz
YayınlayanAhmet Denkel Değiştirilmiş 6 yıl önce
1
BİLGİSAYAR PROGRAMLAMA Ders 11: İşaretçi (Pointer) Kullanımı
Yrd. Doç. Dr. Altan MESUT Trakya Üniversitesi Bilgisayar Mühendisliği
2
İşaretçi (Pointer) İçerisinde bellek adresi tutan değişkendir.
Daha önce gösterilen tüm değişkenler tanımlandıkları türe göre bir değer saklıyor ve bu değere ulaşılmak istendiğinde doğrudan değişkenin ismi ile erişilebiliyordu. İşaretçiler ise değerin bulunduğu bellek hücresinin adresini tutmak sureti ile dolaylı olarak değere erişebilirler.
3
İşaretçi Tanımlama İşaretçiler de değişkenler gibi kullanılmadan önce tanımlanmalıdır. Değişken tanımından farkı işaretçiye verilen isimden önce * işareti yer alır: int *ptr; Burada tanımlanan ptr aslında işletim sisteminin atadığı adresin değerini saklar. O adreste saklanan değere ise *ptr yazılarak yani o adres işaret edilerek ulaşılır. adres (ptr) 5 4 -1 8 değer (*ptr)
4
#include <stdio.h>
İşaretçinin Boyutu İşaret ettiği verinin türü ne olursa olsun işaretçiler 32-bit işletim sistemlerinde 32 bit (4 byte), 64-bit işletim sistemlerinde 64 bit (8 byte) yer kaplar. main(){ char *cptr; int *iptr; double *dptr; printf("%d\n", sizeof(cptr)); printf("%d\n", sizeof(iptr)); printf("%d\n", sizeof(dptr)); printf("%d\n", sizeof(*cptr)); printf("%d\n", sizeof(*iptr)); printf("%d\n", sizeof(*dptr)); } #include <stdio.h> NOT: Önceki slaytta adreslerin 4'er 4'er arttığına dikkat (int değer saklandığı için)
5
değeri değiştirme & adresi değiştirme
Eğer iptr adresindeki değeri değiştirmek istersek: *iptr = 100; gibi bir kullanım ile o adresteki değere 100 sayısını atayabiliriz. Eğer adresi değiştirmek istersek iptr = 100; gibi bir kullanım ile iptr'nin artık 100 adresini göstermesini sağlayabiliriz. Bu kullanım hatalara neden olabileceği için tavsiye edilmez. Eğer "işletim sistemi" yada "aygıt sürücüsü" geliştirmek gibi sistem programlama alanında çalışmıyorsak, kullanacağımız adresi biz belirlememeliyiz (işletim sistemi belirlemeli)
6
& operatörü Bu operatör bir değişkenin önüne yazıldığında o değişkenin saklı olduğu adresi verir. Daha önce scanf içinde bu operatörü kullanmıştık: scanf("%d", &sayi); İlk parametrede "%d" ile integer yani 4 byte olarak hafızaya yazılacağı, ikinci parametrede &sayi ile hangi adrese yazılacağı verilmektedir.
7
Örnek
8
Hafızadan yer tahsisi (malloc)
Önceki slaytta a değişkeninin adresi aptr'ye atanmıştı. Eğer işaretçi için yeni bir adres isteyecek isek malloc fonksiyonunu kullanmalıyız: int *iptr = (int*)malloc(sizeof(int)); Eğer tanımlama anında değil de sonradan yer tahsisi yapacak isek *iptr = … değil iptr = … şekilden kullanılır: iptr = (int*)malloc(sizeof(int)); C++ malloc yerine kullanımı daha kolay olan new operatörünü içerir: int *iptr = new int; 4 NOT: malloc fonksiyonu stdlib.h kütüphanesinde yer almaktadır.
9
i = adres, *i = adresin içeriği, &*i = adresin içeriğinin adresi
malloc örneği (1) #include <stdio.h> #include <stdlib.h> main(){ int a; printf("%d adresi icin deger gir : ", &a); scanf("%d", &a); printf("%d adresindeki deger : %d\n", &a, a); int *i = (int*)malloc(4); // int *i = new int; printf("%d adresi icin deger gir : ", i); scanf("%d", i); printf("%d adresindeki deger : %d\n", i, *i); } NOT: scanf’te &*i yazmak yerine sadece i yazdık. Çünkü önceki örnekte gördüğümüz gibi & ve * yan yana kullanıldığında birbirini götürür. i = adres, *i = adresin içeriği, &*i = adresin içeriğinin adresi
10
malloc örneği (2) #include <stdio.h> #include <stdlib.h> main(){ char *cptr; int *iptr; double *dptr; cptr = (char*)malloc(sizeof(char)); iptr = (int*)malloc(sizeof(int)); dptr = (double*)malloc(sizeof(double)); printf("%d - %d\n", cptr, cptr+1); printf("%d - %d\n", iptr, iptr+1); printf("%d - %d\n", dptr, dptr+1); } NOT: Görüldüğü gibi adresi 1 arttırmak, işaretçinin işaret ettiği verinin türünün boyutu kadar ileri gitmesine neden olur.
11
Dizi – String – İşaretçi
Dizi ismi aslında dizinin başlangıç adresini tutar (yani bir işaretçi gibi düşünülebilir). İki hafta önce bir string tanımlanırken char dizisi yerine char * kullanılabileceğini görmüştük. Dizilerin boyutu bir sabit ile tanımlanabilir, değişken olamaz: const int a = 10; int b = 10; int dizi1[a]; int dizi2[b]; Doğru Dizinin boyutu program çalışırken (run-time) değiştirilemez. Dinamik boyutlu dizi tanımlanamayacağı için işaretçi kullanmalıyız.
12
Dinamik boyutlu diziler
İşaretçi kullanmanın en büyük faydalarından biri programın çalışma anında (runtime) hafızadan malloc (yada new) komutu ile istenilen büyüklükte yer tahsisi yapılabilmesidir. Bu sayede programcının belirlediği statik büyüklükte tanımlanan diziler yerine, programı kullanan kişinin ihtiyacı doğrultusunda hafızadan yer alınabilir.
13
Örnek #include <stdio.h> #include <stdlib.h> main(){ int n, i, *dizi; // dizinin boyutu belli değil printf("dizinin boyutunu girin : ", n); scanf("%d", &n); dizi = (int*)malloc(sizeof(int)*n); // dizi = new int[n]; de olur for(i = 1; i <= n; i++) { printf ("%d. sayi : ", i); scanf("%d", dizi); // &*dizi yerine kısaca dizi yazdık dizi++; } printf("dizinin tersten siralanisi : \n"); dizi--; printf ("%d\n", *dizi); İşaretçi kullanımı dizi kullanımından biraz farklı olsa da, temelde ikisi de hafızada ardışık adreslerde aynı türden verileri saklamak için kullanılırlar.
14
Önceki örnekte dizinin tersten sıralanışı kısmı aşağıdaki gibiydi: printf("dizinin tersten siralanisi : \n"); for(i = 1; i <= n; i++) { dizi--; printf ("%d\n", *dizi); } Aşağıdaki yazımlar da aynı işi yapacaktır: dizi = dizi - n; for(i = n-1; i >= 0; i--) { printf ("%d\n", dizi[i]); for(i = -1; i >= -n; i--) { Değer girereken n defa dizi++ yaptığımız için şimdi n adres geriye gidiyoruz Döngü öncesinde n adres geri gitmeyi sildik, döngüyü -1’den başlattık. Dizi indisleri negatif olmasına rağmen program çalışır
15
Örnek
16
İşaretçi kullanmanın avantajları ve dezavantajları
Liste, kuyruk, ağaç gibi genişletilebilen esnek veri yapılarının oluşturulmasına imkan sağlar Değişken büyüklükte dizilerin (yada nesnelerin) fonksiyonlara parametre olarak iletilmesini sağlar Dezavantajları: Slayt 5'teki gibi hatalı kullanımlar nedeniyle programın yada bilgisayarın kilitlenmesi gibi hatalara neden olur İşletim sistemine ve programı yürüten makineye bağımlı kodlara neden olur
Benzer bir sunumlar
© 2024 SlidePlayer.biz.tr Inc.
All rights reserved.