C++ Örneklerle İşaretçiler

İşaretçiler nedir?

In C++, bir işaretçi, başka bir değişkenin adresini tutan bir değişkeni ifade eder. Normal değişkenler gibi işaretçilerin de bir veri türü vardır. Örneğin, integer tipindeki bir işaretçi, integer tipindeki bir değişkenin adresini tutabilir. Karakter tipindeki bir işaretçi, karakter tipindeki bir değişkenin adresini tutabilir.

Bir işaretçiyi hafıza adresinin sembolik bir temsili olarak görmelisiniz. İşaretçiler sayesinde programlar referansa göre çağrıyı simüle edebilir. Ayrıca dinamik veri yapılarını oluşturabilir ve işleyebilirler. İçinde C++, bir işaretçi değişkeni, başka bir değişken tarafından işaret edilen bir bellekteki belirli bir adresi işaret eden bir değişkeni ifade eder.

Adresler C++

Anlamak C++ işaretçiler için bilgisayarların verileri nasıl sakladığını anlamalısınız.

Programınızda bir değişken oluşturduğunuzda C++ programa bilgisayar belleğinde bir miktar yer tahsis edilir. Bu değişkenin değeri atanan konumda saklanır.

Verilerin bilgisayar belleğinde saklandığı yeri bilmek, C++ sağlar & (referans) operatörü. Operatör değişkenin bulunduğu adresi döndürür.

Örneğin, x bir değişkense, &x değişkenin adresini döndürür.

İşaretçi Bildirimi Sözdizimi

deklarasyonu C++ Aşağıdaki sözdizimini alır:

datatype *variable_name; 
  • Veri türü, geçerli olması gereken işaretçinin temel türüdür. C++ veri türü
  • Değişken_adı işaretçi değişkeninin adı olmalıdır.
  • Yukarıda işaretçi bildirimi için kullanılan yıldız işareti, çarpma işlemini gerçekleştirmek için kullanılan yıldız işaretine benzer. Değişkeni işaretçi olarak işaretleyen yıldız işaretidir.

İşte geçerli işaretçi bildirimlerinin bir örneği C++:

int    *x;    // a pointer to integer
double *x;    // a pointer to double
float  *x;    // a pointer to float
char   *ch     // a pointer to a character

Referans operatörü (&) ve Referans operatörü (*)

Referans operatörü (&), değişkenin adresini döndürür.

Referans operatörü (*), hafıza adresinde saklanan değeri elde etmemize yardımcı olur.

Örneğin:

Eğer num adı verilen, 0x234 adresinde saklanan ve 28 değerini saklayan bir değişkenimiz varsa.

Referans operatörü (&) 0x234 değerini döndürecektir.

Başvuru operatörü (*) 5 değerini döndürecektir.

Örnek 1:

#include <iostream>
using namespace std;
int main() {
	int  x = 27;  
	int  *ip;        
	ip = &x;       
	cout << "Value of x is : ";
	cout << x << endl;
	cout << "Value of ip is : ";
	cout << ip<< endl;
	cout << "Value of *ip is : ";
	cout << *ip << endl;
	return 0;
}

Çıktı:

Referans operatörü (&) ve Referans operatörü (*)

Bu nasıl çalışır:

Referans operatörü (&) ve Referans operatörü (*)

İşte kodun ekran görüntüsü:

Referans operatörü (&) ve Referans operatörü (*)

