Que se passe-t-il (derrière les rideaux) lorsque cela est exécuté?
int x = 7;
x = x++;
Autrement dit, lorsqu'une variable est post-incrémentée et affectée à elle-même dans une seule instruction? J'ai compilé et exécuté cela. x
est toujours 7 même après la déclaration entière . Dans mon livre, il est dit que x
c'est incrémenté!
java
operators
post-increment
Michael
la source
la source
int x = 7; x = ++x;
bien sûr, le code est toujours horrible, vous n'avez pas besoin de le réaffecter.int x = 7; x++;
est assez.x += 1
, sauf peut-être en boucles.for(int x=0; x<7; x++)
Réponses:
x
est incrémenté. Mais vous attribuez l'ancienne valeur dex
retour en soi.x++
incrémentsx
et renvoie son ancienne valeur.x =
assigne l'ancienne valeur à lui-même.Donc à la fin,
x
revient à sa valeur initiale.la source
x
est incrémenté en premier avant d'être lu dans ce cas, donc vous vous retrouvez avecx + 1
.est équivalent à
la source
x=x+1
place dex++
x = x++
, pas seulement l'incrément de publicationx++
.x = ++x;
est également équivalent àint tmp = x; ++x; x = tmp;
, alors par quelle logique peut-on en déduire que votre réponse est correcte (quelle est-elle)?x=x++
=MOV x,tmp; INC x; MOV tmp,x
La déclaration:
est équivalent à:
Bref, la déclaration n'a aucun effet.
Les points clés:
La valeur d'une expression d'incrémentation / décrémentation de Postfix est la valeur de l'opérande avant que l'incrémentation / décrémentation n'ait lieu. (Dans le cas d'un formulaire Prefix, la valeur est la valeur de l'opérande après l'opération,)
le RHS d'une expression d'affectation est complètement évalué (y compris tous les incréments, décréments et / ou autres effets secondaires) avant que la valeur ne soit affectée au LHS.
Notez que contrairement à C et C ++, l'ordre d'évaluation d'une expression en Java est totalement spécifié et il n'y a pas de place pour une variation spécifique à la plate-forme. Les compilateurs ne sont autorisés à réorganiser les opérations que si cela ne change pas le résultat de l'exécution du code du point de vue du thread actuel. Dans ce cas, un compilateur serait autorisé à optimiser l'intégralité de l'instruction car il peut être prouvé qu'il s'agit d'un no-op.
Au cas où ce n'est pas déjà évident:
Espérons que les vérificateurs de code comme FindBugs et PMD signaleront ce code comme suspect.
la source
x++
au lieu dex = x++
.Il a un comportement indéfini en C et pour Java voir cette réponse . Cela dépend du compilateur ce qui se passe.
la source
Une construction comme
x = x++;
indique que vous comprenez probablement mal ce que fait l'++
opérateur:Réécrivons ceci pour faire la même chose, basé sur la suppression de l'
++
opérateur:Maintenant, réécrivons-le pour faire (ce que je pense) que vous vouliez:
La subtilité ici est que l'
++
opérateur modifie la variablex
, contrairement à une expression telle quex + x
, qui évaluerait une valeur int mais laisserait la variablex
elle-même inchangée. Considérons une construction comme lafor
boucle vénérable :Remarquez le
i++
dedans? C'est le même opérateur. Nous pourrions réécrire cettefor
boucle comme ceci et elle se comporterait de la même manière:Je déconseille également d'utiliser l'
++
opérateur dans des expressions plus grandes dans la plupart des cas. En raison de la subtilité du moment où il modifie la variable d'origine avant et après l'incrémentation (++x
etx++
respectivement), il est très facile d'introduire des bogues subtils difficiles à localiser.la source
Selon le code d'octet obtenu à partir des fichiers de classe,
Les deux affectations incrémentent x, mais la différence est le moment de
when the value is pushed onto the stack
Dans
Case1
, Push se produit (puis est ensuite attribué) avant l'incrément (ce qui signifie essentiellement que votre incrément ne fait rien)Dans
Case2
, l'incrémentation se produit d'abord (ce qui en fait 8) puis poussé sur la pile (puis affecté à x)Cas 1:
Code d'octet:
Cas 2:
Code d'octet
la source
Il est incrémenté après "
x = x++;
". Ce serait 8 si vous faisiez "x = ++x;
".la source
x = x++
, il devrait être de 8.L'opérateur Post Increment fonctionne comme suit:
Donc, la déclaration
serait évalué comme suit:
Donc x est en effet augmenté mais comme x ++ assigne le résultat à x, la valeur de x est remplacée par sa valeur précédente.
la source
L'incrémentation se produit après l'appel de x, donc x est toujours égal à 7. ++ x serait égal à 8 lorsque x est appelé
la source
Lorsque vous réattribuez la valeur,
x
elle est toujours de 7. Essayezx = ++x
et vous obtiendrez 8 autres chosesla source
car x ++ incrémente la valeur APRÈS l'affectation à la variable. ainsi de suite et pendant l'exécution de cette ligne:
le varialbe x aura toujours la valeur d'origine (7), mais en utilisant à nouveau x sur une autre ligne, comme
vous donnera 8.
si vous souhaitez utiliser une valeur incrémentée de x dans votre instruction d'affectation, utilisez
Cela incrémentera x de 1, PUIS attribuez cette valeur à la variable x.
[Modifier] au lieu de x = x ++, c'est juste x ++; l'ancien attribue la valeur d'origine de x à lui-même, donc il ne fait rien sur cette ligne.
la source
Ce qu'il se passe quand
int x = 7; x = x++;
?ans ->
x++
signifie d'abord utiliser la valeur de x pour l'expression, puis l'augmenter de 1.C'est ce qui se passe dans votre cas. La valeur de x sur RHS est copiée dans la variable x sur LHS, puis la valeur de
x
est augmentée de 1.De la même
++x
manière,->
augmenter d'abord la valeur de x de un, puis l'utiliser dans l'expression.Donc, dans votre cas, si vous le faites,
x = ++x ; // where x = 7
vous obtiendrez une valeur de 8.
Pour plus de clarté, essayez de savoir combien d'instructions printf exécuteront le code suivant
la source
x
8, mais c'est 7 - l'incrément se produit entre la lecture et l'affectation++x
est pré-incrémenté->
x est incrémenté avant d' être utiliséx++
est post-incrémenté->
x est incrémenté après avoir été utiliséla source
Cela signifie donc:
x++
n'est pas égal àx = x+1
car:
et maintenant ça semble un peu étrange:
très dépendant du compilateur!
la source
(x = x + 1, x-1)
en C, où les expressions séparées par des virgules sont autorisées.x = x ++;
Il s'agit de l'opérateur post-incrémentation. Il doit être compris comme "Utilisez la valeur de l'opérande puis incrémentez l'opérande".
Si vous souhaitez que l'inverse se produise, c'est-à-dire "Incrémenter l'opérande puis utiliser la valeur de l'opérande", vous devez utiliser l'opérateur de pré-incrémentation comme indiqué ci-dessous.
x = ++ x;
Cet opérateur incrémente d'abord la valeur de x de 1, puis attribue la valeur à x.
la source
Je pense que cette controverse peut être résolue sans entrer dans le code et juste penser.
Considérez i ++ et ++ i comme des fonctions, par exemple Func1 et Func2.
Maintenant i = 7;
Func1 (i ++) renvoie 7, Func2 (++ i) renvoie 8 (tout le monde le sait). En interne, les deux fonctions incrémentent i à 8, mais elles renvoient des valeurs différentes.
Donc i = i ++ appelle la fonction Func1. À l'intérieur de la fonction, i augmente jusqu'à 8, mais une fois terminée, la fonction renvoie 7.
Donc, finalement, 7 est alloué à i. (Donc au final, i = 7)
la source
En effet, vous avez utilisé un opérateur de post-incrémentation. Dans cette ligne de code suivante
Ce qui se passe, c'est que vous attribuez la valeur de x à x. x ++ incrémente x une fois que la valeur de x est affectée à x. C'est ainsi que fonctionnent les opérateurs post-incrémentation. Ils travaillent après l'exécution d'une déclaration. Ainsi, dans votre code, x est retourné d'abord après, puis il est ensuite incrémenté.
Si tu l'as fait
La réponse serait 8 car vous avez utilisé l'opérateur de pré-incrémentation. Cela incrémente la valeur avant de renvoyer la valeur de x.
la source