C语言--x奇怪的问题

timxx 发布于 2012/06/29 09:08
阅读 2K+
收藏 1
#include <stdio.h>

int main()
{
    int w = 5;
    int x = 4;
    int y, z;

    y = w++ * w++ * w++;
    z = --x * --x * --x + y--;

    printf("%d\n", z);

    return 0;
 }


 

这么一小段程序,大家猜猜看输出多少?

结果竟然是129,白学C语言了都!

y得出的结果是125我没疑问,无语的是z的计算,

理论上--的比*优先,那么应该全部自减1后才乘的,结果应该是1 * 1 * 1 + 125 = 126的,

可事实上是2 * 2 * 1,为啥?

通过gcc -S得出的汇编代码片段如下:

  

    addl    $1, -16(%rbp)
    addl    $1, -16(%rbp)
    addl    $1, -16(%rbp)
    subl    $1, -12(%rbp)
    subl    $1, -12(%rbp)
    movl    -12(%rbp), %eax
    imull    -12(%rbp), %eax
    subl    $1, -12(%rbp)
    imull    -12(%rbp), %eax

   

其中-16(%rbp)是那个w,-12(%rbp)是x,

可以看到前面的w都是一次性++的,而后面的x,

却是先--两次,然后相乘,再--后再相乘,

为啥?

另外如果我再加一个* --x,变成--x * --x * --x * --x,

通过汇编,得出的都是前面两个先自减,然后相乘,

然后下一个自减,再与前者结果相乘,以此类推。。。

看来我C语言真的是不及格啊,求各位解答!

以下是问题补充:

@timxx:刚换Windows用vs2010测试发现,结果是126 汗啊,看汇编是先全部自减,看来这个都跟编译器有关 (2012/06/29 09:38)
加载中
0
Michael_Yuan
Michael_Yuan
其实楼主已经很深了
timxx
timxx
额,昨天帮一考二级C的童鞋复习时才注意到的 囧
0
Le_Guto
Le_Guto

为毛这样》》??

 

leo108
leo108
回复 @timxx : VC6.0是129,VS才会是126.VS的机制已经和VC不一样了
timxx
timxx
y=124因为在计算z的时候又减了一次,z为126这个在vc里面没的说,跟gcc的不一样
0
zaobao
zaobao
瞎了,我也白学c了。这种表达式换个编译器,结果就可能不一样,刚才翻了下谭浩强的书,里面就是这么说的。
timxx
timxx
确实如此,跟编译器有关的,平常时写程序应该没有人这样写这么一堆的吧,至少我没试过。。。
0
中山野鬼
中山野鬼

哈。。。 GCC的编译

z = --x * --x * --x

等同于

--x; --x;

z = x * x *(--x);

和哪个鬼栈的算法有关。名字忘了,有段时间没碰了。

 

leo108
leo108
后序表达式
0
中山野鬼
中山野鬼
不过还是建议楼主,有空揪这写,不如安心加 ()
timxx
timxx
嗯,这种玩意只适合考试。。。 我找到gcc相关说明了,前置++/--的是按对运算的,就是先计算完最前面的一对再用结果计算下一对 这跟vc的编译器不一样
0
泡不烂的凉粉
泡不烂的凉粉
在实际项目中。谁写出这么有歧义的代码批斗谁。
0
永远在一起

这里涉及到C语言的序列点问题,具体忘记了,总之就是在一个表达式中,同一个变量的值只能改变一次。否则就是行为未定义。

 

--x * --x * --x + y--

这里x都改变了三次了。

0
魔力猫
魔力猫
别折腾这个了。实际开发谁这么写谁脑残。
0
leo108
leo108

VC6.0是129,VS是126

VS的机制已经和VC不一样了

前一阵子准备面试,专门研究了下这个问题= =

timxx
timxx
哈,原来vc6又不一样,面试应该不会问这种问题的吧?
0
陈舵主
陈舵主

x输出结果可能是1,或者可能是4,和编译器有关

返回顶部
顶部