Inkrementieren - verwirrt


  • Mod

    volkard schrieb:

    ghci schrieb:

    camper schrieb:

    Wieviele verschiedene Ergebnisse für j sind möglich? 😉

    ghci> length . nub . map ([a,b,c,d,e]->a*b*(c+1)*(d+1)+e) . permutations . take 5 $ [4..]
    30
    

    Jup, sehe ich auch so.

    ich nicht. Es gibt keinen Grund anzunehmen, dass der Konvertierungsoperator sofort nach dem Inkrementieren aufgerufen werden muss.



  • Dann nochmal eine andere Frage, wenn es okay ist:

    #includ<iostream>
    
    #define X(C,D) ((C)>(D)?(C):(D))
    #define Y(C) ((C)>0?(C):-(C))
    
    #define A(B) B+B
    #define C(D) D*D
    
    using namespace std;
    
    int main() {
       cout << X(1,100)<< endl;
       cout << Y(-100) << endl;
       cout << C(A(6)) << endl;
       cout << A(C(6)) << endl;
    }
    

    (i) Welche Funktionalität beschreiben die Präprozessoranweisungen in den Zeilen 3 und 4?

    (ii) Welchen Quelltext sieht der Compiler in den Zeilen 14 und 15?

    Zu (i):
    Zeile 3: Maximumsfunktion
    Zeile 4: Betragsfunktion

    Zu (ii):
    Zeile 14: A(6)*A(6)=6+6*6+6
    Zeile 15: C(6)+C(6)=6*6+6*6

    Stimmt das?


  • Mod

    Sieht richtig aus und lehrt dich hoffentlich, wieso man Makros eben nicht für solche Zwecke einsetzen sollte. Letzteres hast du darauf gelernt, oder?



  • Ja, das habe ich verstanden.

    Nur nicht, wieso für Zeile 14 und für Zeile 15 beim Ausführen

    48 und 72 ausgegeben wird.

    Denn ich dachte da müsste 78 und 252 stehen.



  • Der Compiler kennt Punkt-vor-Strich.


  • Mod

    LinuxC_newbie schrieb:

    Ja, das habe ich verstanden.

    Nur nicht, wieso für Zeile 14 und für Zeile 15 beim Ausführen

    48 und 72 ausgegeben wird.

    Denn ich dachte da müsste 78 und 252 stehen.

    Dann hast du es eben gerade nicht verstanden. Nicht bloß blind nachplappern*, dass im Buch (hoffentlich) steht, dass Makros böse sind. Das Beispiel ist gerade dazu da, damit du auch verstehst, warum.

    *: Ja, das ist verführerisch, da man damit so tun kann, als ob man genau so viel verstanden hätte, wie die klugen Leute. Aber hat man in Wirklichkeit gar nicht.



  • someone@somewhere:~$ echo "#include<iostream>
    
    #define X(C,D) ((C)>(D)?(C):(D))
    #define Y(C) ((C)>0?(C):-(C))
    
    #define A(B) B+B
    #define C(D) D*D
    
    using namespace std;
    
    int main() {
       cout << X(1,100)<< endl;
       cout << Y(-100) << endl;
       cout << C(A(6)) << endl;
       cout << A(C(6)) << endl;
    }
    " | g++ -E -x c++ - | sed -n -e '/main[[:space:]]*(/,/^}/p'
    int main() {
       cout << ((1)>(100)?(1):(100))<< endl;
       cout << ((-100)>0?(-100):-(-100)) << endl;
       cout << 6 +6*6 +6 << endl;
       cout << 6*6 +6*6 << endl;
    }
    someone@somewhere:~$
    

    * scnr *



  • Ein freundlicher Umgangston sieht aber auch anders aus!
    Ich finde, dass ich mich hier nicht immer so blöde von der Seite anmachen lassen muss! Ich frage normal, und möchte auch normale Antworten haben, die nicht so von oben herab sind.

    Ich wiederhole nochmal, dass ich KEIN Informatiker bin und das auch nicht studiere. Vielmehr handelt es sich nur um einen kleinen einsemestrigen C++-Einschub im Rahmen meines Studiums.

    --------------------

    Es ist mir sehr wohl klar, was "das Böse" an Makros ist.

    Man würde erwarten, dass

    C(A(6))=144 ist, da A(6)=12. Es kommt aber C(A(6))=48 heraus.

    Ebenso würde man vermuten, dass A(C(6))=72. Und es kommt auch hier tatsächlich 72 heraus.



  • LinuxC_newbie schrieb:

    Man würde erwarten, dass

    C(A(6))=144 ist, da A(6)=12.

    A(6) ist nicht 12. A(6) ist 6+6.

    Der Präprozessor macht nur stumpfe Textersetzungen, er rechnet nicht.



  • Das habe ich doch geschrieben!

    Man würde intuitiv erwarten, dass da 144 rauskommt, kommts aber nicht, weil da nicht 12 sondern 6+6 steht.


  • Mod

    Und jetzt die nächste Stufe der Bosheit:

    int i=6;
    cout << C(i++);
    

    Was kommt raus und warum? (Bitte den Threadersteller antworten lassen!)

    P.S.:
    http://www.tty1.net/smart-questions_de.html
    http://www.tty1.net/smart-questions_de.html#keepcool
    http://www.tty1.net/smart-questions_de.html#not_losing



  • 36


  • Mod

    LinuxC_newbie schrieb:

    36

    Och, nö 😞
    So ein langer Thread und gar nichts daraus mitgenommen?


  • Mod

    SeppJ schrieb:

    LinuxC_newbie schrieb:

    36

    Och, nö 😞
    So ein langer Thread und gar nichts daraus mitgenommen?

    Wäre pädagogische evtl. besser mit so etwas wie

    int i=1, j=2;
    cout << X(++i,++j);
    

    anzufangen und dann mit dem C-Beispiel weiterzumachen.



  • Wie gesagt: Du sagst wieder: Es ist nicht definiert, stimmts?

    Und ich sage wieder: Das kapiere ich nicht.

    Es kommt 36 heraus (bei mir).



  • Der Praeprozessor macht nur Textersetzung. Du hast

    #define C(D) D*D
    

    Wenn du nun

    cout << C(i++);
    

    hast ist "D = i++", also wird C(i++) durch i++ * i++ uebersetzt, d.h. du hast dann

    cout << i++ * i++;
    

    und das ist undefiniert. Da das Verhalten des Ausdrucks undefiniert ist ist es bloss Zufall, dass bei dir 36 rauskommt.

    *Edit
    Mein Beitrag ist wohl etwas ueberfluessig... wurde ja eigentlich alles schon gesagt. Habe erst jetzt alle Beitrage zum Thema durchgelesen...



  • Okay, aber WARUM ist das undefiniert?

    Was ist daran mehrdeutig oder so, dass es nicht definiert ist?



  • Den Grund hat SeppJ auf der ersten Seite angegeben:

    Mehrere Seiteneffekte auf i ohne Sequenzpunkt dazwischen.

    Der gleiche Grund warum

    int i = 5;
    i = i++;
    

    nicht definiert ist.


  • Mod

    LinuxC_newbie schrieb:

    Was ist daran mehrdeutig

    i = 4;
    i++ * i++ + i++;
    

    Ist das nun
    4 * 5 + 6?
    Oder
    4 * 4 + 4?
    Oder
    6 * 5 + 4?
    Oder
    5 * 5 + 5?
    Oder noch etwas anderes?

    Bitte mit Begründung.



  • Hier mal ein wenig Text zum Thema Squenzpunkte
    http://manderc.manderby.com/operators/sequencepoints/index.php


Anmelden zum Antworten