“++”和“+= 1”运算符的区别是什么?

时间:2022-12-23 22:57:23

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

在c++的循环中,我经常遇到使用++或+=1的情况,但是我不能区分它们的区别。例如,如果我有一个整数

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?

它们都增加了num的值,但是它们的区别是什么呢?我怀疑num++可以比num+=1工作得更快,但是怎么做呢?这种差异是否微妙到足以被忽略?

10 个解决方案

#1


72  

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

num += 1与+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.

所有这些表达式(num += 1、num+和+num)都使num的值增加了一个,但是num++的值是num增加之前的值。

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.

使用令你开心的事情。与num += 1相比,我更喜欢+num,因为它更短。

#2


16  

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:

+=运算和它的姐妹-=是更通用的解决方案,主要用于不同的数字。当与1一起使用时,甚至可以说它们是冗余的。当与1一起使用时,它们通常作为前缀操作。事实上,在我的机器上他们产生了相同的机器代码。您可以使用示例程序,例如:

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:

在gdb中进行拆卸会得到:

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.

正如您所看到的,它们生成相同的机器代码,即使没有打开编译器优化,除了第一个在movs之后有addl的情况。这意味着,作为用户,您应该使用您喜欢的任何一个,并让编译器人员完成其余的工作。

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

最后,请注意表兄操作符*=和/=没有后缀和前缀对应项。

#3


9  

The ++ prefix or postfix operators change the variable value.

前缀或后缀运算符改变变量值。

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

Or prefix:

或前缀:

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

If used like this, they are the same:

如果像这样使用,它们是一样的:

int a = 0;
++a; // 1
a++; // 2
a += 1; // 3

#4


6  

Both the operators increase the value of n by 1. The difference between them exists when you use the operators along with the assignment operator.

这两个运算符都使n增加了1。当您使用操作符和赋值操作符时,它们之间的区别就存在。

For example:

例如:

First Case --Post-Increment operator

第一个案例——Post-Increment算子

int n=5;
int new_var;

new_var=n++;

print("%d",new_var);

Output=5

输出= 5

Second Case

第二个案例

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

Output =6

输出= 6

This is very similar to what pre-increment operator would result in.

这与前增量运算符的结果非常相似。

Second Case using Pre-increment operator

第二种情况是使用预增量运算符

int n=5;

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

Output =6

输出= 6

#5


2  

They are generally the same and there is no significance to clarify the difference between them. But the implementing of these two statement are in fact different. For example, a+=1 compiling to assember is
add a,1
and a++ or ++a is
inc a
There may be some mildly difference in efficiency because they are two different CPU operation.

它们通常是相同的,没有必要去澄清它们之间的区别。但这两种说法的实施实际上是不同的。例如,将+=1编译为assember就是添加了a、1和a++或++ +a是inc。

#6


2  

Some of you are approaching the difference, but it should be stated very clearly:

你们中有些人正在接近这种差别,但应该非常明确地指出:

THEY ARE VERY DIFFERENT OPERATORS.

它们是非常不同的运算符。

The preincrement and postincrement operators are designed to be used INSIDE EXPRESSIONS to change the value of the variable either BEFORE or AFTER the value of the variable is used in whatever expression encloses it. When using the postincrement operator the OLD value of the variable is used to evaluate the enclosing expression and only after that is the variable incremented.

预递增和后递增操作符被设计为在表达式中使用,以在变量的值被包含在任何表达式之前或之后更改变量的值。使用后增量运算符时,将使用变量的旧值来计算封闭表达式,然后才对变量进行递增。

For example:

例如:

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

This is why it is called the postincrement operator. The variable is incremented POST (AFTER) it's value is used in the greater expression (here an assignment expression).

这就是为什么它被称为postincrement运算符。变量的值是递增的POST (AFTER),它的值用在更大的表达式中(这里是赋值表达式)。

However, if you do:

然而,如果你做的事:

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.

#7


2  

These two operators may appear to be similar, but they are quite different.

这两个操作符可能看起来很相似,但它们是完全不同的。

For primitive types (pointers, integers, etc.) they both increment the value by one. But, for C++ classes, they call different operators (operator+= vs. operator++); indeed, for some classes, like list<T>::iterator, i += 1 does not work and i++ must be used.

对于原始类型(指针、整数等),它们都将值增加1。但是,对于c++类,它们调用不同的操作符(操作符+= vs.操作符+);实际上,对于某些类,比如list ::iterator, i+ = 1不起作用,必须使用i++ ++。

Furthermore, they produce different values. i += 1 produces i after incrementing (like a preincrement), while i++ produces i before incrementing. Thus,

