运算符的结合性是指相同优先级的运算符在同一个表达式中,且没有括号的时候,运算符和操作数的结合方式,通常有从左到右结合和从右到左结合两种方式。
举个例子,假设~是一个运算符,又有表达式a~b~c,如果~是左结合的,那么该表达式被解析为(a~b)~c,如果~是右结合的,那么该表达式将被解析为a~(b~c)。比如上表中三目运算符?:是从右向左结合的
那么下面的表达式a > b ? b > c ? 1 : 0 : 2将被解析为 a > b ? (b > c ? 1 : 0) : 2。
再看下运算符的优先级和结合律:
- // C++ Operator Precedence and Associativity
- // The highest precedence level is at the top of the table.
- //+------------------+-----------------------------------------+---------------+
- //| Operator | Name or Meaning | Associativity |
- //+------------------+-----------------------------------------+---------------+
- //| :: | Scope resolution | None |
- //| :: | Global | None |
- //| [ ] | Array subscript | Left to right |
- //| ( ) | Function call | Left to right |
- //| ( ) | Conversion | None |
- //| . | Member selection (object) | Left to right |
- //| -> | Member selection (pointer) | Left to right |
- //| ++ | Postfix increment | None |
- //| -- | Postfix decrement | None |
- //| new | Allocate object | None |
- //| delete | Deallocate object | None |
- //| delete[ ] | Deallocate object | None |
- //| ++ | Prefix increment | None |
- //| -- | Prefix decrement | None |
- //| * | Dereference | None |
- //| & | Address-of | None |
- //| + | Unary plus | None |
- //| - | Arithmetic negation (unary) | None |
- //| ! | Logical NOT | None |
- //| ~ | Bitwise complement | None |
- //| sizeof | Size of object | None |
- //| sizeof ( ) | Size of type | None |
- //| typeid( ) | type name | None |
- //| (type) | Type cast (conversion) | Right to left |
- //| const_cast | Type cast (conversion) | None |
- //| dynamic_cast | Type cast (conversion) | None |
- //| reinterpret_cast | Type cast (conversion) | None |
- //| static_cast | Type cast (conversion) | None |
- //| .* | Apply pointer to class member (objects) | Left to right |
- //| ->* | Dereference pointer to class member | Left to right |
- //| * | Multiplication | Left to right |
- //| / | Division | Left to right |
- //| % | Remainder (modulus) | Left to right |
- //| + | Addition | Left to right |
- //| - | Subtraction | Left to right |
- //| << | Left shift | Left to right |
- //| >> | Right shift | Left to right |
- //| < | Less than | Left to right |
- //| > | Greater than | Left to right |
- //| <= | Less than or equal to | Left to right |
- //| >= | Greater than or equal to | Left to right |
- //| == | Equality | Left to right |
- //| != | Inequality | Left to right |
- //| & | Bitwise AND | Left to right |
- //| ^ | Bitwise exclusive OR | Left to right |
- //| | | Bitwise OR | Left to right |
- //| && | Logical AND | Left to right |
- //| || | Logical OR | Left to right |
- //| e1?e2:e3 | Conditional | Right to left |
- //| = | Assignment | Right to left |
- //| *= | Multiplication assignment | Right to left |
- //| /= | Division assignment | Right to left |
- //| %= | Modulus assignment | Right to left |
- //| += | Addition assignment | Right to left |
- //| -= | Subtraction assignment | Right to left |
- //| <<= | Left-shift assignment | Right to left |
- //| >>= | Right-shift assignment | Right to left |
- //| &= | Bitwise AND assignment | Right to left |
- //| |= | Bitwise inclusive OR assignment | Right to left |
- //| ^= | Bitwise exclusive OR assignment | Right to left |
- //| , | Comma | Left to right |
- //+------------------+-----------------------------------------+---------------+
有个需要注意的地方:数组解析和解引用与递增运算符混用
- /***************************************************************************
- * @file main.cpp
- * @author MISAYAONE
- * @date 17 March 2017
- * @remark 17 March 2017
- ***************************************************************************/
- #include <iostream>
- #include <vector>
- #include <list>
- #include <string>
- using namespace std;
- int main(int argc,char** argv)
- {
- //*(解引用)运算符优先级优于+(加号)运算符
- int a[3][3] = {1,3,5,7,9,11,13,15,17};
- cout<<"a[2]+1:"<<a[2]+1<<endl;//生成a[2][1]的地址,二维数组中a[2]代表一个一维数组的首地址
- cout<<"*a[2]+1:"<<*a[2]+1<<endl;//先对a[2][0]取值,再加1
- cout<<"*(a[2]+1):"<<*(a[2]+1)<<endl;//生成a[2][1]的地址,再取值
- cout<<"(*a[2])+1:"<<(*a[2])+1<<endl;//先对a[2][0]取值,再加1
- //*(解引用)运算符优先级与+(一元正号)运算符相同,皆为右结合律
- cout<<"+*a[2]:"<<+*a[2]<<endl;
- //*(解引用)运算符的优先级低于后置递增运算符(++),但是结果为1
- //这是一个坑点,因为后置++返回的是原对象的副本,并不会将其递增的结果返回
- int c[3]= {1,3,5};
- vector<int> b(c,c+3);
- auto p = b.begin();
- cout<<"*p++:"<<*p++<<endl;
- cin.get();
- return 0;
- }
自己写代码搞不清楚算符优先级请多加括号,但是一般这样的问题都会出现于笔试题或者面试题中,所以还是弄清楚比较好,注意上面代码的两个小坑~