Que se passe-t-il (derrière les rideaux) quand ceci est exécuté?
int x = 7;
x = x++;
C'est-à-dire, quand une variable est post incrémentée et assignée à elle-même dans une seule déclaration? J'ai compilé et exécuté ceci. x
est toujours 7 même après la déclaration complète. Dans mon livre, il est écrit que x
est incrémenté!
x
est incrémenté. Mais vous assignez l'ancienne valeur de x
en elle-même.
x = x++;
x++
incrémente x
et renvoie son ancienne valeur.x =
assigne l'ancienne valeur à elle-même.Donc, à la fin, x
est affecté à sa valeur initiale.
x = x++;
est équivalent à
int tmp = x;
x++;
x = tmp;
La déclaration:
x = x++;
est équivalent à:
tmp = x; // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
// happens after the value is captured.
x = tmp; // ... this is the effect of assignment operation which is
// (unfortunately) clobbering the incremented value.
En bref, la déclaration n'a aucun effet.
Les points clés:
La valeur d'une expression d'incrément/décrément de Postfix est la valeur de l'opérande before l'incrément/décrément a lieu. (Dans le cas d'une forme de préfixe, 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 les incréments, les diminutions et/ou les autres effets secondaires) avant la valeur est affectée au LHS.
Notez que contrairement à C et C++, l'ordre d'évaluation d'une expression dans Java est totalement spécifié et qu'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 se produit. ne changez pas le résultat de l'exécution du code du point de vue du thread en cours 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 des vérificateurs de code tels que FindBugs et PMD signaleront un code comme celui-ci comme suspect.
int x = 7;
x = x++;
Il a un comportement indéfini en C et pour Java voir cette réponse . Cela dépend du compilateur.
Une construction comme x = x++;
indique que vous ne comprenez probablement pas ce que le ++
l'opérateur fait:
// original code
int x = 7;
x = x++;
Réécrivons cela pour faire la même chose, en supprimant le ++
opérateur:
// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7
Maintenant, réécrivons-le pour faire (ce que je pense) ce que vous vouliez:
// original code
int x = 7;
x++;
La subtilité ici est que le ++
opérateur modifie la variable x
, contrairement à une expression telle que x + x
, ce qui donnerait une valeur int mais laisserait la variable x
elle-même inchangée. Considérons une construction comme la vénérable boucle for
:
for(int i = 0; i < 10; i++)
{
System.out.println(i);
}
Remarquez le i++
dedans là? C'est le même opérateur. Nous pourrions réécrire cette boucle for
comme ceci et elle se comporterait de la même façon:
for(int i = 0; i < 10; i = i + 1)
{
System.out.println(i);
}
Je recommande également de ne pas utiliser le ++
opérateur dans des expressions plus grandes dans la plupart des cas. En raison de la subtilité de lorsque , la variable d'origine est modifiée en pré-incrémentation après incrémentation (++x
et x++
, respectivement), il est très facile d’introduire des bugs subtils difficiles à détecter.
Selon le code Byte obtenu à partir des fichiers de classe,
Les deux assignations incrémentent x, mais la différence est le minutage de when the value is pushed onto the stack
Dans Case1
, Push se produit (puis est affecté ultérieurement) avant l'incrément (ce qui signifie essentiellement que votre incrément ne fait rien)
Dans Case2
, Incrément se produit d’abord (ce qui fait 8) et ensuite poussé sur la pile (puis assigné à x)
Cas 1:
int x=7;
x=x++;
Code d'octet:
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iload_1 [x] //Push 7 onto stack
4 iinc 1 1 [x] //Increment x by 1 (x=8)
7 istore_1 [x] //Pop 7 and store in x
8 return //x now has 7
Cas 2:
int x=7;
x=++x;
Code d'octet
0 bipush 7 //Push 7 onto stack
2 istore_1 [x] //Pop 7 and store in x
3 iinc 1 1 [x] //Increment x by 1 (x=8)
6 iload_1 [x] //Push x onto stack
7 istore_1 [x] //Pop 8 and store in x
8 return //x now has 8
C'est incrémenté après "x = x++;
". Ce serait 8 si vous le faisiez" x = ++x;
".
L'opérateur Post Increment fonctionne comme suit:
Donc la déclaration
int x = 7;
x = x++;
serait évalué comme suit:
Donc, x est effectivement augmenté, mais puisque x ++ assigne le résultat à x, la valeur de x est remplacée par la valeur précédente.
L'incrémentation se produit après l'appel de x, x étant donc toujours égal à 7. ++ x étant égal à 8 lorsque x est appelé
Lorsque vous réaffectez la valeur pour x
, il reste 7. Essayez x = ++x
et vous aurez 8 autres faire
x++; // don't re-assign, just increment
System.out.println(x); // prints 8
car x ++ incrémente la valeur APRÈS l’affecter à la variable. ainsi de suite et lors de l'exécution de cette ligne:
x++;
la varialbe x aura toujours la valeur d'origine (7), mais vous utiliserez à nouveau x sur une autre ligne, telle que
System.out.println(x + "");
vous donnera 8.
si vous souhaitez utiliser une valeur incrémentée de x dans votre instruction d'affectation, utilisez
++x;
Cela incrémentera x de 1, ALORS assignera cette valeur à la variable x.
[Edit] au lieu de x = x ++, c'est juste x ++; la première attribue la valeur initiale de x à elle-même, elle ne fait donc rien sur cette ligne.
Ce qu'il se passe quand int x = 7; x = x++;
?
ans -> x++
signifie la première valeur d’utilisation de x pour expression, puis l’augmente 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 même ++x
veux dire ->
augmente d'abord la valeur de x de un, puis utilise l'expression.
Donc, dans votre cas, si vous 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.
while(i++ <5)
printf("%d" , ++i); // This might clear your concept upto great extend
++x
est pré-incrémenté ->
x est incrémenté avant utiliséx++
est post-incrémenté ->
x est incrémenté après utilisé
int x = 7; -> x get 7 value <br>
x = x++; -> x get x value AND only then x is incremented
Donc, cela signifie: x++
n'est pas égal à x = x+1
parce que:
int x = 7; x = x++;
x is 7
int x = 7; x = x = x+1;
x is 8
et maintenant cela semble un peu étrange:
int x = 7; x = x+=1;
x is 8
très dépendant du compilateur!