上一篇文章中,我提到 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) 分别是什么呢……
学 C/C++ 的童鞋应该都知道 ++i 和 i++ 的区别。开始的时候,我们会这样理解:++i 是让 i 自己增加 1 之后再使用 i 的新值,i++ 是在使用 i 的值之后再让 i 自身增加 1. 这样模糊的说法让这个 i 自增 1 的过程变得充满神秘。人类总是对神秘的东西怀有兴趣,探索的过程就是这样开始的。
但是 i 的自增究竟是什么时候进行的,这个问题困扰了我很久。直到我学到 C++ 的运算符和强制类型转换重写的时候,我开始把一切都看成函数。我经常把基础的数据类型看成类,然后为这些类 YY 出一些实现代码,觉得这一切都合情合理和谐美好。这时我对 ++i 和 i++ 的理解就是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class int { /* Some harmonious code */ public: int operator++(int foo) // i++ { foo = *this; *this = *this + 1; return foo; } int &operator++() // ++i { *this = *this + 1; return *this; } }; |