Sunuyu indir
Sunum yükleniyor. Lütfen bekleyiniz
YayınlayanDilara Heper Değiştirilmiş 8 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. 5048 60312806031284603128860312926031296 adres (ptr) değer (*ptr)
4
İş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)); } NOT: Önceki slaytta adreslerin 4'er 4'er arttığına dikkat (int değer saklandığı için) #include
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; NOT: malloc fonksiyonu stdlib.h kütüphanesinde yer almaktadır. 4
9
malloc örneği #include 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.
10
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.
11
Örnek 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"); for(i = 1; i <= n; i++) { dizi--; printf ("%d\n", *dizi); } #include İş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.
12
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]; Dizinin boyutu program çalışırken (run-time) değiştirilemez. Dinamik boyutlu dizi tanımlanamayacağı için işaretçi kullanmalıyız. Doğru
13
Örnek
14
İşaretçi kullanmanın avantajları ve dezavantajları Avantajları: – 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.