Quelle est la différence entre les opérateurs "++" et "+= 1"?

Dans une boucle en C++, j'ai l'habitude de rencontrer des situations à utiliser ++ ou +=1, mais je ne vois pas la différence. Par exemple, si j'ai un entier

int num = 0;

puis dans une boucle je fais:

num ++;

ou

num += 1;

ils augmentent tous les deux la valeur de num, mais quelle est leur différence? Je doute num++ pourrait fonctionner plus vite que num+=1, mais comment? Cette différence est assez subtile pour être ignoré?

40
demandé sur E_learner 2012-10-20 15:51:12

10 réponses

num += 1 est plutôt équivalent à ++num.

Toutes ces expressions (num += 1,num++ et ++num) incrémenter la valeur de num par un, mais la valeur de num++ est la valeur num avait avant il a été incrémenté.

Illustration:

int a = 0;
int b = a++; // now b == 0 and a == 1
int c = ++a; // now c == 2 and a == 2
int d = (a += 1); // now d == 3 and a == 3

utilisez ce qui vous plaît. Je préfère ++numnum += 1 parce que c'est plus court.

74
répondu Alexandre C. 2012-10-20 11:58:52

prefix et postfix les opérations sont des candidats parfaits pour les questions d'examen.

a = 0;
b = a++;  // use the value and then increment --> a: 1, b: 0

a = 0;
b = ++a;  // increment and then use the value --> a: 1, b: 1

+= opération et sa sœur -= sont des solutions plus générales généralement destinées à être utilisées avec des nombres différents. On pourrait même dire qu'ils sont redondants lorsqu'il est utilisé avec 1. Lorsqu'il est utilisé avec 1 ils agissent surtout comme un prefix opération. En fait sur ma machine, ils produisent le même code machine. Vous pouvez essayer en utilisant un exemple de programme tels que:

void foo() {
    int a, b;
    a = 0;

    // use one of these four at a time
    b = a++;          // first case (different)
    b = ++a;          // second case
    b = (a += 1);     // third case
    b = (a = a + 1);  // fourth case
}

int main() {
    foo();
    return 0;
}

et le démontage dans gdb ce qui donnerait:

premier cas (a++) (différent)

(gdb) disassemble foo
Dump of assembler code for function foo:
   0x00000000004004b4 <+0>:     push   %rbp
   0x00000000004004b5 <+1>:     mov    %rsp,%rbp
   0x00000000004004b8 <+4>:     movl   x0,-0x8(%rbp)
   0x00000000004004bf <+11>:    mov    -0x8(%rbp),%eax
   0x00000000004004c2 <+14>:    mov    %eax,-0x4(%rbp)
   0x00000000004004c5 <+17>:    addl   x1,-0x8(%rbp)
   0x00000000004004c9 <+21>:    pop    %rbp
   0x00000000004004ca <+22>:    retq
End of assembler dump.

deuxième cas (++a)

(gdb) disassemble foo
Dump of assembler code for function foo:
   0x00000000004004b4 <+0>:     push   %rbp
   0x00000000004004b5 <+1>:     mov    %rsp,%rbp
   0x00000000004004b8 <+4>:     movl   x0,-0x8(%rbp)
   0x00000000004004bf <+11>:    addl   x1,-0x8(%rbp)
   0x00000000004004c3 <+15>:    mov    -0x8(%rbp),%eax
   0x00000000004004c6 <+18>:    mov    %eax,-0x4(%rbp)
   0x00000000004004c9 <+21>:    pop    %rbp
   0x00000000004004ca <+22>:    retq   
End of assembler dump.

troisième cas (a += 1)

(gdb) disassemble foo
Dump of assembler code for function foo:
   0x00000000004004b4 <+0>:     push   %rbp
   0x00000000004004b5 <+1>:     mov    %rsp,%rbp
   0x00000000004004b8 <+4>:     movl   x0,-0x8(%rbp)
   0x00000000004004bf <+11>:    addl   x1,-0x8(%rbp)
   0x00000000004004c3 <+15>:    mov    -0x8(%rbp),%eax
   0x00000000004004c6 <+18>:    mov    %eax,-0x4(%rbp)
   0x00000000004004c9 <+21>:    pop    %rbp
   0x00000000004004ca <+22>:    retq   
End of assembler dump.

le quatrième cas (a = a + 1)

(gdb) disassemble foo
Dump of assembler code for function foo:
   0x00000000004004b4 <+0>:     push   %rbp
   0x00000000004004b5 <+1>:     mov    %rsp,%rbp
   0x00000000004004b8 <+4>:     movl   x0,-0x8(%rbp)
   0x00000000004004bf <+11>:    addl   x1,-0x8(%rbp)
   0x00000000004004c3 <+15>:    mov    -0x8(%rbp),%eax
   0x00000000004004c6 <+18>:    mov    %eax,-0x4(%rbp)
   0x00000000004004c9 <+21>:    pop    %rbp
   0x00000000004004ca <+22>:    retq   
End of assembler dump.

comme vous pouvez le voir ils produisent le même code machine même sans optimisations de compilateurs activées sauf le premier cas qui a addl après mov S. Cela signifie que vous devez utiliser ce que vous voulez comme un utilisateur et laisser les gars du compilateur faire le reste.

et enfin, notez que les opérateurs cousins *= et /= aucun postfix et prefix homologues.

16
répondu none 2012-12-19 16:30:03

++ un préfixe ou un suffixe opérateurs modifier la valeur variable.

int a = 0;
int b = a++; // b is equal to 0, a is equal to 1

Ou un préfixe:

