Inkrementieren - verwirrt





  • Ja, es kommt was raus, keien Frage.
    Aber der C++-Standard sagt darüber aus, dass es undefiniert ist.

    Dem Computer gefällt eine Antwort wie "undefiniert" nicht, das wissen auch viele (intelligente) Leute, daher haben die sich gedacht: "Ok, irgendwas msus da rauskommen" Und genau das Ergebnis siehst du bei dir mit der 185.

    Nimmst du aber jetzt einen anderen Compiler kommt was vielleicht anderes raus. Das bedeutet undefiniert, die Compilerhersteller legen fest, was wie wo passiert.

    Auf Deutsch bedeutet das, dass, wenn du guten Code schreiben willst, dich nicht darauf verlassen kannst, was da rauskommt. Schreib es sauber, dann ist das Ergebnis so wie du es willst/brauchst, und wzar auf jedem Rechner, Compiler und System.



  • Keiner schreibt so nen Quatsch außer er will hier mitmachen:

    The International Obfuscated C Code Contest

    http://www.ioccc.org/


  • Mod

    LinuxC_newbie schrieb:

    Also bei mir kommt da 185 heraus...

    Und bei mir 1128. Ist mein Computer kaputt?



  • 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
    


  • Und was ist mit einem Ausdruck wie

    int i = 5;
    int j = (++i) * (++i);
    

    ist das auch Quatsch?

    Edit: Ich habe eine kleine Bitte: Bitte bedenkt, dass ich kein Informatiker bin und mich nur im Rahmen meines Studiums so ein bisschen mit C++ befassen muss! Ich bin also absolut kein Experte und kann daher mit den meisten Tipps, die ihr mehr gebt, nicht sonderlich viel anfangen und muss ich auch gar nicht, was nicht bedeutet, dass es mich nicht interessiert.



  • LinuxC_newbie schrieb:

    int i = 5;
    int j = (++i) * (++i);
    

    ist das auch Quatsch?

    Mit ints ja, mit der Klasse von camper ist das Ergebnis eindeutig.



  • Also es geht um Folgendes:

    Um Präprozessor.

    Und wenn man da einen Ausdruck hat wie:

    #define QUADRAT(a) ((a)*(a))
    
    ...
    
    int Zahl = 5;
    Wert = QUADRAT(++Zahl);
    

    So hat die Variable Wert zum Schluss den Inhalt 49, weil berechnet wird:

    ((++Zahl)*(++Zahl))

    [Das habe ich aus dem Buch "Einstieg in C++" von A. Willemer.]

    Wieso kommt da 49 heraus?



  • Es ist undefiniertes Verhalten!
    Das wurde doch jetzt schon mehrfach gesagt.

    Lies dazu auch den Wiki-Artikel der hier verlingt wurde.


  • Mod

    LinuxC_newbie schrieb:

    [Das habe ich aus dem Buch "Einstieg in C++" von A. Willemer.]

    Ein guter Grund, das Buch sofort wegzuwerfen, wenn das da wirklich so steht.



  • 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.



  • LinuxC_newbie schrieb:

    Das habe ich aus dem Buch "Einstieg in C++" von A. Willemer.

    Gut zu wissen. Das Buch ist demnach nicht zu empfehlen.

    LinuxC_newbie schrieb:

    Wieso kommt da 49 heraus?

    Dabei muss nicht 49 herauskommen. Das Ergebnis ist undefiniert. Es kann also auch etwas anderes herauskommen. Die Frage nach dem "wieso" ist sinnlos.


  • Mod



  • SeppJ schrieb:

    Ein guter Grund, das Buch sofort wegzuwerfen, wenn das da wirklich so steht.

    Nix da!

    @TE: Bewahre das Buch bis zum nächsten Winter auf, werfe es anschließend in den Kamin und wärm' Dir dabei die Füße.
    Wir wollen ja schließlich nicht verschwenderisch werden.


  • 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.


Anmelden zum Antworten