4.6 运算符
C++/C基本上有3种运算符:算术运算符、关系运算符和逻辑运算符,还有一些其他运算符,如函数调用、类型转换、成员选择等。C++新提供了几个类型转换运算符和运行时类型识别运算符(typeid),以及作用域解析(::)、动态内存分配和释放、类成员指针等运算符,我们在后面“C++运算符重载”中再介绍。运算符用来构成表达式并指示计算机执行计算,其基本特性就是优先级和结合律。在没有使用小括号确定一个复合表达式中各运算符的计算顺序的情况下,编译器将使用它们的优先级和结合律来确定计算顺序。优先级越高的运算符越先计算,相反,优先级越低的越后计算;相同优先级的运算符之间或同一运算符之间的计算顺序按照结合律来确定。
运算符和表达式都是属于C++/C程序的基本组成元素,它们看似简单,但使用时隐患还是比较多的。
常见运算符的优先级与结合律见表4-2。注意一元运算符+、-、*的优先级高于对应的二元运算符。
表4-2 运算符优先级和结合律
由于将上表熟记是比较困难的,为了防止产生歧义并提高可读性,应当用括号确定表达式的操作顺序。例如:
word = (high << 8) | low if ((a | b) && (a & c))
【提示4-11】: 如果代码行中的运算符比较多,用括号确定表达式中每一个子表达式的计算顺序,避免使用默认的优先级。
条件运算符“? :”是C++/C中唯一的三元运算符,其语法为:
条件表达式?表达式1:表达式2;
其语义是:如果“条件表达式”为true,则整个表达式的值就是“表达式1”的值,“表达式2”忽略;否则整个表达式的值就是“表达式2”的值,“表达式1”忽略。它的语义等价于如下的if/else结构:
ResultType retValue; if (条件表达式) { retValue= 表达式1; }else { retValue= 表达式2; }
【提示4-12】: 当单独对一个变量使用++、--运算符时,它们的前置版本和后置版本效果一样。只有当变量用在较复杂的表达式中时,它们的前置版本和后置版本才具有不同的效果。在后面的“C++运算符重载”中我们再详细讨论它们的前置版本和后置版本的语义和区别。
当心那些视觉上不易分辨的操作符,以免发生书写错误。我们经常会把“==”误写成“=”,像“||”、“&&”、“<=”、“>=”这类符号也很容易发生“丢1”失误,然而编译器却不一定能自动指出这类错误。