Ich habe eine Frage, wie der Compiler mit folgendem Code arbeitet:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
Ich bin nicht sicher , warum das Ergebnis ist d = 11
.
Ich habe eine Frage, wie der Compiler mit folgendem Code arbeitet:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
Ich bin nicht sicher , warum das Ergebnis ist d = 11
.
Antworten:
In int d = (b == c++) ? (c+1) : (c-1);
:
c++
ist der aktuelle Wert von c
11. Separat c
wird auf 12 erhöht.b == 11
ist falsch, da b
ist 12.(b == c++)
ist falsch, (c-1)
wird verwendet. Außerdem muss das Inkrement von c
bis zu diesem Punkt abgeschlossen sein.c
ist 12, c-1
ist 11.d
wird auf diesen Wert initialisiert, 11.Gemäß dem C-Standard (6.5.15 Bedingter Operator)
4 Der erste Operand wird ausgewertet; Es gibt einen Sequenzpunkt zwischen seiner Auswertung und der Auswertung des zweiten oder dritten Operanden (je nachdem, welcher ausgewertet wird). Der zweite Operand wird nur ausgewertet, wenn der erste ungleich 0 ist; der dritte Operand wird nur ausgewertet, wenn der erste gleich 0 ist; Das Ergebnis ist der Wert des zweiten oder dritten Operanden (je nachdem, welcher Wert ausgewertet wird), konvertiert in den unten beschriebenen Typ.110)
Also im initialisierenden Ausdruck dieser Deklaration
int d = (b == c++) ? (c+1) : (c-1);
Die Variable b
wird mit dem Wert der Variablen verglichen, c
da der Operator nach dem Inkrementieren den Wert seines Operanden vor dem Inkrementieren zurückgibt.
Da die Werte nicht gleich sind ( b
wird auf 12 gesetzt, während c
auf 11 gesetzt wird), wird der Unterausdruck (c-1)
ausgewertet.
Nach dem Zitat gibt es einen Sequenzpunkt nach Bewertung des Zustands des Bedieners. Dies bedeutet, dass nach Auswertung der Bedingung c
der Wert 12
nach Anwenden des Post-Inkrement-Operators auf die Variable vorliegt c
. Infolgedessen wird die Variable d durch den Wert 1
( 12 - 1
) initialisiert .
?:
. Da normalerweise in C das Kombinieren ++
mit anderen Operationen mit demselben Operanden ein undefiniertes Verhalten ist. Und dieser Code funktioniert nur vorhersehbar, da er ?:
verschiedene spezielle Schneeflockenregeln hat.
Weil die Bedingung falsch ist, wird der false
Fall eintreten :, c-1
aber da Sie c
die Bedingung um erhöht haben c++
, c
ist dies jetzt der Fall 12
. Das Ergebnis ist also 12 - 1, was 11 ist.
EDIT: Was OP missverstanden hat, war das Post-Inkrement.
Was also tatsächlich passiert, ist folgender:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d;
if (b == c) { // 12 == 11 ? -> false
c = c + 1;
d = c + 1;
} else { // this executes since condition is false
c = c + 1; // post increment -> c++ -> c = 12 now
d = c - 1; // 12 - 1 = 11 -> d = 11
}
printf("d = %i\n", d);
}
c++
die Bedingung erfüllt ist. Die Bedingung ist falsch, aber dann wird der ursprüngliche Wert von c
zur Berechnung verwendet c - 1
, nicht die inkrementierte Version.
c++
und++c
c++
ist der Operator nach dem Inkrementieren. Der Wert von c++
ist 11, mit dem Nebeneffekt der Herstellung c == 12
. ++c
hätte den Wert 12.
Übersetzt in eine reguläre if-Anweisung würde Ihr Code folgendermaßen aussehen:
int b=12, c=11;
int d;
if (b == c++)
d = c+1;
else
d = c-1;
Der Hinweis hier ist, dass c erhöht wird, nachdem die Bedingung überprüft wurde. Sie geben also den else
Status ein, aber c hat dort bereits den Wert 12.
Siehe Ternary Operator.
Syntax
Bedingung ? value_if_true: value_if_false
Also hast du geschrieben
int d = (b == c++) ? (c+1) : (c-1);
In dieser Situation ist das Ergebnis 11, da nach Überprüfungen der 'c'-Wert erhöht wird (c + 1 = 12) und erst danach der' d'-Wert als c (12) -1 festgelegt wird, was 11 ist.
Wenn Sie zum Beispiel verwendet haben:
int d = (b == ++c) ? (c+1) : (c-1);
Der "c" -Wert würde vor dem Überprüfen der Anweisung erhöht, so dass er wahr wäre und der "d" -Wert c (12) +1 wäre, was 13 ist.