回首页 回首页 ◎ 设为首页  
◎ 收藏本站  
◎ 给我留言  
  
  首 页  C/C++教程  C++之父的FAQ  C/C++动向  C/C++源代码  C/C++误区  Unix/Linux  下载中心  乱七八糟  蚂蚁的Blog  
  当前位置:首 页 >> C/C++教程 >> C 语言基础教程 >> 24. 运算符的优先级和结合律
最 近 更 新
54. goto 语句
53. switch 语句推荐
52. continue 和 break
51. 条件运算符(?:)
50. if 语句嵌套推荐
49. 逻辑运算符推荐
48. 在循环中使用 if 语句推荐
47. if 和 else 连用推荐
46. if 语句
45. 循环应用实例 2
最 新 推 荐
53. switch 语句推荐
50. if 语句嵌套推荐
49. 逻辑运算符推荐
48. 在循环中使用 if 语句推荐
47. if 和 else 连用推荐
44. 循环应用实例 1推荐
43. 循环嵌套推荐
40. for 循环推荐
37. 关系运算符推荐
36. while 循环推荐
热 门 排 行
2. 第一个 C 程序推荐
31. 预处理指令 #define..推荐
1. C 语言简介
11. 基本数据类型:整型..推荐
24. 运算符的优先级和结..推荐
5. 如何编写函数
30. 字符串字面量推荐
13. 标识符命名规则
36. while 循环推荐
7. 第三个 C 程序推荐
站 内 搜 索

Web stdcpp.cn
关键词

搜索方式

搜索范围

精确匹配
广 告

24. 运算符的优先级和结合律


来源:蚂蚁的 C/C++ 标准编程 作者:antigloss 等级:强烈推荐
发布于2006-02-11 12:44 被读5570次 【字体:

Antigloss 最后修改于 2006-12-27

    如果一个表达式包含两个或两个以上的运算符,那么操作数的结合方式将决定这个表达式的结果。为了简便,我们把包含两个或两个以上运算符的表达式称为复合表达式。例如:

        3 + 2 * 5

如果 3 和 2 结合在一起,那么这个表达式的结果将会是 5 * 5 等于 25。当然,C 语言里,本例的 3 不会和 2 结合,而是 2 和 5 结合,得到 3 + 10 等于 13。

    运算符的优先级(precedence)和结合律(associativity)决定操作数的结合方式。当复合表达式中的运算符的优先级不同时,操作数的结合方式由优先级决定。当复合表达式中的运算符的优先级相同时,操作数的结合方式由结合律决定。不过,我们也可以使用括号强制把操作数结合在一起。例如:

        (3 + 2) * 5

强制把 3 和 2 结合在一起。


1. 优先级

    操作数的结合方式决定复合表达式的值。当复合表达式中的运算符的优先级不同时,操作数的结合方式由优先级决定。操作数总是围绕优先级较高的运算符进行结合。例如:

        8.0 + 20.0 / 4.0

因为除法运算符的优先级比加法运算符高,所以 20.0 和 4.0 结合,得到 5.0,然后 8.0 和 5.0 结合,得到 13.0。


2. 结合律

    当复合表达式中的运算符的优先级相同时,操作数的结合方式由结合律决定。例如:

        8.0 + 20.0 / 4.0 * 2.0

乘法运算符的优先级和除法运算符相同。不过,由于它们的结合率都是从左到右(即从左到右进行结合),所以 20.0 和 4.0 结合;得到的结果 5.0 再和 2.0 结合,得到 10.0;8.0 和 10.0 结合,得到 18.0。

    大多数运算符的结合律都是从左到右,不过也有从右到左的(例如赋值运算符)。


3. 使用括号强制结合操作数

    使用括号可以强制把操作数结合在一起。被括号括住的子表达式会被当作一个独立的个体进行处理,这个个体同样要受到优先级和结合律的约束。例如:

        (8.0 + 20.0 / 4.0) * 2.0

强制把 8.0 + 20.0 / 4.0 当成一个个体来处理。因为除法运算符的优先级比加法运算符高,所以 20.0 和 4.0 结合,得到 5.0;然后 8.0 和 5.0 结合,得到 13.0;13.0 和 2.0 结合得到 26.0。

        -9 + 4 * 5 + 6 + 8 * 7 - 1

