关于 C 语言自增自减的问题? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nyse
V2EX    C

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

  •  
  •   nyse 2019-02-06 21:26:46 +08:00 4917 次点击
    这是一个创建于 2529 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
    momocraft
        1
    momocraft  
       2019-02-06 21:32:45 +08:00   4
    c 有定多被求值的序, 的直接回答只能是"因器做".

    不要面向巧合程.
    everwanna
        2
    everwanna  
       2019-02-06 21:35:38 +08:00 via iPhone   2
    不建议写这样的代码。coding 的成就感来自于创造性的解决现实问题,而不是和编译器 CPU 捉迷藏
    ipwx
        3
    ipwx  
       2019-02-06 21:41:34 +08:00   2
    如果你要准备某个考试,就按答案来。

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

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

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

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

    不过还真不明白,我在三个平台下都是用 GCC,居然也不一样。
    sdijeenx
        7
    sdijeenx  
       2019-02-06 21:48:03 +08:00
    对于:printf("%d ,%d\n", ++i+j++, j--);
    // MinGW 的 gcc 先计算 j--,再计算++i+j++;
    // macOS Mojave gcc 先计算++i+j++,再计算 j--。
    skinny
        8
    skinny  
       2019-02-07 09:41:17 +08:00
    这种考试题挺脑残的……特别是编译器到现在还是 Turbo C ……
    MrVito
        9
    MrVito  
       2019-02-07 10:55:02 +08:00
    看看 gcc 的版本吧
    ipwx
        10
    ipwx  
       2019-02-07 19:48:56 +08:00
    @nyse Turbo C 从右到左。。这句话好评。难得看到这么有水平的出题人了。
    jedihy
        11
    jedihy  
       2019-02-08 08:39:18 +08:00
    这样的代码不是 human readable 的
    unlighted
        12
    unlighted  
       2019-02-08 13:16:30 +08:00 via iPhone
    压栈的时候,从右往左压,后缀的增减会被保留到最后进行计算,++i+j-- 这个时候就是 11+9,j++之后因为有 j--,所以被抵消了,即为 10
    NULLSTRING
        13
    NULLSTRING  
       2019-02-13 15:02:53 +08:00
    junkman
        14
    junkman  
       2019-02-13 19:52:05 +08:00
    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
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2315 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 15:54 PVG 23:54 LAX 07:54 JFK 10:54
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86