运算符的结合性是指相同优先级的运算符在同一个表达式中,且没有括号的时候,运算符和操作数的结合方式,通常有从左到右结合和从右到左结合两种方式。
举个例子,假设~是一个运算符,又有表达式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;
}
自己写代码搞不清楚算符优先级请多加括号,但是一般这样的问题都会出现于笔试题或者面试题中,所以还是弄清楚比较好,注意上面代码的两个小坑~
转载自原文链接, 如需删除请联系管理员。
原文链接:C++ 右结合律与左结合律详解,转载请注明来源!