web-dev-qa-db-fra.com

Concept post-incrément et pré-incrément?

Je ne comprends pas le concept d’incrément ou de décrément postfix et préfix. Quelqu'un peut-il donner une meilleure explication?

62
Saad Masood

Jusqu'à présent, les quatre réponses sont incorrect , dans la mesure où elles affirment un ordre spécifique d'événements.

Croire que cette "légende urbaine" a dérouté de nombreux novices (et professionnels), à savoir le flot incessant de questions sur le comportement non défini dans les expressions.

Alors.

Pour l'opérateur de préfixe C++ intégré,

++x

incrémente x et produit comme expression le résultat x sous forme de lvalue, tandis que

x++

incrémente x et produit comme résultat d'expression la valeur d'origine de x.

En particulier, pour x++, il n'y a pas de no time ordering implicite pour l'incrément et la production de la valeur d'origine de x. Le compilateur est libre d’émettre du code machine qui produit la valeur originale de x, par exemple. il peut être présent dans certains registres, ce qui retarde l'incrémentation jusqu'à la fin de l'expression (point de séquence suivant).

Les gens qui croient à tort que l'augmentation doit venir en premier, et ils sont nombreux, en concluent souvent que certaines expressions doivent avoir un effet bien défini, alors qu'ils ont un comportement indéfini.

101
int i, x;

i = 2;
x = ++i;
// now i = 3, x = 3

i = 2;
x = i++; 
// now i = 3, x = 2

'Post' signifie après - c'est-à-dire que l'incrément est fait après la lecture de la variable. 'Pre' signifie avant - donc la valeur de la variable est d'abord incrémentée, puis utilisée dans l'expression.

26
sje397

Personne n'a répondu à la question: Pourquoi ce concept est-il déroutant?

En tant que étudiant de premier cycle en informatique, il m'a fallu un certain temps pour comprendre cela à cause de la façon dont je lis du code.

