307 votes

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

Que se passe-t-il (derrière les rideaux) quand cela 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 déclaration? J'ai compilé et exécuté ceci. x est toujours 7 même après la déclaration entière . Dans mon livre, il est dit que x est incrémenté!

396voto

Prince John Wesley Points 22418
 x = x++;
 

est équivalent à

 int tmp = x;
x++;
x = tmp;
 

328voto

Mysticial Points 180300

obtenir incrémenté. Mais vous assignez l’ancienne valeur de dans lui-même.

tranches de et retourne sa valeur ancienne. `` assigne l’ancienne valeur sur elle-même.

Donc en fin de compte, `` est affectée à sa valeur initiale.

263voto

Stephen C Points 255558

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, l'instruction n'a pas d'effet.

Les points clés:

  • La valeur d'un Postfix augmentation/diminution de l'expression est la valeur de l'opérande avant l'incrémentation/décrémentation. (Dans le cas d'un Préfixe, la valeur est la valeur de l'opérande après l'opération,)

  • le membre de droite d'une expression d'affectation est complètement évalués (y compris toute des augmentations, diminutions et/ou d'autres effets secondaires) avant la valeur est affectée à la LHS.

Notez qu'à la différence de C et de C++, de l'ordre de l'évaluation d'une expression en Java est totalement déterminé et il n'y a pas de place pour la plate-forme spécifique de variation. Les compilateurs ne sont autorisés à réorganiser les opérations si cela ne change pas le résultat de l'exécution du code à partir de la perspective de le thread courant. Dans ce cas, un compilateur serait autorisée à optimiser loin l'ensemble de l'instruction, car il peut être prouvé que c'est un no-op.


Dans le cas où il n'est pas déjà évident:

  • "x = x++;" est presque certainement une erreur dans un programme.
  • L'OP (pour la question d'origine!) signifiait probablement "x++;" plutôt que "x = x++;".
  • Des déclarations qui combinent auto incrémentation/décrémentation et d'affectation sur la même variable sont difficiles à comprendre, et par conséquent devrait être évitée , indépendamment de leur exactitude. Il n'y a pas besoin d'écrire du code comme ça.

Heureusement, code pions comme FindBugs et PMD marquera le code comme ceci comme suspect.

32voto

user712092 Points 789
<pre><code></code><p><a href="http://c-faq.com/expr/ieqiplusplus.html">Il a un indéfini comportement en C</a> <a href="http://stackoverflow.com/questions/6457130/pre-post-increment-operator-behavior-in-c-c-java-c-sharp">cette réponse</a>. Cela dépend du compilateur, ce qui se passe.</p></pre>

16voto

FMM Points 2201

Une construction comme x = x++; indique que vous êtes probablement à l'incompréhension de ce que l' ++ opérateur:

// original code
int x = 7;
x = x++;

Réécrivons cette de faire la même chose, basée sur la suppression de l' ++ 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, nous allons réécrire à faire (ce que je pense) que tu voulais:

// original code
int x = 7;
x++;

La subtilité ici, c'est que l' ++ de l'opérateur modifie la variable x, contrairement à une expression telle que x + x, ce qui devrait correspondre à une valeur int mais laisser la variable x lui-même inchangé. Envisager une construction, comme le vénérable for boucle:

for(int i = 0; i < 10; i++)
{
    System.out.println(i);
}

Avis de l' i++ il? C'est le même opérateur. Nous pourrions réécrire cette for boucle de ce genre et il se comporterait de la même:

for(int i = 0; i < 10; i = i + 1)
{
    System.out.println(i);
}

Je recommande également contre l'utilisation de l' ++ de l'opérateur dans les grandes expressions dans la plupart des cas. En raison de la subtilité de quand il modifie la variable d'origine dans le pré - rapport à la post-incrémentation (++x et x++, respectivement), il est très facile d'introduire des bogues subtils qui sont difficiles à repérer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X