【运算符】
在进行运算时,如果右括号的话我们知道先运算哪个,那如果没有括号了,算术运算符,关系运算符,逻辑运算符,位运算符,赋值运算符,++、--运算符等等,那么多的运算符,我们先算哪边,也就是这些运算符的优先级怎么排序呢?
优先级 | 操作符 | 描述 | 例子 | 结合性 |
---|---|---|---|---|
1 |
()
[] -> . :: ++ -- |
调节优先级的括号操作符
数组下标访问操作符 通过指向对象的指针访问成员的操作符 通过对象本身访问成员的操作符 作用域操作符 后置自增操作符 后置自减操作符 |
(a + b) / 4;
array[4] = 2; ptr->age = 34; obj.age = 34; Class::age = 2; for( i = 0; i < 10; i++ ) ... for( i = 10; i > 0; i-- ) ... |
从左到右 |
2 |
!
~ ++ -- - + * & (type) |
逻辑取反操作符
按位取反(按位取补) 前置自增操作符 前置自减操作符 一元取负操作符 一元取正操作符 解引用操作符 取地址操作符 类型转换操作符 返回对象占用的字节数操作符 |
if( !done ) ...
flags = ~flags; for( i = 0; i < 10; ++i ) ... for( i = 10; i > 0; --i ) ... int i = -1; int i = +1; data = *ptr; address = &obj; int i = (int) floatNum; int size = sizeof(floatNum); |
从右到左 |
3 |
->*
.* |
在指针上通过指向成员的指针访问成员的操作符
在对象上通过指向成员的指针访问成员的操作符 |
ptr->*var = 24;
obj.*var = 24; |
从左到右 |
4 |
*
/ % |
乘法操作符
除法操作符 取余数操作符 |
int i = 2 * 4;
float f = 10 / 3; int rem = 4 % 3; |
从左到右 |
5 |
+
- |
加法操作符
减法操作符 |
int i = 2 + 3;
int i = 5 - 1; |
从左到右 |
6 |
<<
>> |
按位左移操作符
按位右移操作符 |
int flags = 33 << 1;
int flags = 33 >> 1; |
从左到右 |
7 |
<
<= > >= |
小于比较操作符
小于或等于比较操作符 大于比较操作符 大于或等于比较操作符 |
if( i < 42 ) ...
if( i <= 42 ) ... if( i > 42 ) ... if( i >= 42 ) ... |
从左到右 |
8 |
==
!= |
等于比较操作符
不等于比较操作符 |
if( i == 42 ) ...
if( i != 42 ) ... |
从左到右 |
9 | & | 按位与操作符 | flags = flags & 42; | 从左到右 |
10 | ^ | 按位异或操作符 | flags = flags ^ 42; | 从左到右 |
11 | | | 按位或操作符 | flags = flags | 42; | 从左到右 |
12 | && | 逻辑与操作符 | if( conditionA && conditionB ) ... | 从左到右 |
13 | || | 逻辑或操作符 | if( conditionA || conditionB ) ... | 从左到右 |
14 | ? : | 三元条件操作符 | int i = (a > b) ? a : b; | 从右到左 |
15 |
=
+= -= *= /= %= &= ^= |= <<= >>= |
赋值操作符
复合赋值操作符(加法) 复合赋值操作符(减法) 复合赋值操作符(乘法) 复合赋值操作符(除法) 复合赋值操作符(取余) 复合赋值操作符(按位与) 复合赋值操作符(按位异或) 复合赋值操作符(按位或) 复合赋值操作符(按位左移) 复合赋值操作符(按位右移) |
int a = b;
a += 3; b -= 4; a *= 5; a /= 2; a %= 3; flags &= new_flags; flags ^= new_flags; flags |= new_flags; flags <<= 2; flags >>= 2; |
从右到左 |
16 | , | 逗号操作符 | for( i = 0, j = 0; i < 10; i++, j++ ) ... | 从左到右 |
额,表格上这么多,还有相同表示的,例如,&既可以作为取地址操作符又可以作为位与操作符。瞬间晕啦!
咱们来分析一下,将这个表格变简单。
首先,看结合性。分为两种:从左到右(大部分),从右到左。
然后,再看优先级,一个最高,一个最低,最低的就是逗号,这个方便记忆,那最高的呢,有什么共同点?就是构造类型元素或成员以及括号。(这点还有些疑问)
其次,运算符根据操作数,是不是分为单目,双目,三目运算符。
在表中,优先级为2的为单目运算符,优先级为3~13的为双目运算符,优先级为14的为三目运算符,优先级为15的为赋值运算符。
可是双目运算符中还分好多级呢,这怎么办?接着看呗!3算作指针访问成员运算符,4~5为算术运算符(先“乘除取余”后“加减”),6为移位操作符,7~8为关系运算符(先比大小,后算相等),9~11为逻辑位操作符(先“与”后“或”,“异或”放中间),12~13为逻辑操作符(先“与”后“或”)。也就是,算术,关系,逻辑。移位,逻辑位按序插入其中。
最后,C++运算符优先级为:一个最高(构造类型的元素或成员以及括号);一个最低(逗号);指针访问成员排老三;一,二,三,赋值;双目运算符,算术关系逻辑,移位、逻辑位按序插入其中。
【运算符重载】
运算符重载是面向对象中多态性的表现,是一种使用同一个运算符作用于不同类型的数据会有不同的行为的机制。
1、运算符重载条件:(除5种运算符外,其他均可重载)
. 成员选择运算符
.* 成员指针运算符
:: 作用于分辨符
?; 条件运算符
sizeof 计算数据大小运算符
这几种运算符也是属于比较特殊的一类。(成员选择 条件是 作用于指针的运算符来计算数据大小)
2、运算符重载规则(1不能,3不变)
(1)1不能:不能重载C++中没有的运算符
(2)3不变:原操作个数,原语义,原优先级和结合性。
3、运算符函数重载两种形式
(1)重载为类的友元函数
friend 函数类型 operator 运算符(形参表){函数体;}
(2)重载为类的成员函数
返回类型 (类名 :: ) operator
运算符(形参表){函数体;}
(3)比较
成员函数:单目运算符,类型转换函数,运算符操作修改对象。
友元函数:双目运算符,操作数隐式类型转换,运算具有可交互性。
注意:双目运算符=,[ ],(),—>不能重载为类的友元函数。
【总结】
对于C++真题上的操作题,看到运算符多的往往不知道先算哪边的,现在总结一下,有利于提高做题的效率。在我做过的题当中,运算符重载一般出在选择题上。
其实,对运算符优先级的记忆是上网查的,然后自己分析的。这使我明白,无论看到多么多的知识,只要你找就一定能找到联系的,并且能够编织属于你的知识网。所以,遇到困难,不要怕,从多角度分析一下,一切都能解决的。