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
jdevrait-il êtrejà 0?i++est faux, donc la conjonction&&est fausse et++jn'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
iest 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:
iest égal à 0, donci && ...n'est pas évalué, eti++n'est pas évalué, ou commenti++peut-il être 0 siiest 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 de1pouriaprè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 == 1sur la dernière ligne.Cela semble être une bonne raison de ne pas écrire de code comme celui-ci.