V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
speed
V2EX  ›  问与答

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

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

    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
    @b821025551b
    @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
    iosx
        27
    iosx  
       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   ·   实用小工具   ·   1882 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:19 · PVG 00:19 · LAX 08:19 · JFK 11:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.