此外,它们产生不同的价值。i+ = 1在递增后生成i(比如递增),而i++在递增之前生成i。因此,

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

prints 1 0. Because i += 1 is equivalent to a preincrement, in some cases, i += 1 may result

打印1 0。因为i += 1等于一个前增量,在某些情况下,i += 1可能是结果

So, while they are the same for incrementing variables, one should be aware that they are not perfect substitutes in all conditions.

因此,虽然它们对于递增变量是相同的,但是我们应该意识到它们并不是所有条件下的完美替代品。

#8


1  

I am surprised noone mentions that at least for old compilers / computers (basically when C was born and a decade or two after) += 1 will be significantly slower than ++. ++ is an increment which the CPU most likely has a single instruction for. += 1 requires loading the value 1 into a register (likely saving the value of it... somewhere) and calling for an addition. I can't say whether current compilers optimize this out but I suspect they do.

我很惊讶没有人提到,至少对于旧的编译器/计算机(基本上是在C诞生的时候,10年或20年后),+= 1将明显地比++慢。++是CPU很可能只有一条指令的增量。+= 1需要将值1加载到寄存器中(可能保存它的值…在某个地方)并要求增加。我不能说当前的编译器是否对它进行了优化,但我怀疑它们确实进行了优化。

#9


1  

I'm new to * but here's my 2 pence worth.

我刚到*,这是我的2便士。

If the question is about += and not +=1. The statement posted was;

如果问题是关于+=而不是+=1。该声明发布;

I usually encounter situations to use ++ or +=1, but I can't tell their difference.

我经常遇到用+或+=1的情况,但是我分不清它们的区别。

I think the 1 could just have easily been another number or perhaps better written as +=?

我认为1可以很容易地写成另一个数字或者写成+=?

In terms of the result there is no difference (using the posters values). Both will increment by one, however, ++ will only increment by 1 whereas += will increment by the value specified by the coder, in ederman's example this happens to be 1. For Example:

在结果上没有区别(使用海报的值)。两者都将增加1,然而,++将只增加1,而+=将增加编码者指定的值,在ederman的例子中,这恰好是1。例如:

// 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

So if you only want to increment a value by 1 I would use ++ but if you need to increment by more the 1 use +=

如果你想让一个值增加1,我就用++但是如果你想增加1,就用+=

Hope that is useful.

希望是有用的。

#10


0  

++ is used to increment value by 1, while using += you can increment by another amount.

++被用来增加1的值,同时使用+=你可以增加一个量。

#1


72  

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

num += 1与+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.

所有这些表达式(num += 1、num+和+num)都使num的值增加了一个,但是num++的值是num增加之前的值。

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.

使用令你开心的事情。与num += 1相比,我更喜欢+num,因为它更短。

#2


16  

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:

+=运算和它的姐妹-=是更通用的解决方案,主要用于不同的数字。当与1一起使用时,甚至可以说它们是冗余的。当与1一起使用时,它们通常作为前缀操作。事实上,在我的机器上他们产生了相同的机器代码。您可以使用示例程序,例如:

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:

在gdb中进行拆卸会得到:

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.

正如您所看到的,它们生成相同的机器代码,即使没有打开编译器优化,除了第一个在movs之后有addl的情况。这意味着,作为用户,您应该使用您喜欢的任何一个,并让编译器人员完成其余的工作。

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

最后,请注意表兄操作符*=和/=没有后缀和前缀对应项。

#3


9  

The ++ prefix or postfix operators change the variable value.

前缀或后缀运算符改变变量值。

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

Or prefix:

或前缀:

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

If used like this, they are the same:

如果像这样使用,它们是一样的:

int a = 0;
++a; // 1
a++; // 2
a += 1; // 3

#4


6  

Both the operators increase the value of n by 1. The difference between them exists when you use the operators along with the assignment operator.

这两个运算符都使n增加了1。当您使用操作符和赋值操作符时,它们之间的区别就存在。

For example:

例如:

First Case --Post-Increment operator

第一个案例——Post-Increment算子

int n=5;
int new_var;

new_var=n++;

print("%d",new_var);

Output=5

输出= 5

Second Case

第二个案例

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

Output =6

输出= 6

This is very similar to what pre-increment operator would result in.

这与前增量运算符的结果非常相似。

Second Case using Pre-increment operator

第二种情况是使用预增量运算符

int n=5;

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

Output =6

输出= 6

#5


2  

They are generally the same and there is no significance to clarify the difference between them. But the implementing of these two statement are in fact different. For example, a+=1 compiling to assember is
add a,1
and a++ or ++a is
inc a
There may be some mildly difference in efficiency because they are two different CPU operation.