Kod Açıklaması:

  1. iostream başlık dosyasını içe aktarın. Bu bize başlık dosyasında tanımlanan fonksiyonları hata almadan kullanmamızı sağlayacaktır.
  2. Sınıflarını çağırmadan kullanmak için std ad alanını ekleyin.
  3. main() fonksiyonunu çağırın. Program mantığı bu fonksiyonun gövdesine eklenmelidir. { işlevin gövdesinin başlangıcını işaret eder.
  4. Bir tamsayı değişkeni x bildirin ve ona 27 değerini atayın.
  5. Bir işaretçi değişkeni *ip bildirin.
  6. x değişkeninin adresini işaretçi değişkeninde saklayın.
  7. Konsola bir miktar metin yazdırın.
  8. X değişkeninin değerini ekrana yazdırınız.
  9. Konsola bir miktar metin yazdırın.
  10. x değişkeninin adresini yazdırın. Adresin değeri ip değişkeninde saklandı.
  11. Konsola bir miktar metin yazdırın.
  12. İşaretçinin adresinde saklanan değeri yazdır.
  13. Program başarılı bir şekilde yürütüldüğünde değeri döndürmelidir.
  14. Main() işlevinin gövdesinin sonu.

İşaretçiler ve Diziler

Diziler ve işaretçiler ilgili bir konsepte göre çalışır. İşaretçilerin bulunduğu dizilerle çalışırken dikkat edilmesi gereken farklı şeyler vardır. Dizi adının kendisi dizinin temel adresini belirtir. Bu, bir dizinin adresini bir işaretçiye atamak için ve işareti (&) kullanmamanız gerektiği anlamına gelir.

Örneğin:

p = arr;

arr dizilerin adresini temsil ettiğinden yukarıdakiler doğrudur. İşte başka bir örnek:

p = &arr;

Yukarıdakiler yanlıştır.

Bir diziyi dolaylı olarak bir işaretçiye dönüştürebiliriz. Örneğin:

int arr [20];
int * ip;

Aşağıda geçerli bir işlem verilmiştir:

ip = arr;

Yukarıdaki bildirimden sonra ip ve arr eşdeğer olacak ve özellikleri paylaşacaklar. Ancak ip'e farklı bir adres atanabilir ama arr'a hiçbir şey atayamayız.

Örnek 2:

Bu örnek, işaretçiler kullanılarak bir dizide nasıl gezinileceğini gösterir:

#include <iostream>
using namespace std;
int main() {
	int *ip;
	int arr[] = { 10, 34, 13, 76, 5, 46 };
	ip = arr;
	for (int x = 0; x < 6; x++) {
		cout << *ip << endl;
		ip++;
	}
	return 0;
}

Çıktı:

İşaretçiler ve Diziler

İşte kodun ekran görüntüsü:

İşaretçiler ve Diziler

Kod Açıklaması:

  1. Bir tamsayı işaretçi değişkeni ip bildirin.
  2. arr adında bir dizi bildirin ve içine 6 tamsayı depolayın.
  3. arr'ı IP'ye atayın. IP ve arr eşdeğer hale gelecektir.
  4. Bir for döngüsü oluşturun. Döngü değişkeni x, dizi öğelerini 0'dan 5'e kadar yinelemek için oluşturuldu.
  5. İşaretçi IP'sinin adresinde saklanan değerleri yazdırın. Yineleme başına bir değer döndürülecek ve toplam 6 tekrar yapılacaktır. Sonu bir C++ bitiş çizgisi anlamına gelen anahtar kelime. Bu eylem, her değer yazdırıldıktan sonra imleci bir sonraki satıra taşımanıza olanak tanır. Her değer ayrı bir satırda yazdırılacaktır.
  6. Her yinelemeden sonra işaretçiyi bir sonraki int konumuna taşımak için.
  7. For döngüsünün sonu.
  8. Program başarılı bir şekilde yürütüldüğünde bir şey döndürmelidir.
  9. main() işlev gövdesinin sonu.

Boş işaretçisi

Atanacak tam bir adres yoksa işaretçi değişkenine bir NULL atanabilir. Bu beyan sırasında yapılmalıdır. Böyle bir işaretçi, boş işaretçi olarak bilinir. Değeri sıfırdır ve iostream gibi birçok standart kütüphanede tanımlanmıştır.

Örnek 3:

#include <iostream>
using namespace std;
int main() {
	int  *ip = NULL;
	cout << "Value of ip is: " << ip;
	return 0;
}

Çıktı:

Boş işaretçisi

İşte kodun ekran görüntüsü:

Boş işaretçisi

Kod Açıklaması:

  1. Bir işaretçi değişkeni ip bildirin ve ona NULL değeri atayın.
  2. Konsoldaki bazı metinlerin yanında ip işaretçi değişkeninin değerini yazdırın.
  3. Program başarılı bir şekilde tamamlandıktan sonra değeri döndürmelidir.
  4. Main() işlevinin gövdesinin sonu.

Değişkenlerin İşaretçileri

İle C++, verileri doğrudan bilgisayarın belleğinden değiştirebilirsiniz.

Bellek alanı isteğe göre atanabilir veya yeniden atanabilir. Bu, İşaretçi değişkenleri sayesinde mümkün olur.

İşaretçi değişkenleri, bilgisayarın belleğinde başka bir değişken tarafından işaret edilen belirli bir adresi işaret eder.

Aşağıdaki gibi beyan edilebilir:

int *p;

altın,

int* p;

Örneğinizde p işaretçi değişkenini tanımladık.

Bir hafıza adresi tutacaktır.

Yıldız işareti, işaretçi anlamına gelen referans kaldırma operatörüdür.

p işaretçisi bellek adresindeki bir tamsayı değerini işaret etmektedir.

Örnek 4:

#include <iostream>

using namespace std;
int main() {
	int *p, x = 30;
	p = &x;
	cout << "Value of x is: " << *p;
	return 0;
}

Çıktı:

Değişkenlerin İşaretçileri

İşte kodun ekran görüntüsü:

Değişkenlerin İşaretçileri

Kod Açıklaması:

  1. Bir işaretçi değişkeni p ve değeri 30 olan bir x değişkeni bildirin.
  2. X değişkeninin adresini p'ye atayın.
  3. Konsoldaki bir metnin yanında p işaretçi değişkeninin değerini yazdırın.
  4. Program başarılı bir şekilde tamamlandıktan sonra değeri döndürmelidir.
  5. Main() işlevinin gövdesinin sonu.

İşaretçilerin Uygulanması

İçindeki işlevler C++ yalnızca bir değer döndürebilir. Ayrıca, bir fonksiyonda bildirilen tüm değişkenler, fonksiyon çağrı yığınına tahsis edilir. Fonksiyon geri döndüğü anda tüm yığın değişkenleri yok edilir.

Fonksiyona argümanlar değere göre geçirilir ve değişkenlerde yapılan herhangi bir değişiklik geçirilen gerçek değişkenlerin değerini değiştirmez. Aşağıdaki örnek bu kavramı açıklamaya yardımcı olur:-

Örnek 5:

#include <iostream>

using namespace std;
void test(int*, int*);
int main() {
	int a = 5, b = 5;
	cout << "Before changing:" << endl;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	test(&a, &b);

	cout << "\nAfter changing" << endl;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	return 0;
}

void test(int* n1, int* n2) {
	*n1 = 10;
	*n2 = 11;
}

Çıktı:

İşaretçilerin Uygulanması

İşte kodun ekran görüntüsü:

İşaretçilerin Uygulanması

Kod Açıklaması:

  1. İki tam sayı parametresi alacak test adlı bir fonksiyonun prototipini oluşturun.
  2. main() fonksiyonunu çağırın. Program mantığını kendi bünyesine ekleyeceğiz.
  3. Her biri 5 değerine sahip iki a ve b tamsayı değişkenini tanımlayın.
  4. Konsola bir miktar metin yazdırın. Endl (bitiş satırı), sonraki satırda yazdırmaya başlamak için imleci hareket ettirecektir.
  5. a değişkeninin değerini diğer metinle birlikte konsola yazdırın. Endl (bitiş satırı), sonraki satırda yazdırmaya başlamak için imleci hareket ettirecektir.
  6. b değişkeninin değerini diğer metinle birlikte konsola yazdırın. Endl (bitiş satırı), sonraki satırda yazdırmaya başlamak için imleci hareket ettirecektir.
  7. A ve b değişkenlerinin adreslerini parametre olarak alan test() adında bir işlev oluşturun.
  8. Konsola bir miktar metin yazdırın. \n, metin yazdırılmadan önce yeni bir boş satır oluşturacaktır. Endl (bitiş satırı), metin yazdırıldıktan sonra bir sonraki satırda yazdırmaya başlamak için imleci hareket ettirir.
  9. a değişkeninin değerini diğer metinle birlikte konsola yazdırın. Endl (bitiş satırı), sonraki satırda yazdırmaya başlamak için imleci hareket ettirecektir.
  10. b değişkeninin değerini diğer metinle birlikte konsola yazdırın. Endl (bitiş satırı), sonraki satırda yazdırmaya başlamak için imleci hareket ettirecektir.
  11. Program başarılı bir şekilde tamamlandıktan sonra değeri döndürmelidir.
  12. Main() işlevinin gövdesinin sonu.
  13. Fonksiyon testinin tanımlanması(). Fonksiyon iki tamsayı işaretçi değişkeni *n1 ve *n2 almalıdır.
  14. *n1 işaretçi değişkenine 10 değeri atanıyor.
  15. *n2 işaretçi değişkenine 11 değeri atanıyor.
  16. Fonksiyon testinin () gövdesinin sonu.

Her ne kadar fonksiyon testi içerisinde a ve b değişkenlerine yeni değerler atansa da, fonksiyon çağrısı tamamlandığında aynı değer dış fonksiyon main'e yansımamaktadır.

İşaretçileri işlev argümanları olarak kullanmak, değişkenin gerçek adresinin işleve aktarılmasına yardımcı olur ve değişken üzerinde gerçekleştirilen tüm değişiklikler dış işleve yansıtılır.

Yukarıdaki durumda, 'test' fonksiyonu 'a' ve 'b' değişkenlerinin adresine sahiptir. Bu iki değişkene 'test' fonksiyonundan doğrudan erişilebilir ve dolayısıyla bu değişkenlerde yapılan herhangi bir değişiklik 'main' çağıran fonksiyonuna yansıtılır.

İşaretçileri kullanmanın avantajları

Burada İşaretçileri kullanmanın artıları/yararları verilmiştir

  • İşaretçiler diğerlerinin adresini saklayan değişkenlerdir. içindeki değişkenler C++.
  • Birden fazla değişken işaretçiler kullanılarak işlev tarafından değiştirilebilir ve döndürülebilir.
  • Bellek, işaretçiler kullanılarak dinamik olarak tahsis edilebilir ve tahsisi kaldırılabilir.
  • İşaretçiler programın karmaşıklığını basitleştirmeye yardımcı olur.
  • Bir programın yürütme hızı işaretçilerin kullanılmasıyla artar.

ÖZET

  • Bir işaretçi, başka bir değişkenin değişken tutan adresini ifade eder.
  • Her işaretçinin geçerli bir veri türü vardır.
  • İşaretçi, bir bellek adresinin sembolik bir temsilidir.
  • İşaretçiler, programların referansa göre çağrı benzetimini yapmasına ve dinamik veri yapıları oluşturup değiştirmesine olanak tanır.
  • Diziler ve işaretçiler ilgili bir kavramı kullanır.
  • Dizi adı dizinin tabanını belirtir.
  • Bir dizinin adresini bir işaretçiye atamak istiyorsanız ve işareti (&) kullanmayın.
  • Bir işaretçi değişkenine atanacak belirli bir adres yoksa, ona bir NULL atayın.