72 votes

Confusions avant et après incréments en C #

Je suis un peu confus sur la façon dont le compilateur C# poignées de pré - et de post-incrémente et décrémente...

Quand j'ai le code suivant:

int x = 4;
x = x++ + ++x;

x a la valeur 10 par la suite. Je pense que c'est parce que la pré-incrémentation des ensembles de x à 5, ce qui en fait 5+5, qui évalue à 10. Puis la post-graduation de la mise à jour de x à 6, mais cette valeur ne sera pas utilisé car alors 10 sera attribuée à x.

Mais quand je code:

int x = 4;
x = x-- - --x;

alors x sera 2 par la suite. Quelqu'un peut-il expliquer pourquoi c'est le cas?

Merci :-)

59voto

Sebastian Piu Points 4170

x-- sera 4, mais sera 3 au moment de --x , donc il finira par être 2, alors vous aurez

 x = 4 - 2
 

d'ailleurs, votre premier cas sera x = 4 + 6

Voici un petit exemple qui affichera les valeurs de chaque partie. Peut-être pourras-tu ainsi mieux le comprendre:

 static void Main(string[] args)
{
    int x = 4;
    Console.WriteLine("x++: {0}", x++); //after this statement x = 5
    Console.WriteLine("++x: {0}", ++x); 

    int y = 4;
    Console.WriteLine("y--: {0}", y--); //after this statement y = 3
    Console.WriteLine("--y: {0}", --y);

    Console.ReadKey();
}
 

cela imprime

 x++: 4
++x: 6
y--: 4
--y: 2
 

19voto

Mongus Pong Points 6902

Permet d'avoir un coup d'oeil à l'IL, qui est généré à partir de cette déclaration

IL_0002:  ldloc.0     

Charge la valeur de x sur la pile. Pile => (4)

IL_0003:  dup         

Duplique le premier élément sur la pile. Pile => (4, 4)

IL_0004:  ldc.i4.1    

Appuyez sur 1 sur la pile. Pile => (1, 4, 4)

IL_0005:  sub         

Soustrayez les deux premières valeurs et poussez le résultat sur la pile. Pile => (3, 4)

IL_0006:  stloc.0     

Stocker la valeur supérieure de la pile de retour à x. Pile => (4)

IL_0007:  ldloc.0     

Charger la valeur de x dans la pile. Pile => (3, 4)

IL_0008:  ldc.i4.1    

Charger la valeur 1 sur la pile. Pile => (1, 3, 4)

IL_0009:  sub         

La différence entre les deux. Pile => (2, 4)

IL_000A:  dup         

Dupliquer le haut de la valeur => (2, 2, 4)

IL_000B:  stloc.0     

Stocker la valeur de retour de x. Pile => (2, 4)

IL_000C:  sub      

Soustrayez les deux premières valeurs. Pile => (2)

IL_000D:  stloc.0  

Stocker cette valeur dans x. x == 2

9voto

Eric Lippert Points 300275

À partir de votre commentaire:

Je pensais que le post - et pré-incréments sont exécutées avant / après l'évaluation complète de la version - mais ils sont exécutés avant / après l'évaluation de chaque élément de l'expression.

Votre incompréhension est extrêmement fréquent. Notez que dans certains langages, comme le C, il n'est pas spécifié lors de l'effet secondaire devient visible, et il est donc légal, mais pas nécessaire, pour que votre déclaration soit vrai en C.

Ce n'est pas le cas en C#; en C# effets secondaires de code sur le côté gauche de l'expression sont toujours observées à arriver avant le code sur le côté droit s'exécute (à partir d'un seul fil; multithread les scénarios de tous les paris sont éteints.)

Pour une explication plus détaillée de ce que l'incrément d'opérateurs en C#, voir:

C#: quelle est la différence entre i++ et ++i?

Il y a de très nombreux liens vers des articles que j'ai écrits sur ce sujet souvent mal compris.

6voto

Shymep Points 1182

La chose la plus intéressante que vous obtiendrez une réponse complètement différente avec le compilateur C ++. Net.

 int x = 4;
x = x++ + ++x; // x = 11
x = 4;
x = x-- - --x; // x = -1
 

Bien sûr, la différence de résultats est déterminée par une sémantique différente - cela semble normal. Mais malgré la compréhension, le fait que deux compilateurs .net ne se comportent pas de la même manière pour de telles choses élémentaires me trouble aussi.

3voto

Azhar Khorasany Points 1404

Dans cet exemple,

 int x = 4;
x = x++ + ++x;
 

vous pouvez le casser comme:

 x = 4++; which is = 5
x = 4 + ++5; which is 4 + 6
x = 10
 

De même,

 int x = 4;
x = x-- - --x;
 

Ici,

 x = 4--; which is = 3
x = 4 - --3; which is 4 - 2
x = 2
 

En d'autres termes, vous pouvez dire, remplacez la valeur actuelle de x, mais pour chaque ++ ou - ajoutez / soustrayez une valeur de x.

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