folder Tahribat.com Forumları
linefolder C - C++
linefolder C++ Da Pointerlar.



C++ Da Pointerlar.

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    sniperscope
    sniperscope's avatar
    Banlanmış Üye
    Kayıt Tarihi: 14/Mart/2009
    Erkek

    Yaklasik bir haftadir lynda.com un c++ dersleri ile beraber Deitel in C++ How to program isimli kitabi ile c++ ogreniyoru(du)m. dum diye ekledim cunku ilk baslarda gayet iyi giderken pointerlar dan oteye gidemiyorum.

    Simdi

    int i = 5;

    int j;

    int *pointer;

    j = i; // bu sekilde j ye 5 degerini atiyoruz

    eeee

    pointer = i; // bunada 5 degerini atadik.

    o zaman bu pointer zimbirtisina ne gerek var?

     

    video da soyle birsey var.

    int x = 1;

    int y = x;

     

    int *ip;

    ip = &x;

    int y = *ip;

     

    Yukaridaki daha kolay degilmi? Ne diye sol elimizle sag kulagimizi gostermeye calisiyoruz burada?


    "Yer yuzunde hic bir pislik yoktur ki; altindan bir yahudi cikmasin" Adolf Hitler... "Turkiye de hicbir pislik yokturki altindan cemaat cikmasin" SniperScope "Nerede yavşak, hırsız varsa hepsi Allahçı" Fazil Say
  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Gizem
    sLeymN
    sLeymN's avatar
    Kayıt Tarihi: 31/Mart/2008
    Erkek

    Hocam pointer denilen şey adres tutucudur. Yani değişkenin ram üzerindeki adresini üzerine alır.  

    Pointer kullanmak kolay değildir, takibi zordur vs vs..  Ama belleğe direkt erişim sağladığın için çok fazla performans artışı sağlar. Ayrıca adrese müdahale etme gereksinimi duyulan uygulamalar vardır. Oyundaki hileleri vsleri düşünebilirsin. 

     edit. anlam kargaşası

    sLeymN tarafından 18/Eki/12 17:27 tarihinde düzenlenmiştir

    Cehennemin dibine kadar yolum var daha.. || Nasılsa her yalnız kendine sürgündür Asmera unutma.
  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    sniperscope
    sniperscope's avatar
    Banlanmış Üye
    Kayıt Tarihi: 14/Mart/2009
    Erkek

    tamam hafiz,

    int x = 5; tanimida hafizada yer tutuyor.

    Sanirim program calisirken int x in bellekteki yeri ha bire degisip durmuyor. Yani bellekte x icin bir alan olusturuluyor ve onun uzerinden devam edip gidiyor.

    Yani ne diye int y = x; duruken ne diye x in bellekteki adresini cagiralim.

    int *p;

    *p = &x;

    cout << *p; ile cout << x ayni degeri verecek.

     


    "Yer yuzunde hic bir pislik yoktur ki; altindan bir yahudi cikmasin" Adolf Hitler... "Turkiye de hicbir pislik yokturki altindan cemaat cikmasin" SniperScope "Nerede yavşak, hırsız varsa hepsi Allahçı" Fazil Say
  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    kknd
    kknd's avatar
    Kayıt Tarihi: 01/Şubat/2010
    Erkek

    suraya goz at..

    http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and-what-can-be-done-to-overcome

    The advantage of pointers in c are
    1.Dynamic memory allocation is possible with pointers.
    2.passing arrays and structures to functions.
    3.passing addresses to functions.
    4.creating data structures such as trees,linked lists etc.

    kknd tarafından 18/Eki/12 20:02 tarihinde düzenlenmiştir
  5. KısayolKısayol reportŞikayet pmÖzel Mesaj
    DrKill
    DrKill's avatar
    Kayıt Tarihi: 10/Mart/2004
    Erkek

    Hocam şimdi otursam saatlerce açıklarım sana faydalarını. Ama sana şöyle söyleyeyim ki program içindeki esnetilebilirliği çok şekilde arttırabiliyor pointer denen kavram. Küçük bir iş için tüm veri değil sadece 1 byte lık adres kopyalama işlemiyle yapabiliyorsun. Yani bellekte 1 GB veri de işlem yapmak için 4 byte lık bir veri kullanman yeterli oluyor. Ayrıca verdiğin örnekte int *pointer; int i; diyip pointer = i; yapamazsın. Derleyici hata verir. Çok deneme ve alıştırma yapman lazım sonra zaten mantığını kavrarsın.


    Bu imzayı her gördüğünüzde 4gb kotanızın 0,00000358559191226959228515625 azalmaktadır. Bilerek ve istenerek bu imza yapılmıştır. Amaç kotanızı sömürmektir
  6. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Tugberk
    Tugberk's avatar
    Kayıt Tarihi: 04/Ekim/2009
    Erkek

    Sorun verilen örnekte, * operatörünün kullanımı gösterilmek istenmiş ama yoksa öyle bir amaç için pointer kullanılmaz tabi. C++ da pointer kullanımı tavsiye edilmez ve zorunlu kalmadıkça kullanılmaz ama, hem C programcıları için, hem de senin (yinede) anlaman açısından genele uzuuunca birşeyler yazdım :) tabi DrKill in dediği gibi tüm kullanıldığı yerleri ve faydalarını anlatsak sayfalar sürer, ama mantığını anlatmaya çalıştım.

    En önemli kullanım alanı fonksiyonlara parametre olarak nesneyi değil adresini yollamaktır. Mesela bir A nesnesini yarattın, bu A nesnesini fonksiyona direkt yollarsan, A nesnesinin birebir kopyası bellekte yaratılır B nesnesi olarak, fonksiyon bu B nesnesini görür ve üzerinde işlem yapar. 

    Aşağıdaki örnekte fonksiyonun gördüğü nesne kendisine parametre olarak gelen B, fonksiyona yollanan nesne ise A, bunlar aynı nesneler değil birbirinin kopyası.

    void Fonksiyon(NESNE B){...}

    Fonksiyon(A);

    Birincisi temel türler dışında hiç bir nesne fonksiyona direkt geçilmemelidir, çünkü gereksiz bellek kopyalaması yapılmaktadır. A nesnesi 10 mb olsaydı, fonksiyon her çağırıldığında 10 mb data kopyalanması gerekecekti.

    İkincisi, B nesnesi tamamen farklı bir nesne olduğu için (içerik olarak A ile aynı ama farklı bir adreste farklı bir nesne) , B üzerinde yapılan değişiklikler, A yı etkilemez. Dahası, fonksiyon bittiğinde B nesnesi kullanılmaz hale gelir (ömrü biter) A ilk haliyle aynı kalır. 

    Diğer şekilde düşünelim, A nesnesini direkt olarak fonksiyona geçmedin ve adresini verdin fonksiyona. Bu durumda, yine bir P nesnesi, fonksiyon içinde yaratılır, ancak bu sefer P sadece 4 bayt (32 bit sistemler için), ve içinde A nesnesinin adresi olan bir pointer.

    void Fonksiyon(NESNE *P){...}

    Fonksiyon(&A);

    Görüldüğü gibi her hangi bir bellek kopyalaması olmadığı gibi, P nesnesi üzerinden A nesnesine her an erişip bu nesneyi okuyup yazabilirsin. İşte * operatörü genelde bu durumlarda işe yarıyor. Normalde direkt eriştiğin bir nesneye *nesne şeklinde, yapi.eleman şeklinde eriştiğin nesneye yapi->eleman şeklinde erişiyorsun. Tabi bu durumda yaptığın her işlem orijinal nesneyi(A) etkiliyor. 

    Mesela GetSystemInfo fonksiyonu, SYSTEM_INFO adlı bir yapının adresini alır, içini sistemdeki işlemci ile ilgili bazı bilgilerle doldurur, sonra fonksiyon sonlanır. Ancak yapı içindeki bilgilere birşey olmaz çünkü yapı fonksiyonun içinde yaratılmadı, biz sadece ona adresini yolladık.

    Dizilerde nesneyi direkt yollamak gibi bir şansın zaten yok, dizinin adını yazdığında fonksiyona yine başlangıç adresi gider. 

    C++ da pointer kullanımı zaten tavsiye edilmez (bkz: reference) ve hata yönetimi exception yöntemi ile yapılır, ancak C de exception kavramı olmadığı için, fonksiyonun hata verip vermediği geri dönüş değeri ile kontrol edilir. Bazı durumlarda, dönüş değeri farklı anlamlarda kullanılmak istenir ,  tüm değerler (- sayilar, 0, + sayilar) normal olarak dönebilir, bu durumda, geri dönüş değerini tutacak nesne, fonksiyona parametre olarak verilebilir.

    int IslemYap(int p1, int *sonuc);


    Bunlar dışında queue, linkedlist vb veri yapılarında çok sık kullanılır pointer ancak daha kısıtlı bir kullanım alanı. Biraz daha ileri seviyeye geçersek, C dilinin tasarımı tamamen pointer kavramı üzerine kuruludur. C++ da C nin nesne yönelimli versiyonu olduğu için ve mümkün olduğunca C yi kapsadığı için pointerları içerir. Ancak kullanılmasından mümkün olduğunca kaçınılır.

    ---Burdan sonrası konuyla direkt ilgili değil ve biraz daha ileri konular---

    Şimdi C'nin tasarımı ve adres kavramı üzerine birşeyler yazayım. C de başlangıçta dizi dışında özelleştirilebilir bir veri yapısı yoktu (struct, union gibi). Dizilerin ve fonksiyonların isimleri aynı zamanda başlangıç adresleridir, Bu C nin en büyük tasarım özelliğidir. Fonksiyon çağırmak kavramının fonksiyonun adı ile ilgisi yoktur, tamamen () operatörleri ile ilgilidir, diziler için de aynı şeyler geçerli, örneklere bakalım.

    Fonksiyon(p1, p2, p3);

    şeklinde fonksiyon çağırıldığında, () operatörü, öncelikle p1, p2, p3 ü belleğe iteler :), ardından, geri dönüş adresini belleğe push eder ve Fonksiyon isminin belirttiği adres çağırılır (CALL instructionu ile).

    Mesela printf("%X\n", Fonksiyon) yazarak, fonksiyonun hangi adreste bulunduğunu görebilirsin. Veya daha iyisi, direkt adres ile 

    0x2070FF(p1, p2, p3);

    Şeklinde fonksiyon bile çağırabilirsin :) konuyla direkt ilgili olmadığı için pointer cast işlemini yazmadım. Bu durumda şu kodlar çalışır arka planda,

    push p3
    push p2
    push p1
    call 0x2070FF ( ya da fonksiyonun adı -- call geri dönüş değerini arka planda kendisi belleğe push eder en son)

    Görüldüğü gibi işi yapan () operatörleri.

    Aynı şeyi diziler için düşünelim. [] operatörü , solundaki adresi (yani dizi ismini) başlangıç kabul ederek, dizi türünün boyutu * içerdeki değer kadar  ilerler ve oradan aldığı veriyi döndürür. Örnek

    int dizi[5];

    dizi[3];

    İfadesinde, int türü boyutu 4 bayttır, dizi adresi 0x207010 adresi olsun, [] operatörü, 0x207010 + (4*3) yani 0x20701C adresine gider, ve ordaki 4 baytlık datayı alır döndürür. 3 içerdeki değer, 4 ise dizi türünün (int) standart boyutu.

    Yine printf("%X\n", dizi) yazarak, dizinin başlangıç adresini görebilirsiniz. Aynı şekilde 0x207010[3] şeklinde bile kullanabilirsiniz, yani bu operatörler, adres alırlar ve çok esneklerdir, hatta şu iki ifade birbiri ile tamamen aynıdır.

    dizi[4];

    4[dizi];

    Nedenini anlamayı size bırakıyorum :)

    Shellcode kavramını duymuş olanlar için söyleyim, burda mesela asm ile yazılmış 250 baytlık bir fonksiyonun kodları kopyalanır (hex editörle mesela) ve C de bir dizinin içine yapıştırılır. Sonra dizi ismi yani fonksiyon kodunun başlangıç adresi, cast ile fonksiyon göstericisi gibi gösterilerek, o baytların fonksiyon gibi çalıştırılması sağlanır.

    Bu biraz cevaptan ziyade dökümana benzedi ama birilerine faydası dokunur umarım.

    dipnot: yukarıda atladığım casting olayını biraz açayım, 0x207010[3] dediğiniz zaman, bu adresin türünü derleyici bilemez dolayısıyla kodu derleyemez, o yüzden önce o adresin ne tür bir adres olduğunu tanıtmak için cast etmemiz gerek. ((int*)0x207010)[3] , biraz daha çirkin görünüyor dimi.  Fonksiyon için gereken casting ise şöyle ((int(*)(int,int,int))0x2070FF)(p1, p2, p3); fonksiyon göstericilerinin yazımı biraz karmaşıktır, ancak bir kere anlarsanız çok basit yukarıdaki cast şunu söylüyor, bu adreste int fonksiyon(int,int,int) prototipli bir fonksiyon var.

  7. KısayolKısayol reportŞikayet pmÖzel Mesaj
    sniperscope
    sniperscope's avatar
    Banlanmış Üye
    Kayıt Tarihi: 14/Mart/2009
    Erkek

    Verdiginiz cevaplar icin tesekkurler.

    Simdi benim buradan anladigim;

    int x = 100; // diyelimki x degiskene 100 byte lik yer ayrildi

    int y = x;  // y degiskenini x e esitleyerek bellekte 100 byte lik baska bir yer daha ayrildi.

    int z = y; // bellekte baska bir 100 byte lik alan acildi boylece tek bir deger icin bellekte bos yere 200 byte lik yer acilmis oldu.

     

    ama

    int x = 100;

    int *y, *z;

    *y = &x;

    *z = &x;

    seklinde yaparsak elimizde 3 ayri degisken olacak ama sadece 100 byte lik alan kaplayacagiz.

     

    Dogrumu acaba?


    "Yer yuzunde hic bir pislik yoktur ki; altindan bir yahudi cikmasin" Adolf Hitler... "Turkiye de hicbir pislik yokturki altindan cemaat cikmasin" SniperScope "Nerede yavşak, hırsız varsa hepsi Allahçı" Fazil Say
  8. KısayolKısayol reportŞikayet pmÖzel Mesaj
    dhmm
    dhmm's avatar
    Kayıt Tarihi: 15/Eylül/2011
    Erkek

    Abi bir tane swap islemi yapan bir fonksiyon yapmayi dene anliycaksin en basitinden ne ise yaradiklarini

     

    prgoramin her yerinden o degiseknin kendisini degistirebiliyorsun

    Ilk verdigin ornekte

     

    int i = 5;

    int j;

    int *pointer;

     

    j=i deyince evet j de 5 oluyor

    pointer = i deyince pointer 5 olmuyor. Sadece i nin bellekte degerini bulundugu bolumu gosteriyor

     

    EGER i degisirse j de i nin degerini gosterdigi icin degisir

    Fakat j i nin kopyasini aldigi icin yine 5 kalir

     

    Bak simdi sana bir ornek yazdim atayim okursan anliyacaksin

     

     

    #include<iostream.h>
    #include<conio.h>
    int main(int argc, char* argv[])
    {
            int i = 5;
            int j= i;
            int *pointer = &i;
    
            //Burada i ve pointer ayni cikti veriyor
            cout << "i = "<<i<<"  j = "<<j<<"  pointer = "<<*pointer<<endl;
    
            //Sadece i yi degistiriyoruz ve pointerde onu gosterdigi icin
            //degismis gibi duruyor
            i=12;
            cout << "i = "<<i<<"  j = "<<j<<"  pointer = "<<*pointer<<endl;
    
            //j yi degistirince ise sadece j degisiyor
            j=99;
            cout << "i = "<<i<<"  j = "<<j<<"  pointer = "<<*pointer<<endl;
    
            //Ama pointeri degistirirsek i da degisiyor
            *pointer= 55;
            cout << "i = "<<i<<"  j = "<<j<<"  pointer = "<<*pointer<<endl;
    
            getch();
            return 0;
    }

    Ozgurluk aslinda her istedigini yapabilmek degildir, istemedigini yapmamaktir. // Verdigin degeri gormeyince, gordugun degeri ver !!! // Hayatin herkes icin bir bavulu vardir !!! // Dusmek gerekir bazen hayatta; kalkmayi ogrenebilmek icin
  9. KısayolKısayol reportŞikayet pmÖzel Mesaj
    sniperscope
    sniperscope's avatar
    Banlanmış Üye
    Kayıt Tarihi: 14/Mart/2009
    Erkek

    Hafiz ornek icin tesekkurler.

    Simdi olayi kavradim gibi. Ama surada bir sorun var

    ilk basta int j = i; yaptik, daha sonra asagidaki satirda int i = 12; yaptik.

    Yani int j degeri ilk atadigimiz deger olan 5 te sabit kaliyor ve bellekte misal 5 byte lik bir alani int j icin aciyor.

    int i = 12; yapinca int i nin degeri degisiyor ama int j halen int i nin eski degerini gosteriyor.

     

    *pointer ise int i nerede degisirse degissin (programin basinda ortasinda veya sonunda) onun adresini tuttugu icin otomatikman ayni degeri aliyor.

    Yani *pointer aslinda deger falan almiyor sadece int i nin adres bilgisini tutuyor ve bellekte *pointer icin extradan yer tahsisi yapilmiyor.

     

    Dogrumudur?

     


    "Yer yuzunde hic bir pislik yoktur ki; altindan bir yahudi cikmasin" Adolf Hitler... "Turkiye de hicbir pislik yokturki altindan cemaat cikmasin" SniperScope "Nerede yavşak, hırsız varsa hepsi Allahçı" Fazil Say
Toplam Hit: 2052 Toplam Mesaj: 9