关于 C 语言 i++与++i 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
speed

关于 C 语言 i++与++i 的问题

  •  
  •   speed Aug 24, 2015 3946 views
    This topic created in 3904 days ago, the information mentioned may be changed or developed.

    int a,b;

    int i=10 , j=10;

    a=(i++)+(i++)+(i++);

    b=(++j )+(++j )+(++j );

    a 与 b 的值,一直没搞明白!!!

    33 replies    2015-08-24 20:22:38 +08:00
    abscon
        1
    abscon  
       Aug 24, 2015
    建议帖主换 C 语言教材。

    关注点不对
    book1925
        2
    book1925  
       Aug 24, 2015
    i++是运算完后 i 再+1 。
    所以 a=10+10+10=30.
    然后 i 再变为 11

    ++i 是运算之前 i 就已经+1 。
    所以 b=11+11+11=33.
    canautumn
        3
    canautumn  
       Aug 24, 2015
    Undefined Behavior
    speed
        4
    speed  
    OP
       Aug 24, 2015
    这不是 C 教材上的,只是最近看了篇贴在由这个衍生到 2 个概念顺序点和副作用,所以一直没搞明白这题是怎么算的。。。
    @abscon
    speed
        5
    speed  
    OP
       Aug 24, 2015
    用 visual C++6.0 测下来 b 的值为 37
    @book1925
    RecursiveG
        6
    RecursiveG  
       Aug 24, 2015
    1. 不同的编译器会有不同的结果
    2. 不要写这样的代码
    3. 换教材 +1
    4. 如果非要搞明白,搜“ Undefined Behavior ”
    crab
        7
    crab  
       Aug 24, 2015
    钻牛角尖
    kokdemo
        8
    kokdemo  
       Aug 24, 2015
    @speed 我觉得意思是这样的,每次++j 的时候 j 都已经自增了……

    所以 b = 11+12+13 = 36
    多出来的 1 不知道哪里来的……
    lingo233
        9
    lingo233  
       Aug 24, 2015
    看编译器,不知道会是什么。
    b821025551b
        10
    b821025551b  
       Aug 24, 2015 via Android   1
    这种谭浩强 style 的问题不需要去考虑
    book1925
        11
    book1925  
       Aug 24, 2015
    @speed
    本人也比较才疏学浅,刚才的回答确实有问题,还是以其他有经验的人的回答为准吧
    speed
        12
    speed  
    OP
       Aug 24, 2015
    VisaulC++6.0 则会先计算前两个 i 的值为 12 ,第三个 i 的值变成了加三次以后的值为 13 ,因此结果是 12+12+13=37 。作者是这样回答的。。。
    @kokdemo 我也没看懂,呵呵
    publicID001
        13
    publicID001  
       Aug 24, 2015 via Android
    Modifying a variable more than one time in a expression is asking for trouble.
    speed
        14
    speed  
    OP
       Aug 24, 2015
    @b821025551b
    @crab
    @abscon
    @canautumn
    谢谢,现实中肯定不会出现这种引起混乱的代码,只是想自己分析下,呵呵
    lissome
        15
    lissome  
       Aug 24, 2015
    a 是计算后再 i = i + 1 三次,所以 a 是 30
    b 是先 j = j + 1 三次,再计算,所以 b 是 39
    seki
        16
    seki  
       Aug 24, 2015
    不要搞这些花活,这种代码除了炫以外,就剩下坑了
    leavic
        17
    leavic  
       Aug 24, 2015
    C 的问题看汇编可解
    ljbha007
        18
    ljbha007  
       Aug 24, 2015
    这种代码审核的时候会被毙掉
    airbnber
        19
    airbnber  
       Aug 24, 2015
    @speed 书没错,只是这题目挖了一个小坑,赋值之后确实应该是 33 和 37
    Kilerd
        20
    Kilerd  
       Aug 24, 2015
    目测又是谭浩强害死人。
    ```c
    int a,b;

    int i=10 , j=10;

    a=(i++)+(i++)+(i++);

    //等价于
    a = i + i + i;
    i++;
    i++;
    i++;

    b=(++j )+(++j )+(++j );

    //等价于
    ++j;
    b = j;

    ++j;
    b += j;
    ++j;
    b += j;
    ```

    换教程把。
    BTW,谭浩强的书就别看了

    C 分两种。一种是谭浩强的 C ,一种是 C
    speed
        21
    speed  
    OP
       Aug 24, 2015
    @Kilerd
    谢谢,你这样一写豁然开朗啊
    qwlhappy
        22
    qwlhappy  
       Aug 24, 2015
    感觉顺序点和编译器关系很大
    似乎有一些顺序点是标准 c 里面有规定的,就好像分号,或者其他一些杂七杂八的东西
    似乎相关博客很多?搞不懂的话不如直接看汇编咯
    broodnes
        23
    broodnes  
       Aug 24, 2015
    我晕了, vs2015 的结果是 a=30 , b=39
    wwwqq2com
        24
    wwwqq2com  
       Aug 24, 2015
    不要再用 VC6.0 了,这玩意儿比 C++标准出现还早
    loading
        25
    loading  
       Aug 24, 2015 via Android
    我帮你问下大家:
    ++i ,这玩意大家有几次会用?
    zcbenz
        26
    zcbenz  
       Aug 24, 2015
    怎么还有问这种问题的,楼上凡是尝试解释结果的都应该去看看这个:
    http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points
    leoe
        27
    leoe  
       Aug 24, 2015
    a=(i++)+(i++)+(i++);

    b=(++j )+(++j )+(++j );
    谁要这么写代码,我掐死他。
    danny200309
        28
    danny200309  
       Aug 24, 2015
    @zcbenz 其实 6 楼早就说出了问题的关键,楼主没有注意吧
    FrankFang128
        29
    FrankFang128  
       Aug 24, 2015
    把写出这样代码的人开除即可,不需要明白。
    fds
        30
    fds  
       Aug 24, 2015
    标准里没有定义这种操作的顺序,所以怎么实现都可以,出现什么结果都正常。总之就是不要用。
    Kilerd
        31
    Kilerd  
       Aug 24, 2015   1
    @loading
    ```c
    for (int i=0;i<10;++i ){}
    ```

    一般我都会这样写。
    虽然这里写 i++ 和 ++i 都没差。
    但是逻辑不能乱
    dacapoday
        32
    dacapoday  
       Aug 24, 2015 via Android
    加一个编译器结果:
    用安卓的 c4droid
    a 为 33
    b 为 36
    msg7086
        33
    msg7086  
       Aug 24, 2015
    返回 30 也好 300 也好 1234567 也好都是正常的。
    甚至产生编译错误也是正常的。
    因为严格说这不属于合法 C 代码(因为无法唯一地编译成机器语言)。
    About     Help     Advertise     Blog     API     FAQ     Solana     2322 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 78ms UTC 05:33 PVG 13:33 LAX 22:33 JFK 01:33
    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