自加运算符

 

今天遇到一个问题

    int i =3,j;
    j = (++i) + (++i) + (++i);
    printf("%d",j);


打印结果是 16

_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	andl	$-16, %esp
	movl	$0, %eax
	addl	$15, %eax
	addl	$15, %eax
	shrl	$4, %eax
	sall	$4, %eax
	movl	%eax, -12(%ebp)
	movl	-12(%ebp), %eax
	call	__alloca
	call	___main
	movl	$3, -4(%ebp)
	leal	-4(%ebp), %eax
	incl	(%eax)
	leal	-4(%ebp), %eax
	incl	(%eax)
	movl	-4(%ebp), %eax
	movl	-4(%ebp), %edx
	addl	%eax, %edx
	leal	-4(%ebp), %eax
	incl	(%eax)
	movl	%edx, %eax
	addl	-4(%ebp), %eax
	movl	%eax, -8(%ebp)
	movl	-8(%ebp), %eax
	movl	%eax, 4(%esp)
	movl	$LC0, (%esp)
	call	_printf
	movl	$0, %eax
	leave
	ret


可以看出,中间过程是:

3被加了两次,变成5,然后将5分别赋给%eax和%edx,将相加的结果10赋给%edx,然后让5加了1次1,这样就变成了16。

我使用的编译器对于 j=(++i)+(++i) 和 j=(++i) + (++i) + (++i) + (++i)的结果分别是 10 和 23

所以它是先将i自加两次,然后对i的值进行加1运算。

 

另外,对于

int x = 20, y = 35, z;
    z = y++ + x++;

z的输出为55

和

int x = 20, y = 35;
    x = y++ + x++;

x的输出为56

通过查看汇编代码,可以看到当z被赋值为x+y后,x和y才进行自加运算;而x被赋值为y+x后,由于是对x进行自加运算,所以,x的值又被加1

 

对于下列代码

int i=1;
i=(++i)++;

汇编得到

_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	andl	$-16, %esp
	movl	$0, %eax
	addl	$15, %eax
	addl	$15, %eax
	shrl	$4, %eax
	sall	$4, %eax
	movl	%eax, -8(%ebp)
	movl	-8(%ebp), %eax
	call	__alloca
	call	___main
	movl	$1, -4(%ebp)
	leal	-4(%ebp), %eax
	incl	(%eax)
	movl	-4(%ebp), %edx
	leal	-4(%ebp), %eax
	incl	(%eax)
	movl	%edx, -4(%ebp)
	movl	-4(%ebp), %eax
	movl	%eax, 4(%esp)
	movl	$LC0, (%esp)
	call	_printf
	movl	$0, %eax
	leave
	ret

可以看出,i被加1后,赋给了%edx,然后i又加1,但直接把%edx赋给了i,这样i的值就变成了2

可以想象,(++i)++ + i++ 的值为多少?

先++i,使i的值为2,然后将i+i,得到4,赋给i后,将i自加两次,得到6

 

注意:上述结果跟编译器有关,属于未定义的行为。

(++i)++  我在gcc 3.4.2中可以得到结果,但在gcc 4.4.3中编译错误

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值