Çoğu kişide kafa karışıklılığına yol açan pointerlar anlatım

mertkancelik

Uzman üye
27 Nis 2014
1,070
3
Bursa
Pointer Nedir ve Neden Kullanılır ?

Pointerlar bir değişkenin adresini tutmaya yarayan değişkenlerdir. Bu sayede yazılımcılar bazı noktalarda değiştiremediği bir değişkenin değerini pointer ile ulaşıp manipüle edebilir.

Buna bir örnek vermek gerekirse :

Basit bir program yazalım fonksiyon bizden bir integer değer istesin biz bu sayıyı fonksiyon içerisinde arttırarak ekrana bastıralım ve aynı zamanda main içerisinde bastıralım.

Kod:
#include <iostream>

using namespace std;

vo id sayiArttir(int sayi) {

    sayi++;
    cout << "Sayının Yeni Değeri : " << sayi << endl;

}

int main() {

    int sayimiz = 25;

    cout << "Fonksiyon Öncesi Sayımız : " << sayimiz << endl;
    sayiArttir(sayimiz);
    cout << "Fonksiyon Sonrası Sayımız : " << sayimiz << endl;

    return 0;
}

Bir çoğunuz çıktıyı

Fonksiyon Öncesi Sayımız : 25
Sayının Değeri : 26
Fonksiyon Sonrası Sayımız : 26


Asıl Çıktımız

Fonksiyon Öncesi Sayımız : 25
Sayının Değeri : 26
Fonksiyon Sonrası Sayımız : 25


Olarak düşünecektir fakat düşündüğünüz şey yanlış. Nedenine gelirsek biz fonksiyon içerisine bir değer gönderiyoruz ve arttırıyoruz buraya kadar her şey güzel fakat cpp bu sayının fonksiyondan sonrası çağırıldığı zaman değerini arttırmayacaktır çünkü fonksiyon struct gibi yapılar sadece kendi içerilerinde işlem yapar. Peki bu sorunu nasıl düzelteceğiz ? gayet kolay pointer kullanarak :hosnut yeni kodumuz şu şekilde olacak :

Kod:
#include <iostream>

using namespace std;

vo id sayiArttir(int *sayi) {

    (*sayi)++;
    cout << "Sayının Yeni Değeri : " << *sayi << endl;

}

int main() {

    int sayimiz = 25;

    cout << "Fonksiyon Öncesi Sayımız : " << sayimiz << endl;
    sayiArttir(&sayimiz);
    cout << "Fonksiyon Sonrası Sayımız : " << sayimiz << endl;

    return 0;
}

Bu kodun ne yaptığına gelirsek öncelikle main içerisinde bir sayı tanımladık Fonksiyon Öncesi Sayımızı bastırdık ve fonksiyonu çağırdık gördüğünüz üzere fonksiyonu çağırırken sayiArttir(&sayimiz); şeklinde değer gönderdik bunun ne anlama geldiğini birazdan anlatacağım ve daha sonra Fonksiyon sonrası sayımızı bastırdık. Fonksiyonumuzun içerisine gelirsek gördüğünüz üzere bizden artık sadece integer bir veri değil aynı zamanda göndereceğimiz değişkenin adresini istiyor çünkü parametre içerisinde int *sayi olarak tanımladık bunların anlamlarını birazdan anlatacağım sadece şuanlık basit bir pointerın nasıl çalıştığını anlatmak istiyorum. Daha sonra ilk çalışacak kısım (*sayi)++; olacak ve daha sonra Sayının Yeni Değeri : şeklinde ekrana bastıracak. Bu kodun çıktısına gelirsek.

Fonksiyon Öncesi Sayımız : 25
Sayının Değeri : 26
Fonksiyon Sonrası Sayımız : 26


Olarak göreceğiz işte pointerlar ile aslında biz değişkenlerin adresine erişip adresler üzerinden işlemler yapıyoruz.

Pointerlar Nasıl Tanımlanır Ve Pointer İşaretleri :

Biz bir pointer tanımlarken aslında normal bir değişken tanımlar gibi tanımlıyoruz fakat değişken tipinden sonra bir adet * ekliyoruz bu yıldız bizim değişkenimizin bir pointer olduğunu gösteriyor.

Örnek :

int *pointer; bu şekilde tanımlıyoruz. Fakat daha bitmedi :mahcup: dediğim gibi pointerlar sadece bir değişkenin adresini tutar yani gidip int *pointer = 25; gibi bir ifade yazamayız. Ee peki nerden öğreneceğiz bir değişkenin adresini ? C ve C++ dilleri bu konuda bize kolaylık sağlıyor sadece tek bir işaretle bir değişkenin adresini öğrenebiliyoruz. & işareti ile. Peki pointer'a bunu nasıl göstereceğiz onu da hemen göstereyim.

Örnek :

int sayi = 25;
int *pointer = &sayi;


