4.1 基础
-
左值右值
当一个对象被用作左值时,用的是对象的身份;当用作右值时,用的是对象的值
-
求值顺序
int i=f1()*f2(); //无法知道f1()和f2()的计算顺序 int j=0; cout<<j<<" "<<++j<<endl; //可能先计算++j,再计算j的值;也有可能反过来
-
含复数的取模运算
m % (-n) = m % n; (-m) % n = -(m % n);
-
窄化转换问题
int k=0; k=3.14; //类型转换后赋值 k={3.14}; //报错,发生窄化转换
-
位运算符
<<= //左移并赋值 >>= //右移并赋值 &= //按位与并赋值 ^= //按位异或并赋值 |= //按位或并赋值
-
递增与递减运算符
- 前置:将对象本身作为左值返回
- 后置:将原始值的副本作为右值返回
- 两者的效率:前置版本把值加一后直接返回了改变后的运算对象;后置版本需要将原始值存储下来,以便返回未修改的内容。故建议 若不需要未修改的原始值,建议使用前置版本
- *p++ 等价于 *(p++) ,因为后置递增/减优先级高于解引用
-
sizeof
//格式 sizeof (type); sizeof expression; ... Object *p; sizeof *p; //成立,即使p未初始化,在这里对其解引用也是安全的 //注意,对string和vector对象执行sizeof,只返回其固定部分大小,不会计算对象中的元素占了多少空间
4.2 类型转换
-
算术转换
- 整型提升:小整数类型转为较大的整数类型,前提是转换后的类型能容纳原类型的所有可能值
- 对于有符号和无符号混用情况
- 若无符号数不小于有符号数,则有符号类型转为无符号类型
- 有符号数大于无符号数,如果无符号类型的所有可能值都能存放在有符号类型中,则将无符号类型转为有符号类型;反之,将有符号类型转为无符号类型
-
命名的强制类型转换
//格式 cast_name <type> (expression); //cast_name所含的种类 static_cast / dynamic_cast / const_cast / reinterpret_cast
-
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用,当执行显式的类型转换时,警告信息会关闭
-
const_cast
//只能改变运算对象的底层const //利用const_cast可以去掉const性质 //若对象本身不是一个常量,则可以通过const_cast强转,获得写权限 const char *pc; char *p=const_cast<char*>(pc); //成立,但是通过p写值时未定义的
-
reinterpret_cast
//为运算对象的位模式提供较低层次上的重新解释 //容易出错,不建议使用 int *ip; char *pc=reinterpret_cast<char*>(ip); //pc指向的对象时int,而非char
-
老版本的强制转换
type (expression); //函数风格 (type) expression; //C风格