Je comprends le concept de base du court-circuit avec les opérateurs, mais pourquoi
int i = 0, j = -1, k = 1, m; m = !(i++ && ++j) || ++k; printf("%d %d %d %d", i, j, k, m);
avoir 1 -1 1 1 comme sortie? Plus précisément, pourquoi j == -1 au lieu de 0?
Je sais que des questions similaires ont déjà été posées, mais je ne comprends pas cet exemple précis que je n'ai trouvé nulle part.
3 Réponses :
i = -1; i++; // value of expression is -1 // side effect is changing i to 0 if (i++) ; // value of `i++` is zero; the if will not "trigger" i = 0; if (i++ && foo) ; // i++ has value of zero (false) // so false && <anything> is false // so foo is not evaluated
Oui, je comprends maintenant. Merci
Je n'ai pas: pourquoi i
- i
égal à -1?
Je l'ai fait -1
pour l'exemple, pour ne pas avoir à le rendre 0
deux fois.
La valeur de l'opérateur d'incrémentation postfixe est la valeur de son opérande avant l'incrémentation.
La valeur de l'expression i ++ est donc égale à 0 car la variable i a été initialisée par 0.
Donc, comme la valeur de la sous-expression i++
est 0
alors la sous-expression ++j
dans cette expression
m = !(i++ && ++j) || ++k;
n'est pas évaluée et la valeur de l'expression elle-même est 0
.
Application de l'opérateur de négation
!(i++ && ++j) || ++k
vous obtiendrez 1
(vrai logique). Donc la sous-expression ++k
de l'expression
!(i++ && ++j)
ne sera pas évalué.
En conséquence, la valeur de l'expression entière est égale à 1
qui est affectée à la variable m
.
(i++ && ++j)
Par contre, comme il a été souligné au début, l'expression i++
été évaluée. Donc, après cette déclaration, i
serai égal à 1
.
int i = 0, j = -1, k = 1, m;
!(i++ && ++j) || ++k;
==> seul i++
sera évalué, j
et k
ne seront pas évalués
disons simplement que nous substituons les valeurs des variables, puis l'expression devient comme ci-dessous.
!(0 && ++ -1) || ++1
étape 1 !(0 && ++ -1)
==> pour l'opérateur &&
si l'opérande du côté gauche est faux alors nous n'avons pas besoin de vérifier l'opérande du côté droit, donc -1
ne sera pas incrémenté, donc la valeur de j
sera -1
lui-même.
et donc l'expression du côté gauche avant ||
devient !(0)
étape 2 !(0) || ++1
maintenant !(0)
sera 1, donc pour ||
opérateur si l'opérande du côté gauche est VRAI, alors pas besoin d'aller pour l'opérande du côté droit, alors ++k
ne sera pas exécuté.
m = 1 || ++1
==> 1
puisque seul i++
est évalué, il changera sa valeur en 1
donc la sortie est: 1 -1 1 1
Pourquoi
j
devrait-il êtrej
à 0?i++
est faux, donc la conjonction&&
est fausse et++j
n'est pas évalué.++ j est évalué comme -1 + 1 = 0? J'ai l'impression d'avoir fait une erreur évidente dans ma pensée
Le post-incrément
i++
renvoie la valeur d'origine de i (avant l'incrément) qui est zéro. Ainsi, la partie après&&
n'est pas évaluée (à cause d'un raccourci).@dxiv: vous voulez dire que
i
est faux, donci && ...
n'est pas évalué, et ainsi de suite.oh jésus, je me sens si stupide maintenant. Je regardais ce problème pendant environ 10 minutes sans me rendre compte que j'avais évalué i ++ comme ++ i dans ma tête. Edit: suppose que je suis fatigué comme l'enfer, hein
@DavidIlic: pouvez-vous compiler ceci en code ASM, pour que nous puissions y jeter un coup d'œil?
@Dominique Je voulais dire l'expression
i++
qui vaut0
.Merci les gars, je comprends ce qui se passe maintenant. J'ai fait une erreur dans ma tête
@dxiv:
i
est égal à 0, donci && ...
n'est pas évalué, eti++
n'est pas évalué, ou commenti++
peut-il être 0 sii
est 0?@Dominique Bien sûr,
i++
est évalué, comment le compilateur pourrait-il déterminer autrement la valeur de la conjonction. Ceci est cohérent avec la valeur de OP de1
pouri
après l'évaluation.@dxiv: dans sa réponse, Pmg déclare que
i = -1
, d'où cela vient-il?@Dominique Cela a été utilisé comme exemple dans la réponse de pmg. Le message d'OP montre
i == 1
sur la dernière ligne.Cela semble être une bonne raison de ne pas écrire de code comme celui-ci.