web-dev-qa-db-fra.com

Qu'est-ce que x après "x = x ++"?

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é!

271
Michael

x est incrémenté. Mais vous assignez l'ancienne valeur de x en elle-même.


x = x++;
  1. x++ incrémente x et renvoie son ancienne valeur.
  2. x = assigne l'ancienne valeur à elle-même.

Donc, à la fin, x est affecté à sa valeur initiale.

287
Mysticial
x = x++;

est équivalent à

int tmp = x;
x++;
x = tmp;
376
Prince John Wesley

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:

  • "x = x ++;" est presque certainement une erreur dans tout programme.
  • Le PO (pour la question originale!) Voulait probablement dire "x ++;" plutôt que "x = x ++;".
  • Les instructions combinant augmentation/décrémentation automatique et affectation d'une même variable sont difficiles à comprendre et donc doivent être évitées quelle que soit leur exactitude. Il n'y a tout simplement pas besoin d'écrire du code comme ça.

Espérons que des vérificateurs de code tels que FindBugs et PMD signaleront un code comme celui-ci comme suspect.

256
Stephen C
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.

33
user712092

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.

16
FMM

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
  • Stack fait ici référence à Operand Stack, local: x index: 1 type: int
13
Ravi Yenugu

C'est incrémenté après "x = x++; ". Ce serait 8 si vous le faisiez" x = ++x; ".

9
F.J

L'opérateur Post Increment fonctionne comme suit:

  1. Stocke la valeur précédente de l'opérande.
  2. Incrémente la valeur de l'opérande.
  3. Retourne la valeur précédente de l'opérande.

Donc la déclaration

int x = 7;
x = x++; 

serait évalué comme suit:

  1. x est initialisé avec la valeur 7
  2. l’opérateur post-incrémentation stocke la valeur précédente de x, à savoir 7, à renvoyer.
  3. Incrémente le x, si maintenant x est 8
  4. Retourne la valeur précédente de x, c'est-à-dire 7 et il est affecté à x, donc x redevient 7

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.

7
GauravLuthra

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é

7
JonPM

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
7
Vishal

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.

6
josephus

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
4
samprat

++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
3
Roberto Martelloni

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!

1
linuxeasy