int a = 0;
int b = ++a; // b = 1, a = 1

Si utilisé comme cela, ils sont les mêmes:

int a = 0;
++a; // 1
a++; // 2
a += 1; // 3
9
répondu dreamzor 2012-10-20 11:52:54

les deux opérateurs augmentent la valeur de n de 1. La différence entre eux existe lorsque vous utilisez les opérateurs avec l'opérateur d'affectation.

Par exemple:

Premier Cas --Post-Incrémentation de l'opérateur

int n=5;
int new_var;

new_var=n++;

print("%d",new_var);

Sortie=5

Deuxième Cas

int n=5;
n+=1;
new_var=n;
print("%d",new_var);

Sortie =6

ceci est très similaire à ce que l'opérateur de pré-incrément résulterait en.

Deuxième Cas utilisant l'opérateur Pre-increment

int n=5;

new_var=++n;
print("%d",new_var);

Sortie =6

6
répondu Desert Ice 2012-10-20 13:45:20

ils sont généralement les mêmes et il n'y a aucune signification pour clarifier la différence entre eux. Mais la mise en œuvre de ces deux déclarations est en fait différente. Exemple, a+=1 compiler à assember est

ajouter un,1

et un++ ou ++est un

inc

Il peut y avoir une légère différence dans l'efficacité parce qu'ils sont deux opérations CPU différentes.

2
répondu bigfish 2012-10-20 14:11:48

certains d'entre vous s'approchent de la différence, mais il faut le dire très clairement:

CE SONT DES OPÉRATEURS TRÈS DIFFÉRENTS.

les opérateurs de pré-incrément et de post-incrément sont conçus pour être utilisés à l'intérieur D'EXPRESSIONS pour changer la valeur de la variable avant ou après que la valeur de la variable soit utilisée dans n'importe quelle expression qui l'entoure. Lors de l'utilisation de l'opérateur post-incrément, L'ancienne valeur de la variable est utilisée pour évaluer l'expression enveloppante et seulement après cela est la variable incremented.

Par exemple:

i = 10;
j = i++;  // This causes j to be 10 while i becomes 11.

C'est pourquoi on l'appelle l'opérateur post-accroissement. La variable est incrémentée POST (AFTER) sa valeur est utilisée dans la plus grande expression (ici une expression de tâche).

Toutefois, si vous n':

i = 10;
j = ++i; // Now both i and j will be 11 because the increment
         // of i occurs PRE (BEFORE) its value is used in the greater expression.
2
répondu Tom Wetmore 2012-10-20 14:58:54

ces deux opérateurs peuvent sembler similaires, mais ils sont très différents.

pour les types primitifs (pointeurs, entiers, etc.) ils augmentent tous les deux la valeur par un. Mais, pour les classes C++, ils appellent des opérateurs différents (operator+= vs. operator++); en effet, pour certaines classes, comme list<T>::iterator,i += 1 ne fonctionne pas et i++ doit être utilisé.

de plus, ils produisent des valeurs différentes. i += 1 produit i après incrémentation (comme un pré-incrément), alors que i++ produit i avant incrémentation. Ainsi,

int a = 0, b = 0;
cout << (a+=1) << " " << b++ << endl;

imprime 1 0. Parce que i += 1 est équivalent à un pré-accroissement, dans certains cas,i += 1 résultat

donc, bien qu'elles soient les mêmes pour les variables incrémentantes, il faut être conscient qu'elles ne sont pas des substituts parfaits dans toutes les conditions.

2
répondu nneonneo 2012-10-20 23:25:41

je suis surpris que personne ne mentionne qu'au moins pour les vieux compilateurs / ordinateurs (essentiellement quand C est né et une décennie ou deux après) += 1 sera de manière significative plus lent que ++. ++ est un incrément pour lequel le CPU a probablement une instruction unique. += 1 nécessite de charger la valeur 1 dans un registre (ce qui sauvera probablement sa valeur)... quelque part) et appelant à un ajout. Je ne peux pas dire si les compilateurs actuels optimisent ceci mais je soupçonne qu'ils faire.

1
répondu chx 2012-10-20 15:03:39

je suis nouveau à Stackoverflow Mais voici ma valeur de 2 pence.

si la question Est + = et non +=1. La déclaration a été posté;

je rencontre habituellement des situations pour utiliser ++ ou +=1, mais je ne peux pas dire leur différence.

je pense que le 1 pourrait juste avoir facilement un autre numéro ou peut-être mieux écrit que +=?

En termes de résultat, il n'y a pas de différence (en utilisant les affiches des valeurs). Les deux vont augmenter d'un, cependant, ++ n'augmentera que de 1 alors que += augmentera de la valeur spécifiée par le codeur, dans l'exemple d'ederman il se trouve que c'est 1. Par Exemple:

// Example 1:
num = 0;
num = ++;
// the result of num will be 1

// Example 2:
num = 0;
num = += 1;
// the result of num will be 1 the same as example 1

// Example 3:
num = 0;
num = += 2;
// the result of num will be 2.

// Example 4:
num = 0;
num = ++ 2;
// this would not compile as ++ will not except any value for the increment step it is assumed
// you will always want to increment by the value of 1

donc si vous voulez incrémenter seulement une valeur par 1 j'utiliserais ++ mais si vous avez besoin d'incrémenter de plus le 1 utilisez +=

j'Espère que est utile.

1
répondu Kevin Morrissey 2012-11-01 11:54:25

++ est utilisé pour incrémenter la valeur par 1, alors qu'en utilisant += vous pouvez incrémenter d'un autre montant.

0
répondu Alfa3eta 2012-10-20 11:56:27