Question sur la programmation en C

int a, b; a = 1; a = a + a++; a = 1; b = a + a++; printf("%d %d, a, b); 

sortie: 3,2

Quelle est la différence entre les lignes 3 et 5?

Ce que vous faites n’est pas défini.

Vous ne pouvez pas changer la valeur d’une variable que vous êtes sur le point d’atsortingbuer.

Vous ne pouvez pas non plus modifier la valeur d’une variable avec un effet secondaire et essayer d’utiliser cette même variable ailleurs dans la même expression (sauf s’il existe un sharepoint séquence , mais dans ce cas, il n’en existe pas). L’ordre d’évaluation des deux arguments pour + n’est pas défini.

Donc, s’il y a une différence entre les deux lignes, c’est que la première est indéfinie pour deux raisons et la ligne 5 n’est indéfinie que pour une raison. Mais le point est à la fois la ligne 3 et la ligne 5 ne sont pas définies et faire l’un ou l’autre est mauvais.

Ce que vous faites à la ligne 3 n’est pas défini. C ++ a la notion de “points de séquence” (généralement délimités par des points-virgules). Si vous modifiez un object plusieurs fois par sharepoint séquence, il est illégal, comme vous l’avez fait à la ligne 3. Comme l’indique la section 6.5 de C99 :

(2) Entre la séquence précédente et la séquence suivante, la valeur stockée d’un object doit être modifiée au plus une fois par l’évaluation d’une expression. De plus, la valeur antérieure doit être lue uniquement pour déterminer la valeur à stocker.

La ligne 5 n’est pas non plus définie à cause de la deuxième phrase. Vous lisez a pour obtenir sa valeur, que vous utiliserez ensuite dans une autre affectation en a++ .

a++ est un opérateur post-fix, il obtient la valeur de a puis l’ incrémente.

Donc, pour les lignes 2,3:
a = 1
a = 1 + 1, a est incrémenté.
a devient 3 (Remarque, l’ordre dans lequel ces opérations sont effectuées peut varier d’un compilateur à l’autre et a peut devenir facilement 2)

pour les lignes 4,5:
a = 1
b = 1 + 1, a est incrémenté.
b devient 2, a devient 2. (En raison d’un comportement indéfini, b pourrait également devenir 3 d’un ++ est traité avant que a)

Notez que, hormis pour comprendre le fonctionnement des opérateurs postfixes, je ne recommanderais vraiment pas d’utiliser cette astuce. Son comportement n’est pas défini et donnera des résultats différents s’il est compilé à l’aide de différents compilateurs.

En tant que tel, il s’agit non seulement d’une manière inutilement déroutante de faire les choses, mais aussi d’une manière peu fiable et pessimiste de le faire.

EDIT : Et d’autres ont souligné, c’est en fait un comportement indéfini.

La ligne 3 n’est pas définie, la ligne 5 ne l’est pas.

MODIFIER:

Comme Prasoon le souligne correctement, les deux sont UB.

L’expression simple a + a++ est indéfinie pour les raisons suivantes:

  1. L’opérateur + n’est pas un sharepoint séquence, les effets secondaires de chaque opérande peuvent donc se produire dans l’un ou l’autre ordre.
  2. a est initialement 1 .
  3. Un des deux scénarios [sensibles] possibles peut se produire:

    1. Le premier opérande, a est évalué en premier,

      a) Sa valeur, 1 sera stockée dans un registre, R Aucun effet secondaire ne se produit.

      b) Le deuxième opérande a++ est évalué. Il évalue également à 1 et est ajouté au même registre R Comme effet secondaire, la valeur stockée de a est définie sur 2.

      c) Le résultat de l’addition, actuellement dans R est écrit en a . La valeur finale de a est 2.

    2. Le deuxième opérande a++ est évalué en premier.

      a) Il est évalué à 1 et stocké dans le registre R La valeur stockée de a est incrémentée à 2 .

      b) Le premier opérande a est lu. Il contient maintenant la valeur 2 , pas 1 ! Il est ajouté à R

      c) R contient 3 et ce résultat est écrit dans a . Le résultat de l’addition est maintenant 3 , pas 2 , comme dans notre premier cas!

En bref, vous ne devez pas compter sur un tel code pour fonctionner.