Evet bu kadar basit bunun ne yaptığına gelirsek aslında bizim pointer değişkenimiz 25 sayısını tutmuyor sayi değişkeninin adresini tutuyor peki bu adres adres diyoruz bu adres nedir diyenler için adres bir değişkenin RAM üzerinde hangi kısımda olduğunu gösteren bir değerdir. Bu değer 1234 veya 4122 gibi bir değer değil aksine bir çoğunuz daha önceden gördüğü fakat hiç umursamadığı bir değer örnek : 0x7ffeebfa4ac8 bu gibi hexadecimal değerler. Hmm burasını anladık fakat daha bu pointerlar ile ne yapabiliriz diyen arkadaşlar için şöyle bir örnek bırakmak istiyorum :

Kod:
#include <iostream>

using namespace std;

int main() {

    int sayiDegeri = 1000;
    int *ptr = &sayiDegeri;

    cout << "sayiDegeri Değişkeni : " << sayiDegeri << endl;
    cout << "ptr'nin tuttuğu adres : " << ptr << endl;
    cout << "sayiDegerinin Adresi : " << &sayiDegeri << endl;
    cout << "ptr değişkeninin tuttuğu değer : " << *ptr << endl;
    cout << "ptr değişkenimizin adresi : " << &ptr << endl;

    return 0;
}

Bu kodu çalıştırdığımız da alacağımız çıktı şu şekilde olacaktır :

sayiDegeri Değişkeni : 1000
ptr'nin tuttuğu adres : 0x7ffee3e2aaa8
sayiDegerinin Adresi : 0x7ffee3e2aaa8
ptr değişkeninin tuttuğu değer : 1000
ptr değişkenimizin adresi : 0x7ffee3e2aaa0

Gördüğünüz gibi başlangıçta cout << "sayiDegeri Değişkeni : " << sayiDegeri << endl; kodunu yazdık ve ekrana 1000 değeri çıktı burayı herkes anlamıştır şimdi işin diğer kısmına gelelim. Dediğim gibi pointerlar sadece bir değişkenin adresini tutuyordu ve biz bu kod ile cout << "ptr'nin tuttuğu adres : " << ptr << endl; aslında ptr adlı pointerın sayiDegeri adlı değişkenin adresini tuttuğunu görüyoruz gerçekten pointerları kullanmak bu kadar basit arkadaşlar görüldüğü üzere 0x7ffee3e2aaa8 çıktısını aldık bu ptr değişkeninin değil sayiDegeri değişkeninin adresidir. Bir diğer kodumuza geçelim. cout << "sayiDegerinin Adresi : " << &sayiDegeri << endl; Hmm ee bu ptr ile aynı değeri verdi değil mi neden böyle oldu peki ? çünkü biz bir değişkenin adresini görmek istiyorsak & ifadesini kullanıyoruz birazdan diğer kodlarıda anlatacağım ve aklınızda soru işareti kalmayacağını umuyorum. ve daha sonra cout << "ptr değişkeninin tuttuğu değer : " << *ptr << endl; kodunu çalıştırdık çıktımız ptr değişkeninin tuttuğu değer : 1000 oldu ee ama ben pointer tanımladım ve çıktımız sayiDegerinin değeri olarak çıktı neden ? diyecekler için biz bir pointer tanımlarken int *ptr; şeklinde tanımlıyorduk değil mi ve bir değişkenin adresini görmek istersek cout << "değişkenin adresi" << ptr; yazmamız gerekiyordu pointerlar bir değişkenin adresini tuttuğu için biz o adreste ki değişkenin değerinede erişebiliyoruz ve bu değeri ekrana bastırmak için cout << "değer : " << *ptr; yazıyoruz. Yani demem o ki bir pointerı kullanırken ve ekrana bastırırken ptr sadece adresi *ptr ile bastırırken değişkenin tuttuğu değeri görebiliyoruz. Aslında iş bu kadar basit bu operatörleri öğrendiğiniz zaman gerçekten iş bitiyor. Operatörlerden ve pointer tanımlarken neden & işareti kullandığımızdan bahsedip konuyu bitirelim.

Biz bir pointer tanımlarken int *ptr = &sayi; yazıyorduk bu & işareti sayi adlı değişkenin adresini aslında ptr adlı pointer değişkenine atıyor üstte ki yazdığımız bu kodda da cout << "sayiDegerinin Adresi : " << &sayiDegeri << endl; sayiDegerinin Adresi : 0x7ffee3e2aaa8 çıktısını almışken yani neymiş bir pointer tanımlarken en önemli nokta değer tipinden sonra * eklemek ve bir değişkene eşitlerken & kullanmakmış. Arkadaşlar pointerlar gerçekten çok önemli bir konu yanlış bilmiyorsam sadece c ve c++'ta pointerlar var ve bu dillere bu kadar güç veren pointerlar ileride neredeyse yazacağınız bir çok uygulamada karşınıza pointerlar çıkacak veya kullanmanız gerekecek eğer bu konuyu bilmiyorsanız ileride çok zorluk çekeceksiniz özellikle oyun hilesi yapmak isteyen arkadaşlar bu konuyu sular seller gibi öğrenmesi gerekiyor :hosnut eğer anlamadığınız yerler var ise yorum olarak şurayı anlamadım demeniz yeterli biraz daha somut örnekler üzerinden anlatmaya çalışırım.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.