Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between "++" and "+= 1 " operators?

In a loop in C++, I usually encounter situations to use ++ or +=1, but I can't tell their difference. For instance, if I have an integer

int num = 0; 

and then in a loop I do:

num ++; 

or

num += 1; 

they both increase the value of num, but what is their difference? I doubt num++ could work faster than num+=1, but how? Is this difference subtle enough to be ignored?

like image 539
E_learner Avatar asked Oct 20 '12 11:10

E_learner


People also ask

What is the difference between and and or operators?

The bitwise OR operator sets the bit value whereas the logical OR operator sets true or 1 if either one of the conditions/bit value is 1 else it sets false or 0.

What is the difference between += and =+?

+ is an arithmetic operator while += is an assignment operator.. When += is used, the value on the RHS will be added to the variable on the LHS and the resultant value will be assigned as the new value of the LHS..

What is the difference between ++ and +1?

These two are exactly the same. It's just two different ways of writing the same thing. i++ is just a shortcut for i += 1 , which itself is a shortcut for i = i + 1 . These all do the same thing, and it's just a question of how explicit you want to be.

What is the difference between and =?

The “=” is an assignment operator is used to assign the value on the right to the variable on the left. The '==' operator checks whether the two given operands are equal or not. If so, it returns true. Otherwise it returns false.


2 Answers

num += 1 is rather equivalent to ++num.

All those expressions (num += 1, num++ and ++num) increment the value of num by one, but the value of num++ is the value num had before it got incremented.

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 

Use whatever pleases you. I prefer ++num to num += 1 because it is shorter.

like image 57
Alexandre C. Avatar answered Sep 22 '22 00:09

Alexandre C.


prefix and postfix operations are perfect candidates for exam questions.

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 

+= operation and its sister -= are more general solutions mostly intended to be used with different numbers. One might even say they are redundant when used with 1. When used with 1 they mostly act as a prefix operation. In fact on my machine they produce the same machine code. You can try this by using an example program such as:

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; } 

and disassembling in gdb which would give:

first case (a++) (different)

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

second case (++a)

(gdb) disassemble foo Dump of assembler code for function foo:    0x00000000004004b4 <+0>:     push   %rbp    0x00000000004004b5 <+1>:     mov    %rsp,%rbp    0x00000000004004b8 <+4>:     movl   $0x0,-0x8(%rbp)    0x00000000004004bf <+11>:    addl   $0x1,-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. 

third case (a += 1)

(gdb) disassemble foo Dump of assembler code for function foo:    0x00000000004004b4 <+0>:     push   %rbp    0x00000000004004b5 <+1>:     mov    %rsp,%rbp    0x00000000004004b8 <+4>:     movl   $0x0,-0x8(%rbp)    0x00000000004004bf <+11>:    addl   $0x1,-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. 

fourth case (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   $0x0,-0x8(%rbp)    0x00000000004004bf <+11>:    addl   $0x1,-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. 

As you can see they produce the same machine code even without compiler optimizations turned on except the first case which has addl after movs. This means that you should be using whichever you like as a user and let the compiler guys do the rest.

And lastly, note that cousin operators *= and /= have no postfix and prefix counterparts.

like image 28
none Avatar answered Sep 24 '22 00:09

none