C++'da İşaretçiden İşaretçiye

C Da Isaretciden Isaretciye



Bu makale C++'da işaretçiden işaretçiye kavramı hakkındadır. İşaretçinin işaretçisi, başka bir işaretçinin adresini işaret eder veya saklar ve işaretçilerin kendilerinin manipülasyonuna olanak tanır. Bu konsepti kullanarak, hafızadaki başka bir konumdan bir işaretçiyi kolaylıkla değiştirebiliriz. Çift işaretçiler, dinamik olarak ayrılmış bellekte veya çok boyutlu dizilerde bir dizinin öğelerini işlemek için faydalıdır. Bu işaretçiyi C++'da işaretçi çalışması ve kullanımına uygun örneklerle tartışacağız.

Senaryo 1: İşaretçiden İşaretçiye Bellek Temsili

Bu senaryoda, çift işaretçinin bildirilmesi, işaretçi adından önce ek bir yıldız işareti (*) bulunan işaretçi bildirimine benzer. C++'da çift işaretçinin bellek konumunu kolaylıkla temsil edebiliriz. İşaretçiye işaretçinin kod pasajı aşağıda verilmiştir:







#include
ad alanı std'sini kullanma;
int ana ( )
{
int rakam  = elli ;
int * ptrr;
ptrr = & hane;
int ** ptrr1;
ptrr1 = & ptrr;
cout << 'İşaretçi hafıza adresi: \N ' ;
cout << 'ptrr (işaretçi): ' << ptrr << ' \N ' ;
cout << '*ptrr1 (çift işaretçi): ' <<* ptrr1 << ' \N ' ;
cout << 'İşaretçideki değer depoları: \N ' ;
cout << '*ptrr = ' <<* ptrr << sonunda;
cout << '**ptrr1 (işaretçiden işaretçiye) = ' <<** ptrr1 << sonunda;
geri dönmek 0 ;
}


Ana fonksiyonda, hafıza adresinin bir işaretçide saklanması gereken bir değişkeni alıyoruz. Şimdi “digit” değişkenini başlatıyoruz. Daha sonra “digit” hafıza adresini saklayan “ptrr” pointerını deklare ediyoruz. Şimdi “*ptrr” işaretçisinin adresini saklayan adı “**ptrr1” olan çift işaretçiyi deklare ediyoruz. Kodun sonunda pointer ve double pointerın hafızasını ve değerini konsol ekranında gösteriyoruz. Bu kodun çıktısı aşağıda belirtilmiştir:




“ptrr” işaretçisinin hafıza adresi “0x6ffe04” olup “*ptrr1” işaretçisi aynı zamanda “ptrr” işaretçisinin hafıza adresini de saklar. İşaretçinin içinde saklanan değer “50”dir. Temel olarak çift işaretçinin adresi her zaman işaretçinin hafıza adresiyle aynıdır.



Senaryo 2: İşlev Parametresi Olarak İşaretçiden İşaretçiye

Bu senaryoda herhangi bir değişkende geçici bellek tahsisini gerçekleştirmek için herhangi bir fonksiyonda çift işaretçiyi parametre olarak nasıl geçireceğimizi öğreneceğiz. Çift işaretçili fonksiyon parametresinin kod parçacığı aşağıda belirtilmiştir:





#include
geçersiz getMemoryAddress ( int ** double_ptr ) {
hava durumu = 200 ;
* double_ptr = & sıcaklık;
}

int ana ( ) {
int * ptr_1;
int ** double_ptr;
double_ptr = & ptr_1;
getMemoryAddress ( double_ptr ) ;
std::cout << '**double_ptr'nin değeri: ' << ** double_ptr << std::endl;
geri dönmek 0 ;
}


Burada işaretçiden işaretçiye kavramının C++'da nasıl çalıştığını öğreneceğiz. Programda bir işaretçinin çift işaretçiyle çalışacak şekilde bildirildiğini unutmayın. Böylece “getMemoryAddress” fonksiyonunu oluşturuyoruz. Bu fonksiyonu, parametreyi ilettiğimizde çift işaretçinin hafıza adresini otomatik olarak alacak şekilde tasarlıyoruz.

Fonksiyonda “tempp” değişkenini ve “**double_ptr” çift işaretçisini alıyoruz. Belirtilen değişkenin “tempp” adresini, fonksiyonun argümanı olarak double pointer ve double pointer değerlerine aktarıyoruz. Program, ana fonksiyon kodunun sonucunu konsol ekranında görüntüler, böylece ana fonksiyondaki her şey çalıştırılabilir olur. Ana fonksiyonda “ptr_1” işaretçisini ve çift işaretçiyi “double_ptr” olarak alıyoruz. İşaretçinin adresini çift işaretçiye aktarıyoruz.



Şimdi override fonksiyonunda double pointer değişkenini geçiyoruz ve double pointerın sonucunu göstermek için pointerı “cout” çıktı akışı deyimindeki pointer değişkenine aktarıyoruz.

Derleyici geçersiz kılma fonksiyonuna ulaştığında bu fonksiyonun tanımlandığı derleyici denetleyicisi fonksiyonun içindeki kodu çalıştırır ve sonucu ana fonksiyona döndürür.

Bu kodun çıktısı aşağıdaki dosyaya eklenmiştir:


