c++ Primer 第五版 第121页
左值和右值
使用关键字decltype时,左值和右值有所不同
作用于返回结果是左值的表达式得到一个引用类型
假设p是int*
例如decltype(*p)返回 int&
由于取地址返回的是右值,decltype(&p)返回int**,也就是一个指向指针的指针
c++ Primer 第五版 第123页
对于没有指定执行顺序的运算符来说,表达式指向同一个对象时可能会引发错误,举个简单的例子
int i =0;
cout<<i<<" "<< ++i<< endl;
由于程序未定义执行顺序,因此++i 和i我们不知道先执行什么
c++ Primer 第五版 第132页
后置递增运算符返回初始未加1 的值
成员访问运算符 ptr->mem等价于(*ptr).mem
n = (*p).size();
n = p->size();
*p.size();//错误,由于解引用运算符优先级低于点运算符,不加括号的话,代码含义就变了
箭头运算符作用于一个指针类型的运算对象,结果是一个左值;点运算符分两种情况,如果成员所属对象是左值,那结果是左值,反之亦然。
c++ Primer 第五版 第139页
sizeof 运算符有两种形式
sizeof (type) 返回类型的大小
sizeof expr 返回表达式结果的类型大小 且不实际计算运算对象值
int x[10];int *p = x;
cout<<sizeof(x)/sizeof(*x)<<endl;
cout<<sizeof(p)/sizeof(*p)<<endl;
由于x是数组,所以sizeof返回的是数组元素个数的size,因此第一行输出10
由于p是指针,sizeof返回的是指针类型的大小,sizeof(*p)返回的是int大小,二者都是4,所以第二行输出1
c++ Primer 第五版 第140页
逗号运算符 从左往右依次求值 和逻辑与、或以及条件运算符一样 也规定了运算的顺序
对于逗号运算符 线计算左侧表达式的值 然后抛弃 然后运算右表达式 返回的结果是右侧表达式的值
逗号运算符经常运在for循环中
vector<int>::size_type cnt = ivec.size()
for(vector<int>size_type ix=0; ix!=ivec.size();
++ix,--cnt)
ivec[ix] = cnt;
只要ix满足条件,cnt就递减
建议除非必须 否则不要使用后置版本的递增运算符 后置版本需要将原始值存储起来以便返回 这样就导致了浪费
c++ Primer 第五版 第144页
四种强制类型转换 cast-name<type>(expression)
static_cast,:任何具有明确定义的类型转换,只要不涉及底层const均可使用
常用于较大的算数类型赋值给较小的算数类型
对于编译器无法自动执行的类型转换也非常有用,例如找回存在void*指针内的内容
dynamic_cast
const_cast,:只能改变运算对象的底层const,常用于函数重载的 上下文中
reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释
int *ip;
char * pc = reinterpret_cast<char*> (ip);
必须牢记的是,pc的真实对象仍是一个int而非char
作者建议避免强制类型转换,尤其是reinterpret_cast是十分危险的
c++ Primer 第五版 第147页
运算符优先级列表