操作符优先级问题
《c陷阱与缺陷》中有类似如下的一个例子:
int ittt(0);
if (ittt == '\t' || ittt = 'c' || ittt == '\n')//编译不过
{
cout << "helllo" << endl;
}
编译不过的原因是,等号操作符优先级很低。在if判断语句中,计算前面的逻辑临时值,被赋予后面逻辑判断结果,但前面的非左值,所以失败。
书中有给类似的左值问题,测试代码如下:
int a(0), b(0);
// a++++ + b;//error C2105: “++”需要左值
int resu = a+++(++b);//此可通过 a++ + (++b);相当 0 + 1 ,运行后三变量值均为1
//int resu = a + (++++b);//此可通过变异);相当 0 + 2 ,运行后三变量值分别为resu:2,a:0,b:2
在测试环境vs2013中,注掉的第二句代码在打上符号后,5给紧相邻(没空格)的加号自动加了两个空格,这也标志着编译器对其的理解。所谓书中介绍的大嘴法,即a变量后连续两个后自增。如果想五个加号能通过,可理解为第三、四行代码所示,运行结果见注释。
关于c++中运算符优先级,摘录 c++ primer 第四版中5.10节中,表5.4如下:
结合性 |
操作符 |
功能 |
用法 |
L |
:: |
global scope(全局作用域) |
:: name |
L |
:: |
class scope(类作用域) |
class :: name |
L |
:: |
namespace scope(名字空间作用域) |
namespace :: name |
L |
. |
member selectors(成员选择) |
object . member |
L |
-> |
member selectors(成员选择) |
pointer -> member |
L |
[] |
subscript(下标) |
variable [ expr ] |
L |
() |
function call(函数调用) |
name (expr_list) |
L |
() |
type construction(类型构造) |
type (expr_list) |
R |
++ |
postfix increment(后自增操作) |
lvalue++ |
R |
-- |
postfix decrement(后自减操作) |
lvalue-- |
R |
typeid |
type ID(类型 ID) |
typeid (type) |
R |
typeid |
run-time type ID(运行时类型 ID) |
typeid (expr) |
R |
显式强制类型转换 |
type conversion(类型转换) |
cast_name <type>(expr) |
R |
sizeof |
size of object(对象的大小) |
sizeof expr |
R |
sizeof |
size of type(类型的大小) |
sizeof(type) |
R |
++ |
prefix increment(前自增操作) |
++ lvalue |
R |
-- |
prefix decrement(前自减操作) |
-- lvalue |
R |
~ |
bitwise NOT(位求反) |
~expr |
R |
! |
logical NOT(逻辑非) |
!expr |
R |
- |
unary minus(一元负号) |
-expr |
R |
+ |
unary plus(一元正号) |
+expr |
R |
* |
dereference(解引用) |
*expr |
R |
& |
address-of(取地址) |
&expr |
R |
() |
type conversion(类型转换) |
(type) expr |
R |
new |
allocate object(创建对象) |
new type |
R |
delete |
deallocate object(释放对象) |
delete expr |
R |
delete[] |
deallocate array(释放数组) |
delete[] expr |
L |
->* |
ptr to member select(指向成员操作的指针) |
ptr ->* ptr_to_member |
L |
.* |
ptr to member select(指向成员操作的指针) |
obj .*ptr_to_member |
L |
* |
multiply(乘法) |
expr * expr |
L |
/ |
divide(除法) |
expr / expr |
L |
% |
modulo (remainder)(求模(求余)) |
expr % expr |
L |
+ |
add(加法) |
expr + expr |
L |
- |
subtract(减法) |
expr - expr |
L |
<< |
bitwise shift left(位左移) |
expr << expr |
L |
>> |
bitwise shift right(位右移) |
expr >> expr |
L |
< |
less than(小于) |
expr < expr |
L |
<= |
less than or equal(小于或等于) |
expr <= expr |
L |
> |
greater than(大于) |
expr > expr |
L |
>= |
greater than or equal(大于或等于) |
expr >= expr |
L |
== |
equality(相等) |
expr == expr |
L |
!= |
inequality(不等) |
expr != expr |
L |
& |
bitwise AND(位与) |
expr & expr |
L |
^ |
bitwise XOR() |
expr ^ expr |
L |
| |
bitwise OR(位异或) |
expr | expr |
L |
&& |
logical AND(逻辑与) |
expr && expr |
L |
|| |
logical OR(逻辑或) |
expr || expr |
R |
?: |
conditional(条件操作) |
expr ? expr : expr |
R |
= |
assignment(赋值操作) |
lvalue = expr |
R |
*=, /=, %=, |
compound assign(复合赋值操作) |
lvalue += expr, etc. |
R |
+=, -=, |
||
R |
<<=, >>=, |
||
R |
&=,|=, ^= |
||
R |
throw |
throw exception(抛出异常) |
throw expr |
L |
, |
comma(逗号) |
expr , expr |