Sonuç: Çift işaretçinin değeri 200'dür.

Senaryo 3: 2D Diziyi İşaretçiden İşaretçiye Kullanma

Bu örnekte çift işaretçiye sahip 2 boyutlu bir diziyle ilgileneceğiz. Bir dizi alıyoruz ve işaretçiye bir dizinin adresini iletiyoruz. Bu senaryonun tam kodu şu şekilde verilmiştir:

int ana ( ) {
const int satırlar = 3 ;
const int sütunlar = 2 ;
int ** matris = yeni int * [ satırlar ] ;
için ( int ben = 0 ; Ben < satırlar; ++ben ) {
matris [ Ben ] = yeni int [ sütunlar ] ;
}
için ( int ben = 0 ; Ben < satırlar; ++ben ) {
için ( int j = 0 ; J < sütunlar; ++j ) {
matris [ Ben ] [ J ] = ben * sütunlar + j;
}
}
için ( int ben = 0 ; Ben < satırlar; ++ben ) {
için ( int j = 0 ; J < sütunlar; ++j ) {
cout << matris [ Ben ] [ J ] << ' ' ;
}
cout << sonunda;
}
için ( int ben = 0 ; Ben < satırlar; ++ben ) {
silmek [ ] matris [ Ben ] ;
}
silmek [ ] matris;
geri dönmek 0 ;
}


Hepimizin bildiği gibi, 2 boyutlu bir dizide çok sayıda satırımız ve çok sayıda sütunumuz var. Ana fonksiyonda “const int” içeren satır ve sütunları başlatıyoruz. Daha sonra her satır boyunca satırlara hafıza alanı, sütunlara da hafıza alanı ayırıyoruz. Matris çift işaretçisinde işaretçi olarak satır sayısı değerini “**matrix” olarak aktarıyoruz. Bu çift işaretçide satır sayısının döngüsü yürütülür veya doğrudur. Daha sonra koşul yanlış olana kadar başka bir iç döngü yürütülür.

Bellek tahsisinden sonra diziye tekrar bir değer atarız: 2B dizinin satırları için bir dış döngü ve sütunları için bir iç döngü. İç döngüde satır ve sütunların değeri çift işaretçiye atanır ve gerekli aritmetik işlemi gerçekleştirir. Bellekte ayrılan satır ve sütun sayısı gibi 2 boyutlu bir dizinin değerlerini görüntüleriz. Satır ve sütun sayısı her zaman satır ve sütun değerlerini saklayan çift işaretçiyi gösterir. Sonunda belleği temizliyoruz ve bu diziyi C++'daki bellekten kaldırıyoruz.

Çift işaretçili 2 boyutlu dizinin çıktısı aşağıya eklenmiştir:

Senaryo 4: İşaretçiyi Kullanarak İşaretçiyi İşaretçiye Değiştirme

Burada, C++'da çift işaretçiyi bildirerek işaretçilerin nasıl değiştirileceğini öğreneceğiz. Bu senaryonun kod parçacığı aşağıdaki ekte yer almaktadır:

#include
geçersiz takas ( int ** ptrr_1, sen ** ptrr_2 ) {
int * temp_var = * ptrr_1;
* ptrr_1 = * ptrr_2;
* ptrr_2 = temp_var;
}
int ana ( ) {
int x = on beş , y = 25 ;
int * ptrrA = & X, * ptrrB = & Ve;
std::cout << 'Değiştirmeden önce: *ptrrA = ' << * ptrrA << ', *ptrrB = ' << * ptrrB << std::endl;
takas ( & ptrrA, & ptrrB ) ;
std::cout << 'Değiştirmeden sonra: *ptrrA   = ' << * ptrrA << ', *ptrrB  is= ' << * ptrrB << std::endl;
geri dönmek 0 ;
}


İlk olarak, her iki işaretçiyi de işlev argümanı olarak ileterek takas işlevini oluştururuz. Swap fonksiyonunda “temp” işaretçisini alıp bir süre “temp” içerisine “pointer1” değerini aktarıyoruz. Daha sonra “pointer2” değerini “pointer1”e aktarıyoruz. Sonunda “temp” işaretçisinin değerini “pointer2”ye aktarıyoruz.

Ana fonksiyonda “swap” fonksiyonunda ilettiğimiz veya geçersiz kıldığımız iki işaretçiye ihtiyacımız var. Değişkenlerin adreslerini verilen işaretçilere aktarıyoruz. Ardından işaretçinin değeri, işaretçiyi değiştirmeden önceki ve sonraki değeri görüntülenir.

Bu kodun çıktısı aşağıdaki dosyaya eklenmiştir:


Görebildiğimiz gibi, işaretçinin değerleri C++'da çift işaretçi kullanılarak başarılı bir şekilde değiştirilmektedir.

Çözüm

C++'da işaretçinin işaretçisinin her zaman herhangi bir işaretçinin bellek adresini sakladığı sonucuna vardık. Herhangi bir işaretçinin hafıza konumunu herhangi bir anda geçici olarak kullanmak için çift işaretçiyi kullanabiliriz. Bu, bellek adresini dolaylı olarak manipüle etmenin ve verilere yaklaşmanın çok etkili bir yoludur.