尽量不要在一个语句中对相同变量用两次或以上个自增减运算符
上一篇文章中,我提到 i++ 在一个语句里出现了 3 次的情况,似乎解释起来很轻松。但是今天我又多想了一下,如果 C 还讲究对称之美的话,++i 也应该在语句执行之前就执行。所以刚才我做了一个测试:
1 2 3 4 5 6 | int i = 3; int j = (i++) + (i++) + (i++); printf("%d %d\n", i, j); i = 3; j = (++i) + (++i) + (++i); printf("%d %d\n", i, j); |
本来我的预期有两种,一种就是最后 j 会是 18(3 个 ++i 都在语句之前执行了,所以是 6 + 6 + 6),一种就是会是 15(3 个 ++i 分别是 4, 5, 6)。g++ 给的结果居然是:
6 9 6 16
啊!g++ 你让我是情何以堪呐!第一个结果给我个 9 就算了,还算可以被 3 整除,还好解释一些;但是第二个结果是 16, 不能被 3 整除,所以我们无法写出连续的 3 个数的和是 16 的。那这 3 个 (++i) 分别是什么呢……
为了知道这 3 个 (++i) 到底代表了什么数,我写了下面的程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> int test(int a, int b) { printf("(%d %d)\n", b, a); return a; } int main(int argc, char *argv[]) { int i = 3; int j = test(i++, 0) + test(i++, 1) + test(i++, 2); printf("%d %d\n", i, j); i = 3; j = test(++i, 3) + test(++i, 4) + test(++i, 5); printf("%d %d\n", i, j); return 0; } |
结果让我更蛋疼的事情出现了,输出结果居然是我预想的那种和谐盛世才有的东西:
(0 3) (1 4) (2 5) 6 12 (3 4) (4 5) (5 6) 6 15
这不就是我最初的和谐的想法吗?为什么在加号之间套了一些函数就变得这么和谐了?难道加号与自增减之间有一些什么微妙的关系吗?
我觉得编译器这样编译代码,与 C++ 的运算符重写的思想是有很大不同的。看来我的“函数一统表达式的天下”的愿望还是没有实现…… 所以我们目前能做的只是,尽量避免在同一个语句中对同一个变量使用两个或两个以上的自增减操作。

自增减操作似乎Pascal没有,或者说只有个不知道什么原理的inc() dec().
那个16我也不知是什么原理,但是后面加了函数是你强制让他按照某个先后顺序运行,那么6 12,6 15也是情理之中的事。