当前位置:嗨网首页>书籍在线阅读

11-优先级和求值顺序

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.2.8 优先级和求值顺序

运算符优先级为表达式中的求值顺序提供重要的依据,但是并没有规定所有的顺序。C给语言的实现者留出选择的余地。考虑下面的语句:

y = 6 * 12 + 5 * 20;

当运算符共享一个运算对象时,优先级决定了求值顺序。例如上面的语句中, 12+ 运算符的运算对象。根据运算符的优先级,乘法的优先级比加法高,所以先进行乘法运算。类似地,先对 5 进行乘法运算而不是加法运算。简而言之,先进行两个乘法运算 6 125 20 ,再进行加法运算。但是,优先级并未规定到底先进行哪一个乘法。C语言把主动权留给语言的实现者,根据不同的硬件来决定先计算前者还是后者。可能在一种硬件上采用某种方案效率更高,而在另一种硬件上采用另一种方案效率更高。无论采用哪种方案,表达式都会简化为 72 + 100 ,所以这并不影响最终的结果。但是,读者可能会根据乘法从左往右的结合律,认为应该先执行 + 运算符左边的乘法。结合律只适用于共享同一运算对象的运算符。例如,在表达式 12 / 3 2 中, /运算符的优先级相同,共享运算对象 3 。因此,从左往右的结合律在这种情况起作用。表达式简化为 4 2 ,即 8 (如果从右往左计算,会得到 12/6 ,即 2 ,这种情况下计算的先后顺序会影响最终的计算结果)。在该例中,两个*运算符并没有共享同一个运算对象,因此从左往右的结合律不适用于这种情况。

学以致用

接下来,我们在更复杂的示例中使用以上规则,请看程序清单5.7。

程序清单5.7  rules.c 程序

/* rules.c -- 优先级测试 */
#include <stdio.h>
int main(void)
{
     int top, score;
     top = score = -(2 + 5) * 6 + (4 + 3 * (2 + 3));
     printf("top = %d, score = %d\n", top, score);
     return 0;
}

该程序会打印什么值?先根据代码推测一下,再运行程序或阅读下面的分析来检查你的答案。

首先,圆括号的优先级最高。先计算 -(2 + 5) 6 中的圆括号部分,还是先计算 (4 + 3 (2 + 3)) 中的圆括号部分取决于具体的实现。圆括号的最高优先级意味着,在子表达式 -(2 + 5) * 6 中,先计算 (2 + 5) 的值,得 7 。然后,把一元负号应用在 7 上,得 -7 。现在,表达式是:

top = score = -7 * 6 + (4 + 3 * (2 + 3))

下一步,计算 2 + 3 的值。表达式变成:

top = score = -7 * 6 + (4 + 3 * 5)

接下来,因为圆括号中的*比+优先级高,所以表达式变成:

top = score = -7 * 6 + (4 + 15)

然后,表达式为:

top = score = -7 * 6 + 19

-7 乘以 6 后,得到下面的表达式:

top = score = -42 + 19

然后进行加法运算,得到:

top = score = -23

现在, -23 被赋值给 score ,最终 top 的值也是 -23 。记住, = 运算符的结合律是从右往左。