逻辑运算符
&& 和 ||, 都是从左到右计算,仅当左边结果不能得到返回值时,才计算右边。
bool b1 = a && b;
bool b2 = a || b;
b1中,仅当a为真时,才计算b。b2中,仅当a为假时才计算b。
算术运算
p = f() + k();
p的值是函数f()与k()的返回值的和,但是先计算f()还是k()是未定义的,如果f()、k()改变了值,可能会有未定的返回结果。
赋值运算符
赋值运算符优先级较低,最好加括号
while((i = getAns()) == val){
// ...
}
*it++
假设it
是迭代器,*it++
等价于*(it++)
,*的优先级较低。
Type v = *it;
it++;
使用比较广泛,例如:
vector<int> test = {1,2,3,4,5,6,0,-3,21,312};
auto i = test.begin();
while(i != test.end() && *i >= 0){
cout<<*i++<<" ";
}
// 控制台:1 2 3 4 5 6 0
成员访问运算符
string s = "hhhh", p = &s;
(*p).size();
p->size();
// *p.size(); // error
箭头运算符作用于一个指针类型的运算对象,其结果是一个左值;
点运算符分为两种情况:
- 成员所属对象是左值,那么返回值是左值
- 反之,是右值
移位运算符 <<
移位运算符满足左结合律。 注意其优先级位于中间,不注意使用可能会出错!
sizeof
在sizeof
中解引用未初始化指针是无害的,因为在sizeof中并没有真正对其解引用,sizeof不需要解引用也可以知道其类型。
int *p;
// int a = *p; // error, p没有初始化
int len = sizeof *p; // 安全
逗号运算发
逗号运算符也是从左到右依次求值,然后将值丢弃,最终结果是右侧表达式的值。如果右侧的值是左值,那么其最终返回结果也是左值。
类型转换
显示转换
格式如下
cast_name<target_type>(expression);
如果target_type是引用类型,那么结果是左值。
static_cast,
dynamic_cast
支持运行时类型识别