首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
宝塔
V2EX  ›  C/C++/Obj-C

关于 C 语言自增自减的问题?

  •  
  •   nyse · 284 天前 · 1988 次点击
    这是一个创建于 284 天前的主题,其中的信息可能已经有所发展或是发生改变。
    main()
    {
        int i = 10, j=10;
        
        int a = ++i+j++;
        int b = j--;
        printf("%d ,%d\n", a, b); //显然,此处输出为 21 ,11
    }
    

    但是以下代码:

    main()
    {
        int i = 10, j=10;
        printf("%d ,%d\n", ++i+j++, j--);
        //此处在 Linux ( Debian9) 使用 GCC 
        //以及 Windows 下使用 code blocks (应该是 MinGW 的 gcc )输出是 20,10 ;
        //而在 macOS ( Mojave )下使用 gcc,输出是 21,11
    }
    

    这是为什么?我原本自己推测也应该是 21,11

    14 回复  |  直到 2019-02-13 19:52:05 +08:00
        1
    momocraft   284 天前   ♥ 4
    c 沒有規定多個參數被求值的順序, 對這個觀測的直接回答只能是"因爲編譯器這樣做".

    不要面向巧合編程.
        2
    everwanna   284 天前 via iPhone   ♥ 2
    不建议写这样的代码。coding 的成就感来自于创造性的解决现实问题,而不是和编译器 CPU 捉迷藏
        3
    ipwx   284 天前   ♥ 2
    如果你要准备某个考试,就按答案来。

    C/C++ 标准并没有规定这方面的内容,是为了让各个编译器有充分自主的空间去优化最终程序。

    所以不要写这样的代码。
        4
    shintendo   284 天前   ♥ 2
    编程不是实验科学,编程有个概念是“未定义行为”。
    https://bbs.csdn.net/topics/370153775
        5
    inhzus   284 天前 via Android   ♥ 1
    编译器不同,printf 的运算顺序不同,所以尽量避免写这样的代码。
    解释一下 20,10
    从右往左,j--,输出 10,j=9
    ++i+j,输出 20,最后 j++
        6
    nyse   284 天前
    @momocraft
    @everwanna
    @ipwx

    是啊,这就是考试的题目,我也不支持这样写。

    而且题目是写着按照 “ Turbo C 从右到左”,要不是你们提醒我还真不知道这句话说的是求值顺序。

    不过还真不明白,我在三个平台下都是用 GCC,居然也不一样。
        7
    sdijeenx   284 天前
    对于:printf("%d ,%d\n", ++i+j++, j--);
    // MinGW 的 gcc 先计算 j--,再计算++i+j++;
    // macOS Mojave gcc 先计算++i+j++,再计算 j--。
        8
    skinny   283 天前
    这种考试题挺脑残的……特别是编译器到现在还是 Turbo C ……
        9
    MrVito   283 天前
    看看 gcc 的版本吧
        10
    ipwx   283 天前
    @nyse Turbo C 从右到左。。这句话好评。难得看到这么有水平的出题人了。
        11
    jedihy   282 天前
    这样的代码不是 human readable 的
        12
    unlighted   282 天前 via iPhone
    压栈的时候,从右往左压,后缀的增减会被保留到最后进行计算,++i+j-- 这个时候就是 11+9,j++之后因为有 j--,所以被抵消了,即为 10
        14
    junkman   277 天前
    If you using -Wall to compile above code, you would see multiple unsequenced modifications warning.

    ```
    $ gcc -Wall foobar.c
    foobar.c:6:29: warning: multiple unsequenced modifications to 'j' [-Wunsequenced]
    printf("%d ,%d\n", ++i+j++, j--);
    ^ ~~
    1 warning generated.
    ```

    In short, as @momocraft aforementioned, parameter evaluation order is unspecified, it depends on compiler implementation, i.e. it can be LR-evaluated or RL-evaluated.

    BTW, above code is extremely EVIL, as a guideline, [Don't be evil]( https://en.wikipedia.org/wiki/Don%27t_be_evil)

    see: https://stackoverflow.com/questions/34266773/language-c-compile-time-error-multiple-unsequenced-modifications-werror-wun
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   767 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 22:18 · PVG 06:18 · LAX 14:18 · JFK 17:18
    ♥ Do have faith in what you're doing.