Bilgisayar Programlama 1 DERS 11: POINTER (İŞARETÇİLER) DR. HÜSEYİN BAHTİYAR 1
Pointer Nedir İşaretçiler (pointerlar) C++ dilinin en temel yapı taşlarından biridir. İşaretçiler konusu C++ ı diğer dillerden ayıran en önemli özelliklerinden biridir. C++ ta işaretçiler değişkenlerin bellekteki adreslerini tutabilme ve onlarla işlem yapabilme olanağı sağlar.
Pointerlar Pointerları, verilerin bilgisayar hafızasında tutulduğu fiziki adresi olarak tanımlayabiliriz. Donanımsal açıdan bakıldığında bu adres bellekte yer gösteren bir sayıdır. İşlemci, bellekteki bir yere o bölgenin adres bilgisiyle erişebilir. Değişkenlerin adresleri, genelde, derleyici ve işletim sistemi tarafından ortaklaşa olarak belirlenir. Değişken adresleri program çalışmadan önce kesin olarak bilinemez ve önceden tespit edilemez. Programcı adresleri ancak programın çalışması sırasında görebilir.
Pointerlar Belli bir tipte değişken tanımlanıp ve bir değer atandığı zaman, o değişkene dört temel özellik eşlik eder: değişkenin adı değişkenin tipi değişkenin sahip olduğu değer (içerik) değişkenin bellekteki adresi
int tam = 33; Pointerlar
Pointerlar Pointerlara, veriler değil, ilgili verilerin bellekte saklı olduğu bellek alanlarının başlangıç adresleri atanır. Pointer, diğer değişkenler gibi, sayısal bir değişkendir. Bu sebeple kullanılmadan önde program içinde bildirilmelidir.
Referans Operatörü Pointerlar konusunda bilmemiz gereken 2 adet önemli operatör vardır. Bunlar; Referans Operatörü & De Referans ( Referanstan ayırma) Operatörü * Pointerlar tek başlarına değer alamazlar bunun için başka bir değişkeni referans almak zorundadırlar.
Referans (Adres) Operatörü Referans (Adres) operatörü değişkenin hafızada saklandığı yeri (adresini) gösterir foo = &myvar; myvar = 25; foo = &myvar; bar = myvar;
Pointer Tanımlamak Pointerı aşağıdaki gibi tanımlayabiliriz. <Değişken Türü> *<Değişken Adı> Eğer * işaretini değişkeni tanıtırken kullanırsak, o değişkeni pointer olarak tanımlarız. Eğer program içerisinde bir değişkenin önüne eklersek, kayıtlı adres üzerindeki değeri gösterir.
Referans Operatörü Örnek int *isaret; int okul_no=453; isaret=&okul_no; isaret isimli işaretçi okul_no isimli değişkeni referans olarak alıyor, böylece isaret = okul_no adresi diyebiliriz. Genel açıdan bakarsak isaret isimli işaretçi int tipindeki herhangi bir değişkenin adresini tutabilir. isaret değişkenine okul_no nun adresini atayabilmek için pointer şeklinde tanımlamamız gerekiyor. isaret=&okul_no; işleminde okul_no değişkeninin referansının atanması için * işaretini koymuyoruz.
Pointer Örneği int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği int değişkenlerini tanımladım int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği int tipinde pointer tanımladım int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği ilksayı değişkeninin adresini mypointer değişkenine atadım int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği mypointer değerini 10 olarak atadım int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği ikincisayi değişkeninin adresini mypointer değişkenine atadım int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği mypointer değerini 2 olarak değiştirdim int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n';
Pointer Örneği int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n'; cout lar nasıl çıktı verecek?
Pointer Örneği int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n'; 10 20
Pointer Örneği int ilksayi, ikincisayi; int * mypointer; mypointer = &ilksayi; *mypointer = 10; mypointer = &ikincisayi; *mypointer = 20; cout << "İlk Sayi = " << ilksayi << '\n'; cout << "İkinci Sayi = " << ikincisayi << '\n'; Peki neden? 10 20
Pointer Örneği 2 int ilksayi = 5, ikincisayi = 15; int * p1, * p2; p1 = &ilksayi; p2 = &ikincisayi; *p1 = 10; *p2 = *p1; p1 = p2; *p1 = 20; Programın çıktısı nedir? Tartışalım cout << "İlk sayi :: " << ilksayi << '\n'; cout << "İkinci Sayi :: " << ikincisayi << '\n';
Pointer ve Diziler Diziler uygun tipteki işaretçilere dönüştürülebilir. Statik değişkenler ve diziler için programın ilk çalışma anında bellekte yer ayrılır ve bu yer program bitine kadar tutulur. Pointerlar da ise bellek ayrımı derleme aşamasında değil çalışma sırasında olur. Bu şekilde kullanılan değişkenlere dinamik değişken denir.
Pointerlar ve Diziler Örnek int numbers[5]; numbers isimli 5 elemanlı bir dizi oluşturduk. int * p; p isimli pointer oluşturduk p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; numbers dizisi p pointerını birbirine eşitledik *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; ilk elemanı 10 yaptık p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; p++; p yi 1 arttırdık *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", "; ikinci elemanı 20 olarak atadık
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; numbers dizisinin 3. elemanının adresini aldık *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; 40 olarak atadık p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; Dizinin 3. elemanına eriştik *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";
Pointerlar ve Diziler Örnek int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", "; Dizinin 4. elemanını 50 olarak atadık
Pointer ile Dizi içinde dolaşmak int dizi[5]=11,22,33,44,55; int * p = dizi; for(int i =0; i<5; i++) cout<< dizi elemanı << dizi[i]<<endl; cout<< pointer ile <<*(p+i)<<endl; cout<< dizinin adresi <<&dizi[i]<<endl; cout<< pointer in adresi <<&p[i]<<endl;
Pointer ile Dizi içinde dolaşmak int dizi[5]=11,22,33,44,55; int * p = dizi; for(int i =0; i<5; i++) cout<< dizi elemanı << dizi[i]<<endl; cout<< pointer ile <<*(p+i)<<endl; cout<< dizinin adresi <<&dizi[i]<<endl; cout<< pointer in adresi <<&p[i]<<endl;
Dinamik diziler Pointerlar da ise bellek ayrımı derleme aşamasında değil çalışma sırasında olur. Bu şekilde kullanılan değişkenlere dinamik değişken denir. new ve delete komutları ile C++ da dinamik dizi oluşturabiliriz. new komutu ile dinamik dizi oluşturur. degisken_adi = new veritipi [eleman_sayısı]; delete komutu ile oluşturulan diziyi silebiliriz delete degisken_adi;
Dinamik Diziler Örnek int * p; p = new int [3]; p[0] =11; p[1] =22; p[2] =33; p[3] =44; cout <<p[3]<<endl; delete p;
İşaretçinin işaretçisi Şu ana dek incelediğimiz tüm işaretçiler bir değişkene yada bir sabite işaret ediyordu (adresini içeriyordu). Bir pointer ın bir başka pointer a işaret etmesi mümkündür. Bu durumdaki pointerların başında ** işleci getirilir.
char a; char * b; char ** c; a = 'z'; b = &a; c = &b; İşaretçinin işaretçisi
Fonksiyonda İşaretçiler Fonksiyonları tanımlarken parametreleri istediğimiz gibi tanımlayabiliriz. Bu parametreler işaretçi de olabilir. İki tip parametre kullanabiliriz Değer göndererek kullanılan fonksiyonlar (Call by value) Referans göndererek kullanılan fonksiyon (Call by reference)
Fonksiyonda işaretçiler 100 8
Kaynaklar!http://www.cplusplus.com/doc/tutorial/!www.py4e.com!C++ How to program (Deitel)!Ferhat Özok Bilgisayar Programlama I ders notları 40