c ++-“ ++”和“ + = 1”运算符有什么区别?

在C ++中的循环中,我通常会遇到使用numnum++的情况,但是我无法分辨它们的区别。 例如,如果我有一个整数

int num = 0;

然后循环执行:

num ++;

要么

num += 1;

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

E_learner asked 2020-07-28T22:50:59Z
10个解决方案
82 votes

++num等效于num += 1

所有这些表达式(++numnum += 1++num)将num的值加1,但是num++的值是num递增之前的值。

插图:

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

使用任何取悦您的东西。 我更喜欢++num而不是num += 1,因为它更短。

Alexandre C. answered 2020-07-28T22:51:38Z
21 votes

前缀和后缀操作是考试问题的理想选择。

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

*=操作及其姐妹/=是更通用的解决方案,主要旨在用于不同数量。 甚至可以说与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;
}

*=中进行拆解,将得到:

第一种情况(*=)(不同)

(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.

第二种情况(*=

(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.

第三种情况(*=

(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.

第四例(*=

(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.

如您所见,即使没有打开编译器优化,它们也会产生相同的机器代码,除了第一种情况在/=s之后有*=。 这意味着您应该以用户喜欢的方式使用任何内容,而让编译器人员完成其余的工作。

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

none answered 2020-07-28T22:52:34Z
10 votes

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

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

或前缀:

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

如果这样使用,它们是相同的:

int a = 0;
++a; // 1
a++; // 2
a += 1; // 3
dreamzor answered 2020-07-28T22:53:03Z
6 votes

两个运算符都将n的值加1。当您将这些运算符与赋值运算符一起使用时,它们之间存在差异。

例如:

第一种情况-后增量运算符

int n=5;
int new_var;

new_var=n++;

print("%d",new_var);

输出= 5

第二种情况

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

输出= 6

这与预增量运算符将产生的结果非常相似。

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

int n=5;

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

输出= 6

Desert Ice answered 2020-07-28T22:53:57Z
2 votes

它们通常是相同的,没有意义来阐明它们之间的区别。 但是这两个语句的实现实际上是不同的。例如,a + = 1编译为assember是
加a,1
而a或++ a是
公司
由于它们是两个不同的CPU操作,因此效率可能会有一些轻微的差异。

bigfish answered 2020-07-28T22:54:35Z
2 votes

你们中的一些人正在接近差异,但是应该非常清楚地说明:

他们是非常不同的运营商。

可以将preincrement和postincrement运算符设计为在表达式内部使用,以在变量所包含的任何表达式中使用变量之前或之后更改变量的值。 使用postincrement运算符时,变量的OLD值用于评估封闭表达式,只有在此之后,变量才会递增。

例如:

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

这就是为什么它被称为后增量运算符。 该变量递增POST(AFTER),其值用于较大的表达式(此处为赋值表达式)。

但是,如果您这样做:

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.
Tom Wetmore answered 2020-07-28T22:55:17Z
2 votes

这两个运算符可能看起来很相似,但是却有很大不同。

对于基本类型(指针,整数等),它们都将值加1。 但是,对于C ++类,它们调用不同的运算符(operator+=operator++); 实际上,对于某些类,例如list<T>::iterator1 0不起作用,必须使用i += 1

此外,它们产生不同的值。 1 0在递增后(如预递增)产生i += 1,而i += 1在递增前产生i。 从而,

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

打印1 0。由于i += 1相当于预增量,因此在某些情况下,可能会导致i += 1

因此,尽管它们在增加变量方面是相同的,但应注意,它们并不是在所有条件下的完美替代品。

nneonneo answered 2020-07-28T22:55:56Z
1 votes

令我惊讶的是,没有人提到至少对于旧的编译器/计算机(基本上是C诞生以及之后的十年或两年),+= 1的速度将明显慢于2987003305982952952449。++是CPU最有可能使用单个指令的增量。 += 1需要将值1加载到寄存器中(可能将它的值保存在某处)并要求加法。 我不能说当前的编译器是否对此进行了优化,但我怀疑他们可以。

chx answered 2020-07-28T22:56:16Z
1 votes

我是Stackoverflow的新手,但是这是我的2便士。

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

我通常会遇到使用++或+ = 1的情况,但是我无法分辨它们的区别。

我认为1可能很容易就是另一个数字,或者更好地写成+ =?

就结果而言,没有区别(使用海报值)。 两者都将增加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

因此,如果您只想将值增加1,则可以使用++,但如果需要增加1,则可以使用+ =

希望是有用的。

Kevin Morrissey answered 2020-07-28T22:57:03Z
0 votes

++用于将值增加1,而使用+ =则可以增加另一个值。

Alfa3eta answered 2020-07-28T22:57:23Z
translate from https://stackoverflow.com:/questions/12988140/what-is-the-difference-between-and-1-operators