Dans le code suivant:

int main() {
   int i, j;

   j = 10;
   i = (j++, j+100, 999+j);

   cout << i;

   return 0;
}

Le résultat est 1010 .

Cependant, cela ne devrait-il pas être 1009, car ++ devrait être fait après que l'expression entière soit utilisée?

4
Kaind 3 avril 2020 à 00:04

3 réponses

Meilleure réponse

L'opérateur virgule est un point de séquence: comme il est dit dans la norme C ++ 17 par exemple,

Chaque calcul de valeur et effet secondaire associé à l'expression de gauche est séquencé avant chaque calcul de valeur et effet secondaire associé à l'expression de droite.

Ainsi, l'effet de l'opérateur ++ est garanti avant que 999+j ne soit évalué.

8
Brian 2 avril 2020 à 21:09

++ doit-il être fait après l'utilisation de l'expression entière?

Non. L'opérateur de suffixe évalue à la valeur de l'ancien j et a pour effet secondaire d'incrémenter j.

L'opérateur virgule évalue le deuxième opérande après le premier opérande est évalué et ses effets secondaires sont évalués.

Une paire d'expressions séparées par une virgule est évaluée de gauche à droite; l'expression de gauche est une expression à valeur rejetée (Article 5) 83 . Chaque calcul de valeur et effet secondaire associé à la gauche l'expression est séquencée avant chaque calcul de valeur et effet secondaire associé à la bonne expression.

https://stackoverflow.com/a/7784819/2805305

4
bolov 2 avril 2020 à 21:08

L'associativité de l'opérateur virgule est de gauche à droite.

Donc à partir de j++, cela sera évalué en premier (j devient 11)

Alors j + 100 est évalué (inutile)

Alors 999 + j est évalué qui est égal à 1010

Cette valeur la plus à droite est attribuée à i

Ainsi, la sortie est 1010

Réponse longue:

Opérateur de virgule intégré

Les expressions opérateur de virgule ont la forme

E1 , E2   

Dans une expression de virgule E1, E2, l'expression E1 est évaluée, son résultat est ignoré (bien que s'il a un type de classe, il ne sera pas détruit jusqu'à la fin de l'expression complète contenant), et ses effets secondaires sont terminés avant l'évaluation de l'expression E2 commence (notez qu'un opérateur défini par l'utilisateur, ne peut pas garantir le séquençage) (jusqu'à C ++ 17).

Cela répond déjà à votre question, mais je vais la parcourir en référence à votre code:

Commencez par quelque chose de simple comme

int value = (1 + 2, 2 + 3, 4 + 5); // value is assigned 9

Parce que ... l'expression E1 est évaluée, son résultat est écarté ... Ici, puisque nous avons plus de 2 opérandes, l'associativité de l'opérateur virgule entre également en jeu.

Cependant, cela ne devrait-il pas être 1009, car «++» devrait être fait après que toute l'expression soit utilisée?

Maintenant vois:

int j = 0;
int i = (j++, 9 + j);

Ici, la valeur de i est 10 car ... et ses effets secondaires sont terminés avant que l'évaluation de l'expression E2 ne commence ... Par conséquent, l'incrémentation de j a son effet avant l'évaluation de 9 + j.

Je pense que maintenant vous pouvez clairement comprendre pourquoi votre

j = 10;
i = (j++, j+100, 999+j);

i reçoit une valeur de 1010 .

3
Ardent Coder 3 avril 2020 à 07:26