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

2019-02-06 21:26:46 +08:00
 nyse
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

4250 次点击
所在节点    C
14 条回复
momocraft
2019-02-06 21:32:45 +08:00
c 沒有規定多個參數被求值的順序, 對這個觀測的直接回答只能是"因爲編譯器這樣做".

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

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

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

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

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

不过还真不明白,我在三个平台下都是用 GCC,居然也不一样。
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
2019-02-07 09:41:17 +08:00
这种考试题挺脑残的……特别是编译器到现在还是 Turbo C ……
MrVito
2019-02-07 10:55:02 +08:00
看看 gcc 的版本吧
ipwx
2019-02-07 19:48:56 +08:00
@nyse Turbo C 从右到左。。这句话好评。难得看到这么有水平的出题人了。
jedihy
2019-02-08 08:39:18 +08:00
这样的代码不是 human readable 的
unlighted
2019-02-08 13:16:30 +08:00
压栈的时候,从右往左压,后缀的增减会被保留到最后进行计算,++i+j-- 这个时候就是 11+9,j++之后因为有 j--,所以被抵消了,即为 10
NULLSTRING
2019-02-13 15:02:53 +08:00
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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/533234

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX