Sunum yükleniyor. Lütfen bekleyiniz

Sunum yükleniyor. Lütfen bekleyiniz

Göstericiler (Pointers)

Benzer bir sunumlar


... konulu sunumlar: "Göstericiler (Pointers)"— Sunum transkripti:

1 Göstericiler (Pointers)
Güçlü fakat uzmanlaşması zor. Programların referansa göre çağırımını sağlar. Diziler ve stringlerle yakın ilişkilidir.

2 Gösterici Değişkenlerini Bildirmek ve Gösterici Değişkenlerine Atama Yapmak
Değer olarak hafıza adreslerini içerir. Normal bir değişken doğrudan kesin bir değer içerir. Göstericileri kesin bir değer içeren değişkenlerin adreslerini tutar. Bir değeri gösterici ile belirtmek dolaylama(Indirection) yapmak olarak adlandırılır.

3 Gösterici Değişkenlerini Bildirmek ve Gösterici Değişkenlerine Atama Yapmak
Gösterici bildirimleri Gösterici değişkeni ile birlikte * kullanılır. int *myPtr; Bu gösterim ’myPtr bir int göstericisidir’ ya da ‘myPtr, tamsayı tipinde bir nesneyi gösteriri.’ diye okunur. Birden fazla gösterici için her değişkenden önce * kullanılmalıdır. int *myPtr1, *myPtr2; Herhangi bir veri tipi için tanımlanabilirler. Bir göstericiye 0,NULL ya da bir adres atanabilir.(0 ya da NULL hiçbir şeyi göstermez.)

4 Gösterici Operatörleri
& (adres operatörü) Operandının adresini döndüren bir tekli operatördür. int y = 5; İnt *yPtr; yPtr = &y; //yPtr, y’nin adresini alır. //yPtr “gösterir“ y

5 Gösterici Operatörleri
* (içerik operatörü) Operandının(Gösterici) gösterdiği nesnenin değerini döndürür. *yPtr, y değerini döndürür.(çünkü yPtr, y’yi gösteririr) * atama amaçlıda kullanılabilir. *yPtr=7; //y=7 oldu * ve & operatörleri birbirlerinin tersidir. Bir birlerini dengelerler. Not: Öncelik sırası olarak artırma operatörlerine eşittirler.

6 #include <stdio.h>
#include <conio.h> int main() { int a; int *aPtr; a=7; aPtr=&a; printf("aPtr'nin adresi %x",&aPtr); printf("\na'nin adresi %x" "\naPtr'nin degeri %x",&a,aPtr); printf("\na'nin degeri %d" "\n*aPtr'nin degeri %d",a,*aPtr); printf("\n* ve & birbirlerine tersidir." "\n*&aPtr %x\n&*aPtr %x",*&aPtr,&*aPtr); getch(); return 0; }

7 Fonksiyonları Referansa Göre Çağırmak
Gösterici argümanları ile referansa göre çağırmak & operatörü ile argümanların adresleri geçirilir. Hafızadaki gerçek konumunda değişiklik yapma şansına izin verir. Diziler & ile geçirilmez çünkü dizi isimleri zaten birer göstericidir. * Operatörü Fonksiyon içindeki değişken için bir takma ad gibi kullanılır. void double( int *number ) { *number = 2 * ( *number ); } *number alınan değişken için bir takma ad olarak kullanılmıştır.

8 #include <stdio.h>
#include <conio.h> int Kup(int); int main() { int sayi=5; printf("Sayinin esas degeri: %d",sayi); sayi=Kup(sayi); printf("\nSayinin yeni degeri: %d",sayi); getch(); return 0; } int Kup(int a) return a*a*a; #include <stdio.h> #include <conio.h> void Kup(int *); int main() { int sayi=5; printf("Sayinin esas degeri: %d",sayi); Kup(&sayi); printf("\nSayinin yeni degeri: %d",sayi); getch(); return 0; } void Kup(int *aPtr) *aPtr=(*aPtr)*(*aPtr)*(*aPtr);

9 const Belirtecini Göstericilerle Kullanmak
Değişken değiştirilemez. const eğer fonksiyonun değişkeni değiştirmesine gerek yoksa kullanılır. Eğer bir const değişken değiştirilmeye çalışılırsa derleyici bunu yakalar ve hata mesajı verir. const göstericiler Sabit bir hafıza noktasını gösterirler. Tanımlanırken ilk değer atanmalıdır. int *const myPyr=&x; Bir tamsayı için sabit gösterici const int *myPtr=&x; Sabit bir tamsayı için sabit olmayan gösterici const int *const Ptr=&x; Sabit bir tamsayı için sabit bir değişken; x’in kendisi değişse bile *Ptr değişmez.

10 /*Sabit bir veriyi gösteren sabit
olmayan bir gösterici kullanılarak bir stringin karakterlerini sırayla yazdırmak */ #include <stdio.h> #include <conio.h> void printCharacters( const char * ); int main() { char string[] = "Strin karakterleri yaz."; printf( "String:\n" ); printCharacters( string ); printf( "\n" ); getch(); return 0; } void printCharacters( const char *sPtr ) for ( ; *sPtr != '\0'; sPtr++ ) printf( "%c", *sPtr ); /*Sabit bir veriyi sabit olmayan gösterici kullanarak değeri değiştirmeye çalışmak */ #include <stdio.h> void f( const int * ); int main() { int y; f( &y ); return 0; } void f( const int *xPtr ) *xPtr = 100;

11 /*Sabit olmayan bir veriyi gösteren sabit
bir göstericiyi değiştirmeye çalışmak */ #include <stdio.h> int main() { int x, y; int * const ptr = &x; *ptr = 7; ptr = &y; return 0; } /* Sabit bir veriyi gösteren sabit bir göstericiyi değiştirmeye çalışmak*/ #include <stdio.h> int main() { int x = 5, y; const int *const ptr = &x; printf( "%d\n", *ptr ); *ptr = 7; ptr = &y; return 0; }

12 Gösterici İfadeleri ve Gösterici Aritmetiği
Aritmetik operatörler göstericiler ile birlikte kullanılabilir. Bir gösterici arttırılabilir/azaltılabilir.(++/--) Bir tamsayı, göstericiye eklenebilir/çıkartılabilir.(+,+=/-,-=) Göstericiler birbirlerinden çıkartılabilir. İşlemler bir dizi üzerinde uygulanmıyorsa genelde anlamsızdır.

13 Gösterici İfadeleri ve Gösterici Aritmetiği
4 byte’lık int’lerden oluşan 5 elemanlı bir dizi makinada 5 boyutlu int array’da tutulsun( v’dizisi) vPtr=v veya vPtr=&v[0]; Burada vPtr,v’nin ilk elemanını gösterir. vPtr=3000 olsun. vPtr+=2; vPtr’yi 3008 yapar. vPtr artık v[2]’yi göstermektedir. Bunun nedeni göstericiye, gösterdiği nesnenin boyutuyla o tamsayıyı çarparak ekler veya çıkarır. Byte sayısı o veri tipine bağlıdır.

14 Gösterici İfadeleri ve Gösterici Aritmetiği
Göstericilerden çıkarma Gösterici değişkenleri birbirinden çıkarılabilir. vPtr2 = &v[2]; vPtr = &v[0]; vPtr2-vPtr’nin sonucu 2 olacaktır. Gösterici karşılaştırma(<,==,>) Göstericiler aynı dizinin elemanlarını göstermiyorsa anlamsızdır. Daha yüksek numaralı dizi elemanının tespiti için kullanılır. Göstericinin ‘0’ ya da ‘NULL’ olup olmadığının kontrolü için kullanılır.

15 Gösterici İfadeleri ve Gösterici Aritmetiği
Aynı tipteki göstericiler birbirlerine atanabilirler. Eğer aynı değilse dönüşüm operatörü kullanılmalıdır. İstisna: void tipi gösterici(void*) Genel göstericidir. Herhangi bir tipini temsil edebilir. Tüm göstericiler void tipi bir göstericiye atanabilir. void gösterici her tipte göstericiye atanabilir. void tipindeki göstericilerin nesnelerine erişilemez. Erişim için veri tipi net bilinmelidir.

16 Göstericiler ve Diziler Arasındaki İlişki
Diziler e göstericiler yakın ilişkilidir. Dizi ismi sabit bir gösterici gibidir. Göstericiler, dizilerin belirteçle gösterimi de dahil her işlemde kullanılabilirler. b[5] dizi ve bPtr göstericisi tanımlansın. Birini diğerinin yerine kullanabilmek için eşitleyelim: bPtr=b; Dizi ismi b aslında b[5] dizisinin ilk elemanın adresidir. bPtr=&b[0]; Açıkça bPtr’ye b dizisinin ilk elemanının adresi atanmıştır.

