Kompletter anfänger hat eine Frage



  • Ich lerne grad (oder versuche es) c++ mit dem buch "Der c++ Programmierer" und dort war ein Beispiel für die if- anweisung

    int i = 0, j = 2;
    if(i++ || j++) i++;
    

    Warum kommt am ende i = 2 raus ?
    In dem buch steht das das ein Seiteneffekt ist, aber warum passiert das?
    Was ich mir gedacht hab aber ich komisch finde ist:

    1. i und j werden festgellegt
    2. if kann nicht erfüllt werden und nimmt das i++ und führt es aus.
    3. if zeile wird wiederholt und NOCHMAL i++ ausgeführt.

    Ist das so? oder warum geschieht das?



  • Griffn schrieb:

    2. if kann nicht erfüllt werden und nimmt das i++ und führt es aus.

    Wieso kann das if nicht erfüllt werden? Oder korrekter formuliert: warum glaubst du, dass der Ausdruck im if 0 ergibt?



  • Ich verstehe das so

    "wenn i++ gemacht wird oder j++ gemacht wird mache i++"
    Aber es wurde doch nicht gemacht?



  • Griffn schrieb:

    Ich verstehe das so

    "wenn i++ gemacht wird oder j++ gemacht wird >> mache i++"
    Aber es wurde doch nicht gemacht?

    so ist besser



  • Griffn schrieb:

    Ich verstehe das so

    "wenn i++ gemacht wird oder j++ gemacht wird mache i++"
    Aber es wurde doch nicht gemacht?

    Lies nochmal dein Buch oder wirf es deinem Prof an den Kopf, wenn er es dir nicht korrekt beigebracht hat.

    Im if steht:
    1. Prüfe, ob i gesetzt, also ungleich 0 ist. Inkrementiere i in jedem Fall, nachdem du geprüft hast.
    2. i ist zu diesem Zeitpunkt nicht gesetzt, also wird j geprüft, und auch das inkrementiert. Aber i hat in jedem Fall schon mal den Wert 1.
    3 j ist jetzt gesetzt (2), und daher ist die Bedingung des if s erfüllt und i wird noch mal inkrementiert. Und dann hat i den Wert 2.

    || ist OR, nicht AND, das wäre &&. Nur für den Fall, dass du die Operatoren verwechselst.



  • Vielleicht solltest du dir das auch anders denken.

    Nicht: "Wenn XY gemacht wird"
    Sondern: "Wenn XY wahr ist".

    Es wird also überprüft, ob i++ wahr ist. i++ erhöht i um 1 (i ist also nun von 0 auf 1 erhöht) und gibt den Wert von i VOR der Erhöhung zurück (0), also false. Demnach muss auch noch j++ überprüft werden. j++ erhöht j um 1 (also ist j nun 3) und gibt danach den vorherigen Wert von j, also 2, zurück. 2 ist im Wahrheitskontext "true" (alles ungleich 0 ist true) und somit wird das i++ ausgeführt.

    Klar?

    Dann hätte ich eine Folgefrage für dich:
    welchen Wert haben i und j, wenn das if stattdessen lautet:

    if (++i || ++j) ++i;
    


  • Ich habe vor 2-3 im imformatikkurz gelernt das es heißt wenn > dann
    Und ich glaube das haut mich hier ausm kontext raus

    Hab ich das jetzt richtig verstanden das if i++ nicht wahr ist wird i++ gemacht das gleiche für j++ und dann nochmal i++ weil es am ende steht?

    oder was ich mir grade beim nochmaligen durchlesens gedacht hab, ist es vieleicht so das er i++ ausführt wenn beides unwahr ist? dann würde beides hinkommen glaube ich oO. Sry das ist wahrscheinlich ein ganz dummes thema... aber ich blick bei diesem thema nicht durch



  • Griffn schrieb:

    Ich habe vor 2-3 im imformatikkurz gelernt das es heißt wenn > dann

    Wo bei if hört wenn auf und fängt dann an?
    Woraus besteht in deinem Beispiel wenn?
    Welchen Wert hat es?



  • Griffn schrieb:

    int i = 0, j = 2;
    if(i++ || j++) i++;
    

    Setz mal i auf 1 statt 0 und dann achte darauf was mit j passiert. Komisch, oder?



  • Griffn schrieb:

    Ich habe vor 2-3 im imformatikkurz gelernt das es heißt wenn > dann

    if (...) heißt, "wenn der ausdruck in der klammer wahr ist".

    "wahr" heißt true, also ein boolscher ausdruck. ein integer kann in ein bool umgewandelt werden, folgende regel gilt: jede zahl außer 0 ist true, 0 selbst ist false.

    der ausdruck "i++" liefert dir, je nachdem, welchen wert die variable vorher hatte, entweder 0 oder eine andere zahl. ++ als postinkrementoperator hat allerdings den *nebeneffekt*, nach dem liefern eines ergebnisses eines ausdrucks, in dem er verwendet wird, den wert der variablen zu erhöhen.

    int i = 0;
    bool j = bool{i++}; //i war 0, also liefert der ausdruck i++ 0, also ist bool j = false. i wird erst danach inkrementiert
    
    int x = 5;
    bool y = bool{x++}; //y = true
    

    bei den boolschen operatoren and und or (&& und ||) kommt noch die regel dazu, dass der zweite operand nur dann ausgewertet wird, wenn der erste falsch (||) bzw. wahr (&&) ist. nur, wenn ein ausdruck ausgewertet wird, bewirkt er auch nebeneffekte.

    int i = 0;
    if (i++ || anderer_ausdruck) { foo(); }
    

    lies: werte den ausdruck "i++" aus. falls er wahr ist, rufe foo aus. andernfalls werte den ausdruck "anderer_ausdruck" aus. falls er wahr ist, rufe rufe auf.

    jedesmal, wenn du liest "werte ... aus" heißt das: "werte ... aus" und führe alle nebeneffekte aus. was bei einer auswertung von i++, falls i = 0, passiert, steht oben.



  • In den Klammern nach dem if steht eine (logische) Bedingung die kann unwahr oder wahr sein

    In C wird 0 als UNWAHR oder FALSCH angesehen. alles andere ist WAHR .

    Du hast eine ODER-Verknüpfung ||.
    Die ist dann wahr, wenn einer der Operanden wahr ist. Die Auswertung erfolgt von links nach rechts.

    i = 0; j = 2;
    (i++ || j++)
    Du hast da erstmal i++. Da i 0 ist, ist das unwahr.
    Jetzt wird j++ geprüft. J ist 2, damit wahr. Also ist auch die ODER-Verknüpfung wahr.
    Spätestens jetzt werd i und j inkrementiert (kann auch schon fürher sein)
    Dann ist i = 1 und j = 3.

    Da die Bedingung vom if wahr ergeben hat, wird der if-Zweig ausgeführt. i wird inkrementiert.
    Damit hat i jetzt den Wert 2.

    Das Ganze sieht aber bei (j++ || i++) anders aus.



  • manni66 schrieb:

    Griffn schrieb:

    Ich habe vor 2-3 im imformatikkurz gelernt das es heißt wenn > dann

    Wo bei if hört wenn auf und fängt dann an?
    Woraus besteht in deinem Beispiel wenn?
    Welchen Wert hat es?

    Ich verstehe es so.
    1. Ab in der Klammer oder? also wenn ( das das und wahr ist )
    2. Wenn i++ wahr ist ODER j++ wahr ist
    3. i++ ist i um 1 erhöht also 1, also 1?



  • Griffn schrieb:

    Ich verstehe es so.
    1. Ab in der Klammer oder? also wenn ( das das und wahr ist )
    2. Wenn i++ wahr ist ODER j++ wahr ist

    ja.
    i++ ist dann wahr, wenn vor dieser anweisung i != 0 ist.

    3. i++ ist i um 1 erhöht also 1, also 1?

    nein, i++ heißt: der wert ist "i". ++ wird erst "später" (sozusagen "nach der klammer") ausgeführt.



  • Zu 3.
    i++ ist das Postinkrement.
    Der Wert von i wird für die weitere Berechnung genommen, bevor i erhöht wird.
    Also der aktuelle Wert.

    Das Preinkrement wäre ++i.



  • if (i++ || j++)
            i++;
    

    Davon abgesehen, würde keiner sowas coden.
    Eher dann so:

    if (i || j)
        {
            if (!i)
                j++;
            i++;
        }
        else
            j++;
        i++;
    

    Verhält sich wie (vermutlich) gewünscht. Sieht schlimmer aus, aber ist wenigstens deterministisch.



  • DirkB schrieb:

    Zu 3.
    i++ ist das Postinkrement.
    Der Wert von i wird für die weitere Berechnung genommen, bevor i erhöht wird.
    Also der aktuelle Wert.

    Das Preinkrement wäre ++i.

    Gut, das wusste ich nicht, aber ich verstehe immernoch nicht warum das ergebnis rauskommt

    also if ( i++ || j++ ) i++;
    heißt also wenn ich alles was ich jetzt weiß einbeziehe
    Von links nach rechts

    i++ ist unwahr also nix || j++ ist doch auch unwahr ?!?
    vieleicht blockt mir da was anderes vor undzwar

    1. i++ = postinkrement heißt also wird nach der aufgabe berechnet, aber wie wird das gehandhabt? Schließlich verstehe ich nicht wie das programm nachprüfen soll ob es schonmal erhört worden ist.
    2. Hier im buch ist die abbildung für if so :
    if -> ( BEDINGUNG ) > Anweisung oder Block ->
    Natürlich noch mit else aber das wird hier aber nicht gebraucht schätze ich.
    Nach der abbildung heißt es für mich das keine bedingung in der klammer erfühlt wurde also theroetisch nix mit den zahlen passieren sollte oder?

    Ist vieleicht viel verlangt aber kann mir das einer "wördlich" erklären nach dem motto schrittweise wie eine anweisung (1. er prüfft das 2. dann das 3. dann macht er das...)?



  • Griffn schrieb:

    i++ ist unwahr also nix || j++ ist doch auch unwahr ?!?

    Was ist denn für dich nix?
    Wie ist die Wahrheitstabelle für ODER?
    Welchen Wert hat j?

    Griffn schrieb:

    Ist vieleicht viel verlangt aber kann mir das einer "wördlich" erklären nach dem motto schrittweise wie eine anweisung (1. er prüfft das 2. dann das 3. dann macht er das...)?

    Habe ich doch schon gemacht (oke ohne 1. 2. 3., aber das kannst du dir vor jeder ZEile denken):

    DirkB schrieb:

    Du hast eine ODER-Verknüpfung ||.
    Die ist dann wahr, wenn einer der Operanden wahr ist. Die Auswertung erfolgt von links nach rechts.

    i = 0; j = 2;
    (i++ || j++)
    Du hast da erstmal i++. Da i 0 ist, ist das unwahr.
    Jetzt wird j++ geprüft. j ist 2, damit wahr. Also ist auch die ODER-Verknüpfung wahr.
    Spätestens jetzt werden i und j inkrementiert (kann auch schon früher sein)
    Dann ist i = 1 und j = 3.

    Da die Bedingung vom if wahr ergeben hat, wird der if-Zweig ausgeführt. i wird inkrementiert.
    Damit hat i jetzt den Wert 2.

    Das Ganze sieht aber bei (j++ || i++) anders aus.

    Griffn schrieb:

    Schließlich verstehe ich nicht wie das programm nachprüfen soll ob es schonmal erhört worden ist.

    Das braucht es nicht prüfen,das wird gemacht. Es gibt Prozessoren, die machen das in einem Befehl.



  • DirkB schrieb:

    Griffn schrieb:

    i++ ist unwahr also nix || j++ ist doch auch unwahr ?!?

    Was ist denn für dich nix?
    Wie ist die Wahrheitstabelle für ODER?
    Welchen Wert hat j?

    Griffn schrieb:

    Ist vieleicht viel verlangt aber kann mir das einer "wördlich" erklären nach dem motto schrittweise wie eine anweisung (1. er prüfft das 2. dann das 3. dann macht er das...)?

    Habe ich doch schon gemacht (oke ohne 1. 2. 3., aber das kannst du dir vor jeder ZEile denken):

    DirkB schrieb:

    Du hast eine ODER-Verknüpfung ||.
    Die ist dann wahr, wenn einer der Operanden wahr ist. Die Auswertung erfolgt von links nach rechts.

    i = 0; j = 2;
    (i++ || j++)
    Du hast da erstmal i++. Da i 0 ist, ist das unwahr.
    Jetzt wird j++ geprüft. j ist 2, damit wahr. Also ist auch die ODER-Verknüpfung wahr.
    Spätestens jetzt werden i und j inkrementiert (kann auch schon früher sein)
    Dann ist i = 1 und j = 3.

    Da die Bedingung vom if wahr ergeben hat, wird der if-Zweig ausgeführt. i wird inkrementiert.
    Damit hat i jetzt den Wert 2.

    Das Ganze sieht aber bei (j++ || i++) anders aus.

    Griffn schrieb:

    Schließlich verstehe ich nicht wie das programm nachprüfen soll ob es schonmal erhört worden ist.

    Das braucht es nicht prüfen,das wird gemacht. Es gibt Prozessoren, die machen das in einem Befehl.

    Nix = Unwahr
    Wenn a oder b wahr ist wird ausgeführt
    j hat den wert 2

    Warum ist j denn Wahr? es wurde doch nicht erhöht?



  • Griffn schrieb:

    Warum ist j denn Wahr? es wurde doch nicht erhöht?

    Wenn j einen Wert !=0 hat, ist j "wahr". Das ist halt in C so festgelegt.



  • Also praktisch wird überhaubt nicht gefragt ob i oder j erhöht wurden sondern ob sie 0 < also wahr sind? das würde es erklähren. Jetzt bleibt für mich nurnoch offen warum i 2 mal erhöht wurde, kann es sein das die bedingung 2 mal gecheckt wird falls etwas geregelt wurde?

    also?:

    1
    if ( i++ || j++ ) i++;
    false true
    i++ wird ausgeführt
    2. if ( i++ || j++ ) i++;
    true
    da i ja erhöht wurde und somit true ist
    i++ wird ausgeführt

    stimmt das so?


Log in to reply