《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 |