c ++-“ ++”和“ + = 1”运算符有什么区别?
在C ++中的循环中,我通常会遇到使用num
或num++
的情况,但是我无法分辨它们的区别。 例如,如果我有一个整数
int num = 0;
然后循环执行:
num ++;
要么
num += 1;
它们都增加了num
的值,但是它们的区别是什么? 我怀疑num++
是否可以比num+=1
更快地工作,但是如何? 这种差异细微到足以被忽略吗?
++num
等效于num += 1
。
所有这些表达式(++num
、num += 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
,因为它更短。
前缀和后缀操作是考试问题的理想选择。
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之后有*=
。 这意味着您应该以用户喜欢的方式使用任何内容,而让编译器人员完成其余的工作。
最后,请注意表兄弟运算符*=
和/=
没有后缀和前缀对应项。
++
前缀或后缀运算符更改变量值。
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
两个运算符都将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
它们通常是相同的,没有意义来阐明它们之间的区别。 但是这两个语句的实现实际上是不同的。例如,a + = 1编译为assember是
加a,1
而a或++ a是
公司
由于它们是两个不同的CPU操作,因此效率可能会有一些轻微的差异。
你们中的一些人正在接近差异,但是应该非常清楚地说明:
他们是非常不同的运营商。
可以将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.
这两个运算符可能看起来很相似,但是却有很大不同。
对于基本类型(指针,整数等),它们都将值加1。 但是,对于C ++类,它们调用不同的运算符(operator+=
与operator++
); 实际上,对于某些类,例如list<T>::iterator
、1 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
因此,尽管它们在增加变量方面是相同的,但应注意,它们并不是在所有条件下的完美替代品。
令我惊讶的是,没有人提到至少对于旧的编译器/计算机(基本上是C诞生以及之后的十年或两年),+= 1
的速度将明显慢于2987003305982952952449。++
是CPU最有可能使用单个指令的增量。 += 1
需要将值1加载到寄存器中(可能将它的值保存在某处)并要求加法。 我不能说当前的编译器是否对此进行了优化,但我怀疑他们可以。
我是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,则可以使用+ =
希望是有用的。
++用于将值增加1,而使用+ =则可以增加另一个值。