_ {Ce qui suit n'est pas correct! _


x = y ++

X est égal à y post incrémentation. Ce qui semblerait logiquement vouloir dire que X est égal à la valeur de Y after l'opération d'incrémentation est effectuée. Post signifiant après.

ou

x = ++ y 
X est égal à y pre- incrémentation. Ce qui semblerait logiquement vouloir dire que X est égal à la valeur de Y avant l'opération d'incrémentation est effectuée. Pre signifiant avant.


La façon dont cela fonctionne est en fait le contraire. Ce concept est déroutant parce que le langage est trompeur. Dans ce cas, nous ne pouvons pas utiliser les mots pour définir le comportement.
x = ++ y est en fait lu car X est égal à la valeur de Y après l'incrément.
x = y ++ est en fait lu car X est égal à la valeur de Y avant l'incrément.

Les mots pre et post sont à l'envers par rapport à la sémantique anglaise. Ils signifient seulement où le ++ est en relation Y. Rien de plus.

Personnellement, si j'avais le choix, je changerais la signification de ++ y et y ++. Ceci est juste un exemple d'un idiome que j'ai dû apprendre.

S'il y a une méthode à cette folie, j'aimerais savoir en termes simples.

Merci d'avoir lu.

16
mathewbruens

La différence entre l'incrément postfix, x++ et l'incrément prefix, ++x, est précisément dans comment les deux opérateurs évaluent leurs opérandes. L'incrément postfixe copie conceptuellement l'opérande en mémoire, incrémente l'opérande d'origine et donne finalement la valeur de la copie. Je pense que ceci est mieux illustré en implémentant l'opérateur dans le code:

int operator ++ (int& n)  // postfix increment
{
    int tmp = n;
    n = n + 1;
    return tmp;
}

Le code ci-dessus ne sera pas compilé car vous ne pouvez pas redéfinir les opérateurs pour les types primitifs. Le compilateur ne peut pas non plus dire ici que nous définissons un opérateur postfix plutôt que prefix, mais supposons que ce soit un C++ correct et valide. Vous pouvez voir que l'opérateur postfix agit bien sur son opérande, mais il renvoie l'ancienne valeur avant l'incrément, de sorte que le résultat de l'expression x++ est la valeur antérieure à l'incrément. x, cependant, est incrémenté.

Le préfixe incrément incrémente également son opérande, mais il donne la valeur de l'opérande après l'incrément:

int& operator ++ (int& n)
{
    n = n + 1;
    return n;
}

Cela signifie que l'expression ++x a pour valeur xafter l'incrément.

Il est facile de penser que l'expression ++x est donc équivalente à assignmnet (x=x+1). Ce n’est cependant pas précisément le cas, car un incrément est une opération qui peut signifier différentes choses dans différents contextes. Dans le cas d'un entier primitif simple, en effet, ++x est substituable à (x=x+1). Mais dans le cas d'un type de classe, tel qu'un itérateur d'une liste liée, un incrément de préfixe de l'itérateur ne signifie absolument pas "l'ajout d'un à l'objet".

13
wilhelmtell

C'est assez simple. Les deux vont incrémenter la valeur d'une variable. Les deux lignes suivantes sont égales:

x++;
++x;

La différence est si vous utilisez la valeur d'une variable incrémentée:

x = y++;
x = ++y;

Ici, les deux lignes augmentent la valeur de y de un. Cependant, le premier attribue la valeur de y avant l'incrément à x et le second attribue la valeur de y après l'incrément à x.

Il n'y a donc de différence que lorsque l'incrément est également utilisé comme expression. La post-incrémentation s'incrémente après le retour de la valeur. Le pré-incrément incrémente avant.

6
Jonathan Wood
int i = 1;
int j = 1;

int k = i++; // post increment
int l = ++j; // pre increment

std::cout << k; // prints 1
std::cout << l; // prints 2

Post increment implique que la valeur i est incrémentée après avoir été affectée à k. Cependant, pré-incrémentation implique que la valeur j soit incrémentée avant d'être affectée à l.

La même chose s'applique pour décrémenter.

4
Seth

Post incrémentation (a ​​++)

Si int b = a ++, alors cela signifie

int b = a;

a = a+1;

Ici, nous ajoutons 1 à la valeur. La valeur est renvoyée avant que l'incrément ne soit effectué,

Par exemple, a = 1; b = a ++;

Alors b = 1 et a = 2

Pré-incrémentation (++ a)

Si int b = ++ a; alors cela signifie

a=a+1;

int b=a ;

Pré-incrémentation: Ceci ajoutera 1 à la valeur principale. La valeur sera renvoyée une fois l’incrément réalisé, pour a = 1; b = ++ a; Alors b = 2 et a = 2.

1
drvenom

L'incrémentation post-incrémentation (x ++) se produit à l'instruction suivante:

Exemple de post-incrémentation:

  static void Main(string[] args)
    {
        int x = 0;
        int y= Method(x++);//x=0
        Console.WriteLine(x);// now x=1
        Console.WriteLine(y);// but y=0;
    }
    public static int  Method(int x)
    {
       //when called value of x=0;
        return x;//returns 0

    }

L'augmentation de pré-incrémentation (++ x) se produit à l'instruction en cours

Exemple de pré-incrémentation:

  static void Main(string[] args)
    {
        int x = 0;
        int y= Method(++x);//x=1
        Console.WriteLine(x);// now also  x=1
        Console.WriteLine(y);//y is 1
    }
    public static int  Method(int x)
    {

       //inside x=1;
        return x; //returns 1

    }
0
venkat

Puisque nous avons maintenant des extraits javascript en ligne, je pourrais aussi bien ajouter un exemple interactif d’incrémentation pré et pos. Ce n'est pas C++ mais le concept reste le même.

let A = 1;
let B = 1;

console.log('A++ === 2', A++ === 2);
console.log('++B === 2', ++B === 2);

0
Olian04

De la norme C99 (C++ devrait être identique, sauf surcharge étrange)

6.5.2.4 Opérateurs d’incrémentation et de décrémentation de Postfix

Contraintes

1 L'opérande de l'incrément postfixe ou l'opérateur de décrémentation doit avoir qualifié ou non qualifié réel ou type de pointeur et doit être modifiable lvalue.

Sémantique

2 Le résultat de postfix ++ opérateur est la valeur de l'opérande . Une fois le résultat obtenu, le la valeur de l'opérande est incrémentée . (C'est-à-dire que la valeur 1 du type approprié Lui est ajoutée.) Voir les discussions des opérateurs additifs et affectation composée pour informations sur les contraintes, les types et conversions et les effets de opérations sur les pointeurs. Le côté effet de la mise à jour de la valeur stockée de l'opérande doit se situer entre le précédent et le prochain point de la séquence.

3 L'opérateur postfixe est analogue à l'opérateur postfix ++, sauf que la valeur de l'opérande est décrémenté (c’est-à-dire que la valeur 1 de le type approprié lui est soustrait ).

6.5.3.1 Opérateurs de préfixe incrémentation et décrémentation

Contraintes

1 Opérande de l'incrément de préfixe ou l'opérateur de décrémentation doit avoir qualifié ou non qualifié réel ou type de pointeur et doit être modifiable lvalue.

Sémantique

2 La valeur de l'opérande du le préfixe ++ est incrémenté. Le résultat est la nouvelle valeur de l'opérande après incrémentation. L'expression ++ E est équivalent à (E + = 1). Voir les discussions des opérateurs additifs et affectation composée pour information sur contraintes, types, effets secondaires et conversions et les effets de opérations sur les pointeurs.

3 Le préfixe - opérateur est analogue à l'opérateur préfixe ++, sauf que la valeur de l'opérande est décrémenté.

0
Scott Wales