geht sowas?



  • hey,

    mein prof hat mir die zusammenstellung hier gegeben und ich kann das resultat nicht nachvollziehen. Also hier der Code:

    #include <stdio.h>
    
    int main(void){
    static char* z[] = {"JAGURAR", "OPEL", "MAZDA", "AUDI", "TOYOTA"};
    char** zz[] = {z+4,z+3,z+2,z+1,z};
    char*** zzz = zz;
    
    		printf("%s  \n",*--*++zzz+2); //1.Ausgabe ZDA
    		printf("%s  \n",3 + *zzz[-2]); //2.Ausgabe keine ausgabe
    		printf("%s  \n",*(zz[3]+1)+1); //3.Ausgabe AZDA
    		printf("%s  \n",1 + zzz[-1][-1]); //4.Ausgabe UDI
    }
    

    1.Ausgabe
    er gibt zwar zda aus, aber wie kann ich das nachvollziehen. Heißt das +2 das, ab dem 2ten zeichen ausgegeben wird oder wie?
    2.das -2 weißt auf nichts zurück deswegen keine ausgabe?
    3.keine Ahnung was, beim ersten oder +1 passiert 😕
    4.wie soll ich das -1 verstehen.
    getestet hab ich das mit MSVC++ 7.1 und dem mingw



  • Du solltest dazu mal deine Aufzeichnungen über Operatoren und Zeigerarithmetik zur Hand nehmen.

    mosta schrieb:

    1.Ausgabe
    er gibt zwar zda aus, aber wie kann ich das nachvollziehen. Heißt das +2 das, ab dem 2ten zeichen ausgegeben wird oder wie?

    Ab dem dritten. +0 ist erstes, +1 ist zweites, +2 ...

    mosta schrieb:

    2.das -2 weißt auf nichts zurück deswegen keine ausgabe?

    Es gibt kein zzz[-2], deshalb ➡ undefiniertes Verhalten. Was dies in C++ bedeutet, dazu sollte es genug Lektüre im Netz geben. Selbst hier im Forum gibts dazu etliche Beiträge.

    mosta schrieb:

    3.keine Ahnung was, beim ersten oder +1 passiert 😕

    +1 heisst nichts anderes als "addiere 1". Dazu nochmal der Hinweis, schau dir Zeigerarithmetik an.

    mosta schrieb:

    4.wie soll ich das -1 verstehen.

    Seiteneffekte der ersten Ausgabe beachten.

    Da du wahrscheinlich mit anderen Antworten gerechnet hast, hier mal ein kurzes Beispiel. Danach solltest du aber versuchen, selbst etwas zu denken.

    // 3.
    zz           // = {z+4,z+3,z+2,z+1,z}
    zz[3]        // = z+1                 // = {"OPEL", "MAZDA", "AUDI", "TOYOTA"}
    zz[3]+1      // = z+1+1               // = {"MAZDA", "AUDI", "TOYOTA"}
    *(zz[3]+1)   // = (zz[3]+1)[0]        // = "MAZDA"
    *(zz[3]+1)+1 // = "AZDA"
    

    edit:
    Hinweis von CStoll bzgl. Seiteneffekten.



  • groovemaster schrieb:

    mosta schrieb:

    3.keine Ahnung was, beim ersten oder +1 passiert 😕

    +1 heisst nichts anderes als "addiere 1". Dazu nochmal der Hinweis, schau dir Zeigerarithmetik an.

    Am anfang steht er auf der dritten position und die +1 beudeutet das er ab dem zweiten zeichen ausgibt nur was passiert beim letzten +1.



  • Das letzte +1 bedeutet doch, dass er ab dem zweiten Zeichen ausgibt. Würde da zB nur

    *(zz[3]+1)
    

    stehen, würde "MAZDA" ausgegeben werden.
    Und *(zz[3]+1) ist nunmal ein Zeiger, welcher auf das erste Zeichen von "MAZDA" verweist. Wird dieser Zeiger inkrementiert (+1), dann verweist er entsprechend auf das zweite Zeichen.



  • groovemaster schrieb:

    mosta schrieb:

    2.das -2 weißt auf nichts zurück deswegen keine ausgabe?

    Es gibt kein zzz[-2], deshalb ➡ undefiniertes Verhalten. Was dies in C++ bedeutet, dazu sollte es genug Lektüre im Netz geben. Selbst hier im Forum gibts dazu etliche Beiträge.

    zzz ist ein Zeiger, da gibt es durchaus ein zzz[-2] (das ist gleichbedeutend mit *(zzz-2)) - du mußt nur darauf achten, daß dieses Element nicht außerhalb des Arrays liegt, über das du läufst.

    Ansonsten ein Tip - setz ein paar Klammern entsprechend dem Operator-Vorrang und werte die Ausdrücke von innen nach außen aus.



  • CStoll (off) schrieb:

    zzz ist ein Zeiger, da gibt es durchaus ein zzz[-2]

    Nein, gibt es nicht. zzz ist ein Zeiger auf das erste Element von zz. Praktisch genau dieser Zeiger, zu dem zz in einem Zeigerkontext umgewandelt wird. Und vor dem ersten Element gibt es nichts, auf was wir zugreifen dürfen. Somit liefert zzz[-2] undefiniertes Verhalten. Punkt.



  • Deswegen auch:

    CStoll (off) schrieb:

    du mußt nur darauf achten, daß dieses Element nicht außerhalb des Arrays liegt, über das du läufst.

    (und zzz zeigt an dieser Stelle nicht mehr auf den Anfang des Arrays, da die erste Anweisung einige Seiteneffekte hatte).

    OK, genauer: zzz[-2] ist nicht "per Definition" verboten, aber es kann zu undefiniertem Verhalten führen.



  • CStoll (off) schrieb:

    und zzz zeigt an dieser Stelle nicht mehr auf den Anfang des Arrays, da die erste Anweisung einige Seiteneffekte hatte.

    Ja, das stimmt. Da zzz lediglich inkrementiert wird, liefert zzz[-2] aber immer noch undefiniertes Verhalten. 🙂


Anmelden zum Antworten