关于 C 语言 i++与++i 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
speed
V2EX    问与答

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

  •  
  •   speed 2015-08-24 10:43:24 +08:00 3781 次点击
    这是一个创建于 3791 天前的主题,其中的信息可能已经有所发展或是发生改变。

    int a,b;

    int i=10 , j=10;

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

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

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

    33 条回复    2015-08-24 20:22:38 +08:00
    abscon
        1
    abscon  
       2015-08-24 10:47:30 +08:00
    建议帖主换 C 语言教材。

    关注点不对
    book1925
        2
    book1925  
       2015-08-24 10:48:41 +08:00
    i++是运算完后 i 再+1 。
    所以 a=10+10+10=30.
    然后 i 再变为 11

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

    所以 b = 11+12+13 = 36
    多出来的 1 不知道哪里来的……
    lingo233
        9
    lingo233  
       2015-08-24 10:56:04 +08:00
    看编译器,不知道会是什么。
    b821025551b
        10
    b821025551b  
       2015-08-24 10:57:01 +08:00 via Android   1
    这种谭浩强 style 的问题不需要去考虑
    book1925
        11
    book1925  
       2015-08-24 11:00:41 +08:00
    @speed
    本人也比较才疏学浅,刚才的回答确实有问题,还是以其他有经验的人的回答为准吧
    speed
        12
    speed  
    OP
       2015-08-24 11:01:34 +08:00
    VisaulC++6.0 则会先计算前两个 i 的值为 12 ,第三个 i 的值变成了加三次以后的值为 13 ,因此结果是 12+12+13=37 。作者是这样回答的。。。
    @kokdemo 我也没看懂,呵呵
    publicID001
        13
    publicID001  
       2015-08-24 11:02:53 +08:00 via Android
    Modifying a variable more than one time in a expression is asking for trouble.
    speed
        14
    speed  
    OP
       2015-08-24 11:04:34 +08:00
    @b82102551b
    @crab
    @abscon
    @canautumn
    谢谢,现实中肯定不会出现这种引起混乱的代码,只是想自己分析下,呵呵
    lissome
        15
    lissome  
       2015-08-24 11:18:59 +08:00
    a 是计算后再 i = i + 1 三次,所以 a 是 30
    b 是先 j = j + 1 三次,再计算,所以 b 是 39
    seki
        16
    seki  
       2015-08-24 11:20:53 +08:00
    不要搞这些花活,这种代码除了炫以外,就剩下坑了
    leavic
        17
    leavic  
       2015-08-24 11:22:37 +08:00
    C 的问题看汇编可解
    ljbha007
        18
    ljbha007  
       2015-08-24 11:30:41 +08:00
    这种代码审核的时候会被毙掉
    airbnber
        19
    airbnber  
       2015-08-24 11:49:12 +08:00
    @speed 书没错,只是这题目挖了一个小坑,赋值之后确实应该是 33 和 37
    Kilerd
        20
    Kilerd  
       2015-08-24 11:54:28 +08:00
    目测又是谭浩强害死人。
    ```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
       2015-08-24 12:34:23 +08:00
    @Kilerd
    谢谢,你这样一写豁然开朗啊
    qwlhappy
        22
    qwlhappy  
       2015-08-24 12:40:34 +08:00
    感觉顺序点和编译器关系很大
    似乎有一些顺序点是标准 c 里面有规定的,就好像分号,或者其他一些杂七杂八的东西
    似乎相关博客很多?搞不懂的话不如直接看汇编咯
    broodnes
        23
    broodnes  
       2015-08-24 12:42:03 +08:00
    我晕了, vs2015 的结果是 a=30 , b=39
    wwwqq2com
        24
    wwwqq2com  
       2015-08-24 13:00:43 +08:00
    不要再用 VC6.0 了,这玩意儿比 C++标准出现还早
    loading
        25
    loading  
       2015-08-24 13:07:05 +08:00 via Android
    我帮你问下大家:
    ++i ,这玩意大家有几次会用?
    zcbenz
        26
    zcbenz  
       2015-08-24 13:11:00 +08:00
    怎么还有问这种问题的,楼上凡是尝试解释结果的都应该去看看这个:
    http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points
    leoe
        27
    leoe  
       2015-08-24 13:17:54 +08:00
    a=(i++)+(i++)+(i++);

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

    一般我都会这样写。
    虽然这里写 i++ 和 ++i 都没差。
    但是逻辑不能乱
    dacapoday
        32
    dacapoday  
       2015-08-24 14:02:05 +08:00 via Android
    加一个编译器结果:
    用安卓的 c4droid
    a 为 33
    b 为 36
    msg7086
        33
    msg7086  
       2015-08-24 20:22:38 +08:00
    返回 30 也好 300 也好 1234567 也好都是正常的。
    甚至产生编译错误也是正常的。
    因为严格说这不属于合法 C 代码(因为无法唯一地编译成机器语言)。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1086 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:10 PVG 02:10 LAX 10:10 JFK 13:10
    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