#include <iostream> using namespace std; int main() { int a,b; a=5; a=a+(a++); cout<<a<<endl; a=5; b=a+(a++); cout<<b<<endl; return 0; }
vs2010下输出11,10.不过导致输出结果不同的原因是什么?求一个详细的解释
C和C++标准里都明确说明了a=a++;
这种表达式的结果是未定义的,也就说,编译器厂商可以自己决定这个表达式的运算顺序。所以,用VC编译出来的代码输出11,10,原因Yang Fang已经说明了,而用GCC编译输出的结果是10,10。其他更严格的语言例如C#和Java的输出结果都是10。
自加运算在不同的语言里会有不一样的解释,你在java中就会发现两个都是10,我觉得这个挺误导人的,python、go中都没有这个了,没啥意义。C里面的这个,我觉得可以理解成那个++运算发生在赋值运算之后,而java中发生在赋值运算之前,所以被赋值运算覆盖了。我真的闲的蛋疼了看了一下代码(砍掉无关的,只留下这段计算):
movq %rsi, %rax movl %edi, %ecx movl %ecx, -4(%rbp) movq %rax, -16(%rbp) movl $5, -28(%rbp) movl -28(%rbp), %eax movl -28(%rbp), %ecx addl %ecx, %eax movl %eax, -28(%rbp) movl -28(%rbp), %eax addl $1, %eax movl %eax, -28(%rbp) movl -28(%rbp), %eax xorb %cl, %cl leaq L_.str(%rip), %rdx movq %rdx, %rdi movl %eax, %esi movb %cl, %al callq _printf movl $5, -28(%rbp) movl -28(%rbp), %ecx movl -28(%rbp), %edx addl %edx, %ecx movl %ecx, -32(%rbp) movl -28(%rbp), %ecx addl $1, %ecx movl %ecx, -28(%rbp) movl -32(%rbp), %ecx xorb %dl, %dl leaq L_.str1(%rip), %rdi movl %ecx, %esi movb %dl, %al callq _printf movl $0, -24(%rbp) movl -24(%rbp), %eax movl %eax, -20(%rbp) movl -20(%rbp), %eax addq $32, %rsp popq %rbp ret
第一个算式中加1操作在这里:
movl -28(%rbp), %eax addl $1, %eax movl %eax, -28(%rbp)
从开头就能看到-28(%rbp)
就是变量a的内存位置
第二个算式中加1操作在这里:
movl -28(%rbp), %ecx addl $1, %ecx movl %ecx, -28(%rbp)
而变量b的地址是-32(%rbp)
,当然不会被这个加1操作影响了
#include <iostream> using namespace std; int main() { int a,b; a=5; a=a+(a++); cout<<a<<endl; a=5; b=a+(a++); cout<<b<<endl; cout<<a<<endl; // 你觉得这行还会输出 5 么 ..? return 0; }
代码解释一切 ...