E_l*_*ner 45 c++ integer loops increment auto-increment
在C++的循环中,我经常遇到要使用的情况,++或者+=1我无法区分它们.例如,如果我有一个整数
int num = 0;
Run Code Online (Sandbox Code Playgroud)
然后在循环中我做:
num ++;
Run Code Online (Sandbox Code Playgroud)
要么
num += 1;
Run Code Online (Sandbox Code Playgroud)
他们都增加了价值num,但他们的区别是什么?我怀疑num++可以比工作更快num+=1,但如何?这种差异是否足以被忽视?
Ale*_* C. 84
num += 1相当于++num.
所有这些表达式(num += 1,num++和++num)增加值num的一个,但价值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
Run Code Online (Sandbox Code Playgroud)
用你喜欢的任何东西.我喜欢++num到num += 1,因为它是短.
non*_*one 22
前缀和后缀操作是考试问题的完美候选者.
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
Run Code Online (Sandbox Code Playgroud)
+=操作及其姐妹-=是更通用的解决方案,主要用于不同的数字.有人甚至可能会说它们在使用时是多余的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;
}
Run Code Online (Sandbox Code Playgroud)
并拆解gdb其中会给:
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>: 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.
Run Code Online (Sandbox Code Playgroud)
++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.
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,即使没有打开编译器优化,它们也会生成相同的机器代码,除了第一个具有s addl之后mov的情况.这意味着您应该使用任何您喜欢的用户,并让编译器人员完成剩下的工作.
最后,请注意表兄经营者*=并/=没有后缀和前缀对应物.
dre*_*zor 10
的++前缀或后缀运算符改变变量值.
int a = 0;
int b = a++; // b is equal to 0, a is equal to 1
Run Code Online (Sandbox Code Playgroud)
或前缀:
int a = 0;
int b = ++a; // b = 1, a = 1
Run Code Online (Sandbox Code Playgroud)
如果像这样使用,它们是相同的:
int a = 0;
++a; // 1
a++; // 2
a += 1; // 3
Run Code Online (Sandbox Code Playgroud)
两个运算符都将n的值增加1.当您将运算符与赋值运算符一起使用时,它们之间存在差异.
例如:
第一种情况 - 后增量运算符
int n=5;
int new_var;
new_var=n++;
print("%d",new_var);
Run Code Online (Sandbox Code Playgroud)
输出= 5
第二个案例
int n=5;
n+=1;
new_var=n;
print("%d",new_var);
Run Code Online (Sandbox Code Playgroud)
输出= 6
这与预增量运算符的结果非常相似.
第二种情况使用预增量运算符
int n=5;
new_var=++n;
print("%d",new_var);
Run Code Online (Sandbox Code Playgroud)
输出= 6