今天遇到一个问题
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中编译错误