WARNING: 完全摘自 c primer plus···劝导做,自己的笔记····
如果你企图一次使用太多的增量运算符,可能连自己都会弄糊涂。例如,你可能认为你可以改进 squares.c程序
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 /* squares.c --- 产生前 20个整数的平方表 */ 2 3 #include <stdio.h> 4 5 int main (void) 6 7 { 8 9 int num = 1; 10 11 while (num < 21) 12 13 { 14 15 printf ("%4d %6d \n",num,num*num); 16 17 num = num + 1; 18 19 } 20 21 getchar(); 22 23 return 0; 24 25 }
方法是使用下面的代码代替 while 循环来打印整数和它们的平方:
while (num <21>){ printf ("%10d %10d\n",num,num*num++); }
这看起来是合理的。你打印数值 num,然后用它本身来乘它已得到平方值,最后将 num 增加1。事实上,返个程序可能在某些系统上可以正常工作,但不是所有的系统上都可以。问题是当 printf()获取要打印的值时,它可能先计算最后一个参数的值,从而计算其它参数之前增加 num 的值。所以,不是打印成:
5 25
而是可能打印成:
6 25
在 C中,编译器可以选择先计算函数里哪个参数的值。这个自由提高了编译器的效率,但是如果在函数参数里使用了增量运算符就会带来麻烦。
另一个麻烦的可能来源是这样的语句:
ans = num / 2 + 5(1 + num++);
问题依然是编译器可能不按照你想象的顺序来操作。你可能认为编译器应该先找到 num/2, 然后继续进行,但是它可能先做最后的项目,即先增加 num 的值,然后在num/2 中使用新值。这些都是没有保证的。
另外一个麻烦的例子如下:
n = 3; y = n++ + n++;
虽然在该语句被执行后,n 的值比以前的大 2,但是 y 癿值是不确定的。一个编译器可能在计算 y 值时使用 n 的旧值两次,然后将 n 增加两次。这使 y 的值为 6, n 的值为 5 。 或者编译器使用 n 的旧值一次,然后增加 n 的值一次,在表达式里再使用第二个 n 值,最后第二次增加 n 的值。这种方法使 y 癿值为 7,n 癿值为 5 。两种选择都是允许癿。更准确地说,这个结果是不确定的,这意味着 C 标准没有定义结果将是什么。
通过如下原则,你可以很容易地避免这些问题:
·如果一个变量出现在同一个函数的多个参数中时,不要将增量或者减量运算符用于它上面。
·当一个发量多次出现在一个表达式里的时候,不要将增量或减量运算符运用到它的上面。
另一方面,关于什么时候执行增量动作, C 还是是做出了一些保证的。C Primer Plus这本书第5章癿“副作用和顺序点”部分讨论到顺序点时会有所介绍