27 votes

Quand ++ ne produit-il pas les mêmes résultats que +1?

Les deux C# fragments de code à produire des résultats différents (en supposant que la variable de niveau est utilisé à la fois avant et après l'appel récursif). Pourquoi?

public DoStuff(int level)
{
  // ...
  DoStuff(level++);
  // ...
}

,

public DoStuff(int level)
{
  // ...
  DoStuff(level+1);
  // ...
}

Après la lecture de certaines réponses ci-dessous j'ai pensé qu'il serait bon de poster des traces de la pile pour le niveau++, ++niveau et le niveau+1 pour mettre en évidence comment tromper ce problème.

J'ai simplifié pour ce post. L'appel récursif de la séquence commence avec DoStuff(1).

// niveau++

DoStuff(int level = 1)
DoStuff(int level = 2)
DoStuff(int level = 2)
DoStuff(int level = 2)

// ++niveau

DoStuff(int level = 4)
DoStuff(int level = 4)
DoStuff(int level = 3)
DoStuff(int level = 2)

// niveau+1

DoStuff(int level = 4)
DoStuff(int level = 3)
DoStuff(int level = 2)
DoStuff(int level = 1)

44voto

Matt Points 738

Pour clarifier toutes les autres réponses:

++++++++++++++++++++++

 DoStuff(a++);
 

Est équivalent à:

 DoStuff(a);
a = a + 1;
 

++++++++++++++++++++++

 DoStuff(++a);
 

Est équivalent à:

 a = a + 1;
DoStuff(a);
 

++++++++++++++++++++++

 DoStuff(a + 1);
 

Est équivalent à:

 b = a + 1;
DoStuff(b);
 

++++++++++++++++++++++

29voto

Parce que le premier exemple est vraiment équivalent à:

 public DoStuff(int level)
{  
  // ...
  int temp = level;
  level = level + 1;
  DoStuff(temp);
  // ...
}
 

Notez que vous pouvez également écrire au niveau ++; ce serait équivalent à:

 public DoStuff(int level)
{  
  // ...
  level = level + 1;
  DoStuff(level);
  // ...
}
 

Il vaut mieux ne pas abuser des opérateurs ++ et - à mon avis; cela devient rapidement confus et / ou indéfini ce qui se passe réellement, et les compilateurs C ++ modernes ne génèrent pas de code plus efficace avec ces opérateurs de toute façon.

27voto

workmad3 Points 12974

niveau++ va passer de niveau en DoStuff et puis incrémenter le niveau pour une utilisation dans le reste de la fonction. Cela pourrait être un assez méchant bug comme la récursivité n'aura jamais de fin (à partir de ce qui est montré DoStuff est toujours passé de la même valeur). Peut-être ++niveau est destinée au lieu de cela, que c'est le contraire de niveau++ (incréments de niveau et passe la valeur incrémentée dans DoStuff)?

niveau+1 va passer de niveau+1 en DoStuff et laisser niveau inchangé pour le reste de la fonction.

12voto

Orion Adrian Points 8855

la valeur de retour de l' level++ sera level et therefore pass level en DoStuff. Cela pourrait être un assez méchant bug comme la récursivité n'aura jamais de fin (à partir de ce qui est montré DoStuff est toujours transmis avec la même valeur). Peut - ++level ou level + 1 est destinée à la place?

level + 1 passera level + 1 en DoStuff et laissez level inchangé pour le reste de la fonction.


La post-incrémentation de l'opérateur (variable++) est précisément l'équivalent de la fonction

int post_increment(ref int value)
{
    int temp = value;
    value = value + 1
    return temp;
}

alors que le pré-opérateur d'incrémentation (++variable) est précisément l'équivalent de la fonction

int pre_increment(ref int value)
{
    value = value + 1;
    return value;
}

Par conséquent, si vous développez l'opérateur inline dans le code, les opérateurs sont équivalentes à:

DoStuff(a + 1)

int temp = a + 1;
DoStuff(temp);

DoStuff(++a)

a = a + 1;
DoStuff(a);

DoStuff(a++);

int temp = a;
a = a + 1;
DoStuff(temp);

Il est important de noter que la post-incrémentation est pas équivalent à:

DoStuff(a);
a = a + 1;

En outre, comme un point de style, il ne faut pas incrémenter une valeur, sauf si l'intention est d'utiliser la valeur incrémentée (une version spécifique de la règle de "ne pas affecter une valeur à une variable, sauf si vous prévoyez sur l'utilisation de la valeur"). Si la valeur i + 1 n'est jamais utilisé de nouveau, alors préféré l'utilisation de la DoStuff(i + 1) et pas DoStuff(++i).

2voto

PintSizedCat Points 4221

La première consiste à utiliser la valeur de niveau puis à l'incrémenter.

Ce dernier utilise le niveau + 1 comme variable transmise.

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