#include <stdio.h>
main() {
int i=3,j;
j=++i*++i*++i;
printf("%d,%d",i,j);
}
答案即将到来,i = 6,j = 150 请解释为什么j出现150 ??
答案 0 :(得分:9)
答案 1 :(得分:2)
编译器中的j=++i*++i*++i
将分解为1:(++i*++i)*++i
,然后它将计算左操作数,然后计算右操作数。左边的是一个括号,所以它会看到里面的东西。 ++i*++i
将被评估为(++i)*(++i)
,然后编译器将计算左右操作数,然后它将进行乘法运算。左操作数会将i
增加1并返回i
,右操作数会将i
增加1并返回i
。因此,我们在i*i
表达式的第一个括号中得到1
,i
为5
,因此它将返回25
。现在我们得到(25)*(++i)
,编译器检查两个操作数,左边一个返回25
,右边一个增加i
一个并返回i
,i
现在是{{ 1}}所以我们得到了6
。这就是gcc的工作原理
答案 2 :(得分:1)
结果实际上取决于编译器。
我用gcc和clang编译了它。 Gcc输出150,而clang输出120。
但是反汇编可以说明为什么j = 150:
movl $0x3,-0xc(%rbp) // i = 3
movl $0x0,-0x10(%rbp) // j = 0
mov -0xc(%rbp),%eax // %eax = i = 3
add $0x1,%eax // %eax += 1, %eax = 4
mov %eax,-0xc(%rbp) // move %eax back to i, ie i = 4
mov -0xc(%rbp),%eax // %eax = i = 4
add $0x1,%eax // %eax = 5
mov %eax,-0xc(%rbp) // move %eax back to i, ie i = 5
mov -0xc(%rbp),%eax // store i in %eax
mov -0xc(%rbp),%ecx // store i in %ecx
imul %ecx,%eax // %eax * %ecx, %eax = 5*5 = 25
mov -0xc(%rbp),%ecx // store i in %ecx
add $0x1,%ecx // %ecx + 1, %ecx = 6
mov %ecx,-0xc(%rbp) // move %ecx back to i, ie i = 6
mov -0xc(%rbp),%ecx // store i in %ecx
imul %ecx,%eax // %eax * %ecx, %eax = 6*25=150
mov %eax,-0x10(%rbp) // move %eax to j, ie j = 150