Die eigentliche Antwort lautet:
- Der Compiler gibt "i == 0" Vorrang , was als wahr ausgewertet wird.
- Dann wird i = 1 als TRUE oder FALSE ausgewertet, und da kompilierte Zuweisungsoperatoren niemals fehlschlagen (andernfalls würden sie nicht kompilieren), wird es auch als true ausgewertet.
- Da beide Anweisungen als wahr ausgewertet werden und TRUE && TRUE als TRUE ausgewertet wird, wird die if-Anweisung als TRUE ausgewertet.
Schauen Sie sich zum Beweis einfach die asm-Ausgabe Ihres Compilers für den von Ihnen eingegebenen Code an (alle Kommentare sind meine eigenen):
mov dword ptr [rbp - 8], 0 ; i = 0;
cmp dword ptr [rbp - 8], 0 ; i == 0?
sete al ; TRUE (=1)
mov cl, al
and cl, 1 ; = operator always TRUE
movzx edx, cl
mov dword ptr [rbp - 8], edx ; set i=TRUE;
test al, 1 ; al never changed,
; so final ans is TRUE
Die obige ASM-Ausgabe stammte von CLANG, aber alle anderen Compiler, die ich mir ansah, gaben eine ähnliche Ausgabe. Dies gilt für alle Compiler auf dieser Site, unabhängig davon, ob es sich um reine C- oder C ++ - Compiler handelt. Alle haben keine Pragmas, um den Modus des Compilers zu ändern (der für die C ++ - Compiler standardmäßig C ++ ist).
Beachten Sie, dass Ihr Compiler nicht i = 1 gesetzt hat, sondern i = TRUE (was bedeutet, dass jeder 32-Bit-Ganzzahlwert nicht Null ist). Dies liegt daran, dass der Operator && nur auswertet, ob eine Anweisung TRUE oder FALSE ist, und dann die Ergebnisse entsprechend diesem Ergebnis festlegt. Versuchen Sie als Beweis, i = 1 in i = 2 zu ändern, und Sie können selbst beobachten, dass sich nichts ändern wird. Überzeugen Sie sich selbst von einem beliebigen Online-Compiler im Compiler Explorer
i
ist1
.