C++ 右结合律与左结合律详解

运算符的结合性是指相同优先级的运算符在同一个表达式中,且没有括号的时候,运算符和操作数的结合方式,通常有从左到右结合和从右到左结合两种方式。

     举个例子,假设~是一个运算符,又有表达式a~b~c,如果~是左结合的,那么该表达式被解析为(a~b)~c,如果~是右结合的,那么该表达式将被解析为a~(b~c)。比如上表中三目运算符?:是从右向左结合的

那么下面的表达式a > b ? b > c ? 1 : 0 : 2将被解析为 a > b ? (b > c ? 1 : 0) : 2。


再看下运算符的优先级和结合律:

[cpp]  view plain  copy
  1. // C++ Operator Precedence and Associativity  
  2. // The highest precedence level is at the top of the table.  
  3. //+------------------+-----------------------------------------+---------------+  
  4. //| Operator         | Name or Meaning                         | Associativity |  
  5. //+------------------+-----------------------------------------+---------------+  
  6. //| ::               | Scope resolution                        | None          |  
  7. //| ::               | Global                                  | None          |  
  8. //| [ ]              | Array subscript                         | Left to right |  
  9. //| ( )              | Function call                           | Left to right |  
  10. //| ( )              | Conversion                              | None          |  
  11. //| .                | Member selection (object)               | Left to right |  
  12. //| ->               | Member selection (pointer)              | Left to right |  
  13. //| ++               | Postfix increment                       | None          |  
  14. //| --               | Postfix decrement                       | None          |  
  15. //| new              | Allocate object                         | None          |  
  16. //| delete           | Deallocate object                       | None          |  
  17. //| delete[ ]        | Deallocate object                       | None          |  
  18. //| ++               | Prefix increment                        | None          |  
  19. //| --               | Prefix decrement                        | None          |  
  20. //| *                | Dereference                             | None          |  
  21. //| &                | Address-of                              | None          |  
  22. //| +                | Unary plus                              | None          |  
  23. //| -                | Arithmetic negation (unary)             | None          |  
  24. //| !                | Logical NOT                             | None          |  
  25. //| ~                | Bitwise complement                      | None          |  
  26. //| sizeof           | Size of object                          | None          |  
  27. //| sizeof ( )       | Size of type                            | None          |  
  28. //| typeid( )        | type name                               | None          |  
  29. //| (type)           | Type cast (conversion)                  | Right to left |  
  30. //| const_cast       | Type cast (conversion)                  | None          |  
  31. //| dynamic_cast     | Type cast (conversion)                  | None          |  
  32. //| reinterpret_cast | Type cast (conversion)                  | None          |  
  33. //| static_cast      | Type cast (conversion)                  | None          |  
  34. //| .*               | Apply pointer to class member (objects) | Left to right |  
  35. //| ->*              | Dereference pointer to class member     | Left to right |  
  36. //| *                | Multiplication                          | Left to right |  
  37. //| /                | Division                                | Left to right |  
  38. //| %                | Remainder (modulus)                     | Left to right |  
  39. //| +                | Addition                                | Left to right |  
  40. //| -                | Subtraction                             | Left to right |  
  41. //| <<               | Left shift                              | Left to right |  
  42. //| >>               | Right shift                             | Left to right |  
  43. //| <                | Less than                               | Left to right |  
  44. //| >                | Greater than                            | Left to right |  
  45. //| <=               | Less than or equal to                   | Left to right |  
  46. //| >=               | Greater than or equal to                | Left to right |  
  47. //| ==               | Equality                                | Left to right |  
  48. //| !=               | Inequality                              | Left to right |  
  49. //| &                | Bitwise AND                             | Left to right |  
  50. //| ^                | Bitwise exclusive OR                    | Left to right |  
  51. //| |                | Bitwise OR                              | Left to right |  
  52. //| &&               | Logical AND                             | Left to right |  
  53. //| ||               | Logical OR                              | Left to right |  
  54. //| e1?e2:e3         | Conditional                             | Right to left |  
  55. //| =                | Assignment                              | Right to left |  
  56. //| *=               | Multiplication assignment               | Right to left |  
  57. //| /=               | Division assignment                     | Right to left |  
  58. //| %=               | Modulus assignment                      | Right to left |  
  59. //| +=               | Addition assignment                     | Right to left |  
  60. //| -=               | Subtraction assignment                  | Right to left |  
  61. //| <<=              | Left-shift assignment                   | Right to left |  
  62. //| >>=              | Right-shift assignment                  | Right to left |  
  63. //| &=               | Bitwise AND assignment                  | Right to left |  
  64. //| |=               | Bitwise inclusive OR assignment         | Right to left |  
  65. //| ^=               | Bitwise exclusive OR assignment         | Right to left |  
  66. //| ,                | Comma                                   | Left to right |  
  67. //+------------------+-----------------------------------------+---------------+  


有个需要注意的地方:数组解析和解引用与递增运算符混用

[cpp]  view plain  copy
  1. /*************************************************************************** 
  2.  *  @file       main.cpp 
  3.  *  @author     MISAYAONE 
  4.  *  @date       17  March 2017 
  5.  *  @remark     17  March 2017  
  6.  ***************************************************************************/  
  7.   
  8. #include <iostream>  
  9. #include <vector>  
  10. #include <list>  
  11. #include <string>  
  12. using namespace std;  
  13.   
  14. int main(int argc,char** argv)  
  15. {  
  16.     //*(解引用)运算符优先级优于+(加号)运算符  
  17.     int a[3][3] = {1,3,5,7,9,11,13,15,17};  
  18.     cout<<"a[2]+1:"<<a[2]+1<<endl;//生成a[2][1]的地址,二维数组中a[2]代表一个一维数组的首地址  
  19.     cout<<"*a[2]+1:"<<*a[2]+1<<endl;//先对a[2][0]取值,再加1  
  20.     cout<<"*(a[2]+1):"<<*(a[2]+1)<<endl;//生成a[2][1]的地址,再取值  
  21.     cout<<"(*a[2])+1:"<<(*a[2])+1<<endl;//先对a[2][0]取值,再加1  
  22.   
  23.     //*(解引用)运算符优先级与+(一元正号)运算符相同,皆为右结合律  
  24.     cout<<"+*a[2]:"<<+*a[2]<<endl;  
  25.   
  26.   
  27.     //*(解引用)运算符的优先级低于后置递增运算符(++),但是结果为1  
  28.     //这是一个坑点,因为后置++返回的是原对象的副本,并不会将其递增的结果返回  
  29.     int c[3]= {1,3,5};  
  30.     vector<int> b(c,c+3);  
  31.     auto p = b.begin();  
  32.     cout<<"*p++:"<<*p++<<endl;  
  33.   
  34.     cin.get();  
  35.     return 0;  
  36. }  

自己写代码搞不清楚算符优先级请多加括号,但是一般这样的问题都会出现于笔试题或者面试题中,所以还是弄清楚比较好,注意上面代码的两个小坑~


猜你喜欢

转载自blog.csdn.net/dp323/article/details/80299567