根据优先级和结合律,这个表达式的结合方式等同于:

        ( ( ( ( (-9) + (4 * 5) ) + 6 ) + (8 * 7) ) - 1 )

由于赋值运算符的结合律是从右到左,所以

        i = j = k = l

的结合方式等同于:

        ( i = ( j = (k = l) ) )

 

4. 运算顺序

    优先级和结合律仅能确定操作数的结合方式,却不能决定操作数的运算顺序。例如:

        5 * 3 + 8 * 4

根据优先级和结合律,我们知道,这个表达式的结合方式等同于

        (5 * 3) + (8 * 4)  // 5 * 3 和 8 * 4 是 + 的操作数

但是, 到底是先运算 5 * 3 还是先运算 8 * 4,我们并不能确定。它们运算的先后是由编译器决定的。标准不规定操作数的运算顺序是为了让特定系统的编译器选择对该系统来说效率最高的运算顺序。但无论它们的运算先后如何,最终得到的结果都是 47。

下面我们来看一个小程序。

        /*--------------------------------------------------------------
         | 作者: Antigloss @ http://stdcpp.cn @ 蚂蚁的 C/C++ 标准编程
         | 
         | 功能: 演示优先级结合律对运算结果的影响
          -------------------------------------------------------------*/

        #include <stdio.h>

        int main(void)
        {
            int var1, var2;

            var1 = var2 = -(9 + 4) * 5 + (6 + 8 * (7 - 1));
            printf("var1 = var2 = %d\n", var1);

            return 0;
        }

请认真阅读以上程序,想想会出现什么结果,然后编译运行,看看运行结果和您想象的是否一样。

    因为优先级和结合律不能决定操作数的运算顺序,所以我们不知道到底是先运算 -(9 + 4) * 5 还是先运算 (6 + 8 * (7 - 1))。它们运算的先后是由编译器决定的。假设先运算 -(9 + 4) * 5,虽然加法运算符的优先级较低,但是括号强制把 9 和 4 结合在一起,得到 13。负号运算符的优先级比乘法运算符高,其作用于 13 得 -13。于是我们得到:

        var1 = var2 = -13 * 5 + (6 + 8 * (7 - 1));

由于乘法运算符的优先级比加法运算符高,所以 -13 和 5 结合在一起,得到 -65:

        var1 = var2 = -65 + (6 + 8 * (7 - 1));

在 (6 + 8 * (7 - 1)) 中,括号强制把 7 和 1 结合,得 6:

        var1 = var2 = -65 + (6 + 8 * 6);

因为 * 优先级高于 +,于是我们得到:

        var1 = var2 = -65 + (6 + 48);

进而

        var1 = var2 = -65 + 54;
        var1 = var2 = -11;

因为赋值运算符的结合率是从右到左,所以 -11 被赋值给 var2,接着 var2 被赋值给 var1。最终的结果是,var1 和 var2 相等,它们的值都是 -11。


5. 规定了操作数的运算顺序的运算符

    C 语言中,有四个运算符对其操作数的运算顺序做了明确的规定:

        &&   ||   ?:   ,

除了这四个运算符以外,其它运算符都没有规定其操作数的运算顺序。


6. C 语言提供的所有运算符

    下图列出了 C 语言提供的所有运算符,按优先级从高到低进行排列,优先级相同的运算符放在同一行。


参考资料:C Primer 5th Edition
           C99 标准

本文版权归 蚂蚁的 C/C++ 标准编程 以及 作者 antigloss 共同所有,转载请注明原作者和出处。谢谢。



相关专题:C 语言运算符
巧用异或交换整型变量的值
51. 条件运算符(?:)

上一篇:23. 乘法运算符和除法运算符
下一篇:25. 模除运算符 %

共有评论 2 条 网友评分 0分 查看全部评论

游客:hzieehero
评分:0
关于优先级中的?:的结合率不是应该从左到右的么?
怎么你上面图上写的是从右到左?
游客:leo
评分:0
不用管這些,如果你不清楚用括號就可以了

查看全部评论

【发表评论】 评分:1分 2分 3分 4分 5分


验证码:

Powered By Www.Xydw.COM Ver1.14 管理
Copyright © 2005-2006 蚂蚁的 C/C++ 标准编程 All Right Reserved. XCMS
粤ICP备06014124号   站长:Antigloss