none
关于一个小程序的问题 RRS feed

  • 问题

  • 我刚写了这样一个程序
    i=3,b;
    b=i++*++i+i--*--i;
    printf("%d",b)
    我想的是b=3*5+5*3=30,可结果是b=18,让我很是费解,不知哪位高人肯不吝赐教。
    2010年1月14日 9:08

答案

  • 因为C++并没有对表达式具有多个sequence point的情况进行定义。所以如果在一个表达式中具有多个Sequence point的时候。结果是未定义的。所以尽量不要这样写。
    如果你看过VC++对于
    i =0;
    i = i++;
    那么根据i++表达式的意义。应该是返回0之后,再对i加1。实现应该是
    int operator++()
    {
        int temp = i;
        i = i +1;
        return temp;
    }
    按照上面的实现,结果应该是0。
    但是实际的结果1。
    因为这里有两个sequence point。
    在汇编中你可以看到,i=i++;首先返回i =0; 然后才对i进行加1操作的。所以如果一个表达式中如果有多个sequence point,结果是不确定的。
    在看你的表达式,首先我觉得没有太大的意义。
    b=i++*++i+i--*--i;
    i++在b被赋值、++i、i--、--i之前可能不会加1。也可能加1。
    ++i按照语义必须加1。
    而i--在b被赋值、--i之前可能不会减1,也可能不减1。
    所以这个结果的标准答案是不存在的。整个行为被视为未定义。
    非常鼓励楼主尝试看一下C++标准,建议看03标准,目前的0x标准没有一个编译器可以比较正确的实现,所以可能会耽误很多时间。

    麻烦把正确答案设为解答。
    • 已标记为答案 霁旻 2010年1月16日 1:10
    2010年1月15日 1:22
    版主

全部回复

  • 哎,很久没做这种BT题目了。 谁要是把这个写进程序的代码里,真的是纯属找抽。

    为了便于理解,上式可写做: b = (i++) * (++i) + (i--) * (--i);
    加括号是为了便于看得更清楚,不影响运算结果。 由此可知,i++、++i、i--、--i 的优先级是一样的,需要最先算。由i的初始值为3,可知用于运算的四个表达式值依次为: 3   4   3   2
    3*4+3*2 = 18

    2010年1月14日 10:14
    版主
  • 不是i++和i--是拿i的值先用后,再去让i值+1或-1给后边的i继续使用,我按照这种思路首先把i=3拿来用,然后i已经加1,把i=4给++i使用,而++i和--i这种是先将i+1或-1后使用,这样第二个i用的就是5,后边同理,现在我是这样想的,我现在请自述病情,请对症下药。

    2010年1月14日 10:29
  • 因为i++ ++i i-- --i 这四部份都是优先级一样的,因此应该同时算的。你有没有关注过这个表达式计算后i的值是多少啊?
    2010年1月14日 12:15
    版主
  • 这种表达式,也许换个编译器计算结果就变了也说不定。
    2010年1月14日 12:16
    版主
  • 因为C++并没有对表达式具有多个sequence point的情况进行定义。所以如果在一个表达式中具有多个Sequence point的时候。结果是未定义的。所以尽量不要这样写。
    如果你看过VC++对于
    i =0;
    i = i++;
    那么根据i++表达式的意义。应该是返回0之后,再对i加1。实现应该是
    int operator++()
    {
        int temp = i;
        i = i +1;
        return temp;
    }
    按照上面的实现,结果应该是0。
    但是实际的结果1。
    因为这里有两个sequence point。
    在汇编中你可以看到,i=i++;首先返回i =0; 然后才对i进行加1操作的。所以如果一个表达式中如果有多个sequence point,结果是不确定的。
    在看你的表达式,首先我觉得没有太大的意义。
    b=i++*++i+i--*--i;
    i++在b被赋值、++i、i--、--i之前可能不会加1。也可能加1。
    ++i按照语义必须加1。
    而i--在b被赋值、--i之前可能不会减1,也可能不减1。
    所以这个结果的标准答案是不存在的。整个行为被视为未定义。
    非常鼓励楼主尝试看一下C++标准,建议看03标准,目前的0x标准没有一个编译器可以比较正确的实现,所以可能会耽误很多时间。

    麻烦把正确答案设为解答。
    • 已标记为答案 霁旻 2010年1月16日 1:10
    2010年1月15日 1:22
    版主
  • 谢谢你的解答。我懂了

    2010年1月16日 1:12