Ich brauch ein bischen hilfe bei einigen Fragen zu Zeigern



  • hallo,

    ich lerne gerade etwas denn Umgang mit Zeigern und Referenzen.
    Eigentlich weis ich selbst garnicht genau wofür man das eigentlich braucht und man nicht einfach normale Variablen verwendet. Das Problem ist aber das im Builder ja alles schon mit TForm *Form1 usw. sprich mit Zeiger läuft.

    Hier mal ein paar Fragen die ich trotz nachlesen noch nicht ganz verstanden habe:

    1.) Was ist denn der wesentliche Vorteil bei der Verwendung von Zeigern und wann sollte ich sie einsetzen und wann eher nicht ?

    2.) Hier mal ein Codestückchen wie ich es verstanden habe, stimmt das ???

    int i=17; // Integer Variable denn Wert 17 Zuweisen
     int *pi; // Einen einen Zeiger anlegen der einen Int Wert annehmen kann
    
     pi = &i; // Ich weise der Speicheradresse pi die Adresse von i zu
    
     // pi ist die Adresse im Speicher wo der Integer Wert steht
     // *pi ist der Inhalt der Integer Variablen, sprich 17 
    
     /* &i weist pi die Speicheradresse von i zu,
        wird nun der Wert von i verändert änder sich auch der wert vin pi.
        andersrum genauso da sie auf die selbe speicheradresse zeigen. */
    
     /* warum kann ich aber nicht z.B. sagen *pi = 17 ????
        wenn  ich es mache stürzt der Builder ab :(   */
    

    Bitte helft mir da ein bischen auf die sprünge da ich mit dem ganzen sehr schwer zurechtkomme 😞

    danke!



  • Verschoben nach "C++".



  • int i=17; // Integer Variable denn Wert 17 Zuweisen
    

    eine variablen dekleration mit einer initialiesierung (wir meinen das gleiche ;))

    int *pi; // Einen einen Zeiger anlegen der einen Int Wert annehmen kann
    

    der auf ein int zeigen kann, ein int wert ist z.b. 17

    pi = &i; // Ich weise der Speicheradresse pi die Adresse von i zu
    

    nicht ganz, pi kann eine speicher adresse von einen int aufnähmen

    // pi ist die Adresse im Speicher wo der Integer Wert steht
    

    pi speichert die adresse von der int variable

    // *pi ist der Inhalt der Integer Variablen, sprich 17
    

    duch den op* sagst du er soll kucken was in pi steht und dann an die adresse gehen und das den int der an der adresse ist zurück geben (bildlich gesprochen)

    /* &i weist pi die Speicheradresse von i zu,
        wird nun der Wert von i verändert änder sich auch der wert vin pi.
        andersrum genauso da sie auf die selbe speicheradresse zeigen. */
    

    wenn der pc i z.b. auf speicher adresse 100 angelegt hatt, dann macht er bei "i = 42;" dies: er geht an die speicher adresse 100 und speicher dort eine 42.
    wenn du schreibst &i; dann hollt der pc die adresse von i (in unser bsp die 100)

    /* warum kann ich aber nicht z.B. sagen *pi = 17 ????
        wenn  ich es mache stürzt der Builder ab :(   */
    

    das sollte gehen, aber nur wenn pi auf ein int zeigt z.b.

    int i=17;
    int *pi;
    //hier zeigt pi noch auf kein int
    *pi = 42;
    //sollte zum absturtz führen
    pi = &i;
    

    oder

    int *pi;
    
    {
        int i = 17;
        pi = &i;
    }// hier am ende des scopes wird i zerstört
    
    *pi = 17;// absturtz
    

    solche zeiger nennt man wilde zeiger, sie sind ein beliebter fehler



  • Dimah schrieb:

    solche zeiger nennt man wilde zeiger, sie sind ein beliebter fehler

    Ich würde eher sagen: Sie sind einer der meist gehassten Fehler 😉



  • int *pi; 
    
    { 
        int i = 17; 
        pi = &i; 
    }// hier am ende des scopes wird i zerstört 
    
    *pi = 17;// absturtz
    

    heißt das am oberen beispiel:

    auserhalb der funktion einen zeiger auf eine int variable anlegen.
    in der funktion die adresse von pi auf die adresse von i legen.
    ende der funktion. i wird zerstört und aus dem speicher gelöscht weil es eine lokale variable ist.
    nun will ich mit *pi = 17 an die stelle im speicher wo i stand denn wert 17 zuweisen aber die stelle ist nichtmehr reserviert und das programm stürtzt ab.

    ist das richtig ???



  • Wenn du pi außerhalb einer Verbundanweisung (außerhalb "{" "}") deklarierst und dann in einer Verbundanweisung diesen Zeiger auf eine Variable zeigen lässt, kannst du pi dort beliebig etwas zuweisen:

    int *pi;  
    
    {  
        int i = 17;  
        pi = &i;
        *pi = 19 // i enthält jetzt 19  
    }// hier am ende des scopes wird i zerstört  
    
    *pi = 17;// absturtz
    

    Außerhalb der Verbundanweisung zeigt pi auf nichts mehrm, da i zerstört wurde, du müsstest also folgendes machen:

    int *pi;  
    
    {  
        int i = 17;  
        pi = &i;
        *pi = 19;  
    }// hier am ende des scopes wird i zerstört  
    
    int neue_variable;
    pi = &neue_variable;
    *pi = 17;
    

    17 würde jetzt in neue_variable gespeichert werden. Die geschweiften Klammern sind keine Funktion. eine Funkton wird aufgerufen und von dort aus könnte man keinen Zeiger benutzen der z.B. in einer anderen Funktion deklraiert ist. Das mit den geschweiften Klammern ist nur ein Beispiel für einen Gültigkeitsbereich. könnte auch ne if-Anweisung sein oder eine Schleife sein.

    Code-Hacker



  • pointerNebie schrieb:

    ist das richtig ???

    ja



  • danke.
    und warum genau sollte ich zeiger statt einfachen variablen verwenden ?
    was ist denn daran der wesentliche vorteil und wo sollte man am besten lieber zeiger als variablen verwenden ???



  • also es ist so das pointer aus c kommen in c++ wurden referenzen eingeführt, referenzen ersetzen an vielen stellen die pointer

    am öfftersten setzt man es für sowas ein
    http://www.volkard.de/vcppkold/inhalt.html Lektion 33 bis 37

    ein vorteil bei deinen bsp code gibts nicht, man könnte sich aber was zusammen fummeln

    z.b.

    int a = 0;
    int b = 0;
    
    bool a_statt_b = false;
    if(/* user fragen */)
        a_statt_b = true;
    
    if(a_statt_b)
        a = 100;
    else
        b = 100;
    
    //... 
    if(a_statt_b)
        a = 100;
    else
        b = 100;
    
    //usw.
    

    und mit pointern

    int a = 0;
    int b = 0;
    int * i = &b;
    
    if(/* user fragen */)
        i = &a;
    
    *i = 100;
    
    //... 
    
    *i = 100;
    
    //usw.
    

    oder http://www.c-plusplus.net/forum/viewtopic.php?t=39497


Anmelden zum Antworten