它们通常是相同的,没有必要去澄清它们之间的区别。但这两种说法的实施实际上是不同的。例如,将+=1编译为assember就是添加了a、1和a++或++ +a是inc。

#6


2  

Some of you are approaching the difference, but it should be stated very clearly:

你们中有些人正在接近这种差别,但应该非常明确地指出:

THEY ARE VERY DIFFERENT OPERATORS.

它们是非常不同的运算符。

The preincrement and postincrement operators are designed to be used INSIDE EXPRESSIONS to change the value of the variable either BEFORE or AFTER the value of the variable is used in whatever expression encloses it. When using the postincrement operator the OLD value of the variable is used to evaluate the enclosing expression and only after that is the variable incremented.

预递增和后递增操作符被设计为在表达式中使用,以在变量的值被包含在任何表达式之前或之后更改变量的值。使用后增量运算符时,将使用变量的旧值来计算封闭表达式,然后才对变量进行递增。

For example:

例如:

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

This is why it is called the postincrement operator. The variable is incremented POST (AFTER) it's value is used in the greater expression (here an assignment expression).

这就是为什么它被称为postincrement运算符。变量的值是递增的POST (AFTER),它的值用在更大的表达式中(这里是赋值表达式)。

However, if you do:

然而,如果你做的事:

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.

#7


2  

These two operators may appear to be similar, but they are quite different.

这两个操作符可能看起来很相似,但它们是完全不同的。

For primitive types (pointers, integers, etc.) they both increment the value by one. But, for C++ classes, they call different operators (operator+= vs. operator++); indeed, for some classes, like list<T>::iterator, i += 1 does not work and i++ must be used.

对于原始类型(指针、整数等),它们都将值增加1。但是,对于c++类,它们调用不同的操作符(操作符+= vs.操作符+);实际上,对于某些类,比如list ::iterator, i+ = 1不起作用,必须使用i++ ++。

Furthermore, they produce different values. i += 1 produces i after incrementing (like a preincrement), while i++ produces i before incrementing. Thus,

此外,它们产生不同的价值。i+ = 1在递增后生成i(比如递增),而i++在递增之前生成i。因此,

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

prints 1 0. Because i += 1 is equivalent to a preincrement, in some cases, i += 1 may result

打印1 0。因为i += 1等于一个前增量,在某些情况下,i += 1可能是结果

So, while they are the same for incrementing variables, one should be aware that they are not perfect substitutes in all conditions.

因此,虽然它们对于递增变量是相同的,但是我们应该意识到它们并不是所有条件下的完美替代品。

#8


1  

I am surprised noone mentions that at least for old compilers / computers (basically when C was born and a decade or two after) += 1 will be significantly slower than ++. ++ is an increment which the CPU most likely has a single instruction for. += 1 requires loading the value 1 into a register (likely saving the value of it... somewhere) and calling for an addition. I can't say whether current compilers optimize this out but I suspect they do.

我很惊讶没有人提到,至少对于旧的编译器/计算机(基本上是在C诞生的时候,10年或20年后),+= 1将明显地比++慢。++是CPU很可能只有一条指令的增量。+= 1需要将值1加载到寄存器中(可能保存它的值…在某个地方)并要求增加。我不能说当前的编译器是否对它进行了优化,但我怀疑它们确实进行了优化。

#9


1  

I'm new to * but here's my 2 pence worth.

我刚到*,这是我的2便士。

If the question is about += and not +=1. The statement posted was;

如果问题是关于+=而不是+=1。该声明发布;

I usually encounter situations to use ++ or +=1, but I can't tell their difference.

我经常遇到用+或+=1的情况,但是我分不清它们的区别。

I think the 1 could just have easily been another number or perhaps better written as +=?

我认为1可以很容易地写成另一个数字或者写成+=?

In terms of the result there is no difference (using the posters values). Both will increment by one, however, ++ will only increment by 1 whereas += will increment by the value specified by the coder, in ederman's example this happens to be 1. For Example:

在结果上没有区别(使用海报的值)。两者都将增加1,然而,++将只增加1,而+=将增加编码者指定的值,在ederman的例子中,这恰好是1。例如:

// 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

So if you only want to increment a value by 1 I would use ++ but if you need to increment by more the 1 use +=

如果你想让一个值增加1,我就用++但是如果你想增加1,就用+=

Hope that is useful.

希望是有用的。

#10


0  

++ is used to increment value by 1, while using += you can increment by another amount.

++被用来增加1的值,同时使用+=你可以增加一个量。