首页 > a=a+(a++)和b=a+(a++)有什么区别

a=a+(a++)和b=a+(a++)有什么区别

#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;
}

代码解释一切 ...

【热门文章】
【热门文章】