17 Göstericiler ve Diziler Arasındaki İlişki
b[3] elemanı *(bPtr+3) şeklinde de erişilebilir. Burada 3 offset olarak adlandırılır. Gösterime gösterici/offset denir. bPtr[3]şeklinde de erişilebilir. Buna da gösterici/belirteç gösterimi denir. bPtr[3],b[3] ile birdir. Aynı zaman *(b+3) şeklinde dizi üstünde gösterici aritmetiği yardımıyla da erişilebilir.

18 #include <stdio.h>
#include <conio.h> int main() { int b[] = { 10, 20, 30, 40 }; int *bPtr = b; int i, offset; printf( "d dizi asagidaki metdolarla yazilmistir:\n" "Dizi belirtecleri yontemi\n" ); for ( i = 0; i < 4; i++ ) printf( "b[ %d ] = %d\n", i, b[ i ] ); printf( "\nGosterici/offset yonetmi,\n" "gosterici dizinin ismiyken\n" ); for ( offset = 0; offset < 4; offset++ ) printf( "*( b + %d ) = %d\n", offset, *( b + offset ) ); printf( "\nGosterici belirtec yontemi\n" ); printf( " bPtr[ %d ] = %d\n", i, bPtr[ i ] ); printf( "\nGosterici/offset yontemi\n" ); printf( "*( bPtr + %d ) = %d\n", offset, *( bPtr + offset ) ); getch(); return 0; }

19 Dinamik Hafıza Tahsisi
Standart kütüphanedeki malloc(), calloc(), realloc(), free() fonksiyonları ile program dinamik olarak bellek alanı isteyebilir. İstenen belleğin başlangıç adresi bir işaretçide tutularak ile bu bellek üzerinde işlem yapılır. void* malloc(boyut) boyut byte kadar yeni bellek alanı ayırır. void* calloc(adet, boyut) boyut*adet byte kadar yeni bellek alanı ayırır. void* realloc(işaretçi, boyut) işaretçi tarafından işaret edilen bellek alanını boyut byte kadar olacak şekilde değiştirir. free(işaretçi) işaretçi için ayrılan bellek alanı geri verilir.

20 #include <stdio.h>
#include <stdlib.h> #include <conio.h> int main(){ int *x,i,N,toplam=0; float ortalama; printf("Eleman sayisi "); scanf("%d",&N); x = (int *) malloc(N*sizeof(int)); //N tane int gözü isteniyor (Nx2 byte) printf("Elemanlari girin:\n"); for(i=0;i<N;i++){ printf("%d.eleman = ",i+1); scanf("%d",&x[i]); // x[i] ile *(x+i) aynı anlamda ! toplam += x[i]; } free(x); // ayrılan yer boşaltılıyor... ortalama = (float) toplam/N; printf("Bu %d sayinin ortlamasi %f dir\n",N,ortalama); getch(); return 0;

21 Gösterici Dizileri Diziler göstericiler içerebilir.
Örneğin; takım string dizisini ele alalım char *takim[4]={"kupa", "karo","sinek","maca"}; C’de stringl’er, gerçekte ilk karakteri gösteren göstericilerdir. char*- takım’in her bir elemanı char gösteren bir göstericidir. String’ler aslında takım dizisinde tutulmazlar sadece bu string’leri gösteren göstericiler tutulut.

22 Fonksiyonları Gösteren Göstericiler
Bir fonksiyonu gösteren gösterici Fonksiyonunun adresini tutar. Bir dizi isminin ilk elemanın adresi olmasına benzer. Fonksiyon isimleri, fonksiyonun görevini yapan kodun hafızadaki başlangıç adresidir. Fonksiyonları gösteren göstericiler Fonksiyonlara geçirilebilir. Fonksiyonlardan geri döndürülebilir. Fonksiyon gösteren diğer göstericilere atanabilir.

23 #include <stdio.h>
#include <conio.h> void yazdir(int,int,int(*)(int,int)); int kucuk(int,int); int buyuk(int,int); int main() { int a,b,secim; printf("Iki tamsayi giriniz: "); scanf("%d%d",&a,&b); printf("Buyuk olani bulmak icin 1" " kucuk olani bulmak icin 2 giriniz: "); scanf("%d",&secim); if(secim==1) yazdir(a,b,buyuk); else yazdir(a,b,kucuk); getch(); return 0; } void yazdir(int a,int b,int(*kar)(int,int)) { int sonuc=0; sonuc=(*kar)(a,b); printf("Sonuc: %d",sonuc); } int kucuk(int a,int b) if(a<b) return a; else return b ; int buyuk(int a,int b) if(a>b) return a;


"Göstericiler (Pointers)" indir ppt

Benzer bir sunumlar


Google Reklamları