45 votes

a = (a++) * (a++) donne des résultats étranges dans Java

Je fais les études pour la OCPJP examen, et donc, je dois comprendre chaque petit détail étrange de Java. Cela comprend l'ordre dans lequel les pré - et post-incrémentation opérateurs s'appliquent à des variables. Le code suivant est de me donner des résultats étranges:

int a = 3;

a = (a++) * (a++);

System.out.println(a); // 12

Ne pas la réponse, est de 11? Ou peut-être de 13 ans? Mais pas 12!

SUIVI:

Quel est le résultat le code suivant?

int a = 3;

a += (a++) * (a++);

System.out.println(a);

110voto

Bozho Points 273663

Après la première a++ a devient 4. Vous avez donc 3 * 4 = 12.

(a devient 5 après le 2 a++, mais qui est mis au rebut, parce que la cession a = le remplace)

31voto

Rok Kralj Points 11593

Je vais répondre à votre question de suivi. Let's get étape par étape, comme Java évalue l'énoncé:

a += (a++) * (a++);
  1. Depuis a += b "est l'abréviation de a = a + b, l'énoncé devient:

    a = a + (a++) * (a++);

  2. a = 3 se substituer à la première en additionnant:

    a = 3 + (a++) * (a++);

  3. a = 3 se substituer au premier facteur, la valeur de a est augmenté de a = 4.

    a = 3 + 3 * (a++);

  4. a = 4 se substituer au deuxième facteur, la valeur de a est augmenté de a = 5.

    a = 3 + 3 * 4;

a obtient la valeur de 15.

Dans la pratique, vous devriez éviter de telles déclarations et de le transformer en simple, de forme équivalente, comme l'un de ces:

a = a*a + 2*a
a = a*(a+2)
a += a*(a+1)

25voto

thecoop Points 23695

a++ signifie 'la valeur de a, et a est alors incrémenté de 1'. Ainsi, lorsque vous exécutez

(a++) * (a++)

la première a++ est évalué en premier, et produit de la valeur 3. a est ensuite incrémenté de 1. Le deuxième a++ , est ensuite évaluée. a produit la valeur de 4, et est ensuite incrémenté de nouveau (mais ce n'est pas grave maintenant)

Donc, ce qui se transforme en

a = 3 * 4

qui est égal à 12.

9voto

CodesInChaos Points 60274
int a = 3;
a += (a++) * (a++);

D'abord construire l'arbre de syntaxe:

+=
  a
  *
    a++
    a++

Pour l'évaluation de commencer avec la plus externe de l'élément et la descente récursive. Pour chaque élément:

  • Évaluer les enfants à partir de la gauche vers la droite
  • Évaluer l'élément lui-même

L' += opérateur est spécial: Il est étendu à quelque chose comme left = left + right, mais seulement l'évaluation de l'expression left une fois. Toujours du côté gauche obtient évalué à une valeur(et pas seulement une variable) avant le côté droit devient évalué à une valeur.

Cela conduit à:

  1. Commencer à évaluer +=
  2. Évaluer côté gauche de l'affectation à la variable a.
  3. Évaluer la variable a de la valeur 3 qui sera utilisé dans l'addition.
  4. Commencer à évaluer *
  5. L'évaluation de la première a++. Ce retourne la valeur courante de 3 et définit a de 4
  6. Évaluer le second a++. Ce retourne la valeur courante de 4 et définit a de 5
  7. Calculer le produit: 3*4 = 12
  8. Exécuter +=. Le côté gauche a été évaluée à l' 3 dans la troisième étape, et le côté droit est - 12. Donc, il assigne 3+12=15 a.
  9. La valeur finale de l' a est de 15.

Une chose à noter ici est que la priorité de l'opérateur n'a aucune influence directe sur l'ordre d'évaluation. Cela n'affecte que la forme de l'arbre, et donc indirectement de la commande. Mais entre frères et sœurs dans l'arborescence de l'évaluation est toujours de gauche à droite, que ce soit la priorité de l'opérateur.

7voto

Kal Points 14230

(a++) est une post-incrémentation, la valeur de l'expression est de 3.

(a++) est post-incrémentation, la valeur de l'expression est maintenant de 4.

L'évaluation de l'Expression est en passe de gauche à droite.

3 * 4 = 12 

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