Post- und Prefix Notation?



  • Danke HighLigerBiMBam!

    Jetzt weiß ich wo ich gestern die ganze Zeit hängen geblieben bin.

    Ich habe die ganze Zeit die Codezeile

    *(p+1) = 's';
    

    falsch interpretiert. Ich hab das so interpretiert, als ob der Pointer p um einen Schritt erhöht wird und an diese neue Stelle das 's' geschrieben wird. Wie diese Stelle aber nun wirklich funktionieren soll, kann ich mir aber leider nicht erklären. Es muss doch, damit ich an das Element mit dem Index 2 rankomme und aus dem 'd' ein 's' werden kann, trotzdem der Pointer p um eins erhöht werden. Und zwar bevor ich das neue char schreiben kann. Laut Vorrangregel kommt ja auch das p+1 zuerst, da Klammern vor diesem Pointer-Sternchen kommen...

    Natürlich hat DirkB recht wenn er schreibt, dass

    p+1 verändert den Zeiger nicht.

    Ich hab auch die Adressen ausgeben lassen und p+1 verändert den Zeiger in der Tat nicht. Wie aber kommt dann trotzdem das weitere 's' an den Index 2, wenn doch der Zeiger eigntlich noch immer auf den Index 1 des Arrays zeigt?

    Die zentrale Frage ist also dann: "Was macht *(p+1) bzw. *(p+7)?"



  • Du erhöhst ja den Pointer p mit p + 1 nicht, sondern du sagst nur, dass du auf das Element/Wert der Adresse *(p + 1) zugreifen willst. p bleibt unverändert. Anders ist dies bei dem post/prefix, dieser verändert p in jedem Fall. Natürlich kannst du p mit einer Adition verändert, aber nur mit einer Zuweisung:

    p = p + 7
    


  • Hm, Danke.

    Jetzt hab ich's endlich gerafft.

    Ich hab jetzt noch ein paar Fragen.

    Es gibt ja auch noch das Konstrukt:

    *p+1 entspricht (*p)+1

    Dieses Konstrukt erhöht mir aber nun die Adresse des Pointers, oder?



  • *p = *p + 1
    

    Damit erhöhst du bestenfalls den Wert auf den der Pointer zeigt.

    *p = (*p)+1
    

    Ist äquivalent zu oben.

    char zk[2][6] = {"asdfg", "qwer"}; 
        char *p, *q; 
        int j = 3; 
    
        p = &zk[0][0];  // p zeigt auf 'a' 
        q = p + 6;     //q zeigt auf 'q' 
        *(p++) = *q;    // p zeigt auf 's'  string ist {"qsdfg", "qwer"} 
        *(p+1) = 's';   // string ist {"qssfg", "qwer"} 
        zk[0][j] = '\0'; // string ist {"qss0g", "qwer"} 
        *q = 'g';      // string ist {"qss0g", "gwer"} 
        *(p+7) = 'h';  // string ist {"qss0g", "gwhr"} 
    
    	//Zusatz
    	*p = *p+1;    // string ist {"qts0g", "gwhr"} 
    	p = p + 8;   // p zeigt auf 'r'
    	*p = (*p)+1;   //string ist {"qts0g", "gwhs"}
    


  • Ich hoffe ich nerv nicht, aber was macht dann das hier:

    *&j entspricht doch auch: *(&j)=j

    Was kann man nun damit machen? Mit &j hole ich mir doch die Adresse von einer Variable j, oder? Was aber macht dann der * Stern hier? Ist das an dieser Stelle das Dereferenzierungszeichen oder ist das immer noch ein Pointer?



  • Ich würde sagen du dereferenzierst die Adresse von j (welche ja normalerweise ein pointer ist) und greifst mit dem * auf den Wert der Adresse zu.

    int a = 5, b;  // a = 5
    	int *p = &a; // p zeigt auf a
    
    	*(&a) = 7; // die Adresse von a wird dereferenziert ist also a = 7
    	(*&a)++; // die Adresse von a wird dereferenziert ist also a++ und somit ist a = 8
    	*&b = 4;
    
        printf("%i %i", *p, b); // p zeigt auf a und der Wert davon ist nun 8
    


  • *(&a) = 7; // die Adresse von a wird dereferenziert ist also a = 7

    Ich ersetze hier also die Adresse von a mit dem Wert 7 bzw. einer jeden anderen Variablen? Stimmt das so?



  • Nein, du setzt a = 7 den Wert. *&a ergibt wenig Sinn, da die Operationen sich gegenseitig aufheben, also kannst du diese auch weglassen und nu a schreiben.

    &variable //Adresse von variable (Wert->Adresse)
    *pointer //Dereferenzierung einer Adresse/Pointers (Adresse->Wert)
    
    *&variable // Wert -> Adresse -> Wert sinnvoll?
    


  • Ahja, wenn ich also schreibe *&j = 7; dann kann ich gleich bloß j = 7; schreiben, weil sich *& gegenseitig aufheben. Kann man das mit -1+1=0 vergleichen? Das hebt sich ja auch auf...?

    Gleich noch mal eine neue Frage:

    Was passiert hier:

    int a = 5, b;
        int *p;
    
    	p = &a;
    	printf("%u\n\n", p);
    
    	*p = *p * *p;
    	printf("%u", p);
    

    In p steht die Adresse von a. Und nun multipliziere ich zwei (gleiche) Pointer miteinander... Was passiert da? Wenn ich mir nach der Multiplikation den pointer ausgebe, dann ist es die gleiche Adresse wie vorher...



  • Ja du kannst j = 7 schreiben. Den Vergleich " -1+1=0 " finde ich etwas sonderbar, ich würde es eher mit Wellen Vergleich die sich gegenseitig auslöschen (Wasser,Ton,...)

    &variable //Adresse von variable (Wert->Adresse) 
    *pointer //Dereferenzierung einer Adresse/Pointers (Adresse->Wert) 
    
    *&variable // Wert -> Adresse -> Wert sinnvoll?
    

    Frage zwei:

    int a = 5;
        int *p;
    
        p = &a;   //p zeigt auf a welches 5 ist
        printf("%u\n\n", p);
    
        printf("%i\n\n", *p); //Ausgabe WERT von p!
    
        *p = *p * *p; // Wert auf den pointer zeigt (also a) = Wert auf den Pointer zeigt (also a) MAL Wert auf den Pointer zeigt (also a)
    //anderst ausgedückt könntest du hier " a = a * a " schreiben!
    //Somit wird der pointer natürlich NICHT verändert.
        printf("%u", p);
    
        printf("%i\n\n", *p); //Ausgabe WERT von p!
    


  • printf hat für Pointer extra ein %p:

    printf("%p", p);
    

    Dann passt das, egal wie groß der Pointer ist (Anzahl der Bit))

    Wenn du *int p; hast, dann ist *p (mit dem 😉 so wie ein normales int.
    p (ohne 😉 ist der Zeiger.



  • Ich hab dann noch eine Frage:

    Bleiben wir bei Pointer:

    Was macht dann -*p? Man kann das ja auch als -(*p) schreiben. Bekommt da der der Wert der ja durch *p dereferenziert ein Minus? Oder wird da irgendwas an der Adresse gedreht?



  • Probiere es doch einfach aus!!!!! Sei mal selbstständiger. Du musst doch nur die Adresse und den Wert vor der Operation und nach der Operation ausgeben. Dann siehst du auch was passiert.



  • Gut du hast Recht. Wenn man es ausprobiert sieht man es. Ich habs jetzt mal so ausprobiert:

    int a = 5, b = 0;
        int *p = &a;
    
    	printf("p_vorher = %p\n\n", p);
    	printf("b_vorher = %i\n\n", a);
    
    	b = -*p;
    	printf("p_nachher = %p\n\n", p);
    	printf("b_nachher = %i\n\n", a);
    

    Meine Konsolenausgabe:

    p_vorher = 0024FF0C
    b_vorher = 5
    p_nachher = 0024FF0C
    b_nachher = 5

    Was schleiße ich nun daraus? Dass das irgendwie ja nix bewirkt hat. Weder hat es an der Adresse noch am Wert was verändert....



  • Schau dir mal den Wert von b an! Deine Ausgabebezeichnung ist falsch btw.

    int a = 5, b = 0; 
        int *p = &a; 
    
        printf("p_vorher = %p\n\n", p);
        printf("*p_vorher = %i\n\n", *p); 
        printf("a_vorher = %i\n\n", a);
    	printf("b_vorher = %i\n\n", b); 
    
        b = -*p; 
        printf("p_nachher = %p\n\n", p);
        printf("*p_nachher = %i\n\n", *p);  
        printf("a_nachher = %i\n\n", a);
    	printf("b_nachher = %i\n\n", b);
    


  • Ja, hier war wirklich nur die Ausgabebezeichnung falsch.

    Nochmal zur Thematik von %i, %p, %u.

    int a = 5, *p;
    p = &a;
    
    printf("a = %i\n\n", a);   //Ausgabe a = 5;
    printf("p = %p\n\n", p);   //Ausgabe der Adresse in Hex
    printf("p = %i\n\n", p);   //Ausgabe der Adresse in Dez
    printf("p = %u\n\n", p);   //Ausgabe der Adresse in Dez
    

    Irgendeinen Unterschied muss aber %u zu %i haben, oder? Auf meinen Bildschirmausgaben sehe ich aber keinen...

    Das hier hab ich noch nicht so verstanden:

    printf hat für Pointer extra ein %p:
    C/C++ Code:
    printf("%p", p);

    Dann passt das, egal wie groß der Pointer ist (Anzahl der Bit))

    Wenn du int *p; hast, dann ist *p (mit dem 😉 so wie ein normales int.
    p (ohne 😉 ist der Zeiger.




Anmelden zum Antworten