细嚼慢咽C++primer(2)——表达式,sizeof,new,delete,类型转换
1 表达式基础
1)操作符的含义:该操作符执行什么操作以及操作结果的类型,取决于操作数的类型。
2)短路求值(short-circuit evaluation):逻辑与和逻辑或操作符总是先计算其做操作数,只有在仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数。
3)bool值:false用0表示,true用1表示。
4)bitset对象或整型值的使用
初始化:bitset<32> bitset_quiz1;
unsigned long int_quiz1 = 0;
设置对应的位:
bitset_quiz1.set(27);
int_quiz1 |= 1UL<<27; //将测验数据与一个整数做位或操作,该整数只有一个指定的位为1.
上述语句和该句等价:
int_quiz1 = int_quiz1 | 1UL << 27;
复位操作:
bitset_quiz1.reset(27);
int_quiz1 &=~(1UL << 27);
查看指定位:
bool status'
status = bitset_quiz1[27];
status = int_quiz1 & (1UL<<27);
5)移位操作符具有中等优先级:其优先级比算术操作符低,但比关系操作符、赋值操作符和条件操作符优先级高。
6)尽量少用后置操作符:后置操作符必须先保存操作数原来的值,以便返回未加1之前的值作为左操作数的值。对于复杂迭代器类型,这种额外工作可能会花费更大的代价。
vector<int>::iterator iter = ivec.begin();
while ( iter != ivec.end())
cout << *iter++ << endl; // 虽然自增操作优先级高,但是该表达式使iter加1后,返回iter原值的副本作为该表达式的结果。所以前置自增和后置自增的根本区别
//在于是否会有副本产生并返回。
7)C++语言不能确保从左到右的计算次序。
8)如果指针指向不是用new分配的内存地址,则在该指针上使用delete是不合法的。
一旦删除了指针所指向的对象,立即将指针置为0,这样就非常清楚地表明指针不再指向任何对象。
2 sizeof操作符
sizeof操作符返回一个对象或类型名的长度,返回值的类型为size_t,长度的单位是字节。
求数组元素的个数:int sz = sizeof(ia) * sizeof(*ia);
3 类型转换
1 隐式转换
1)指针转换:不将数组转换为指针的例外情况有:
- 数组用作取地址(&)操作符的操作数
- sizeof操作符的操作数
- 用数组对数组的引用进行初始化
2)转换为const对象当使用非const对象初始化const对象的引用时,系统将非const对象转换为const对象。2)由标准库类型定义的转换类类型可以由编译器自动执行类型转换。string s;while(cin >> s)将istream类型转换为bool类型意味着要检验流的状态。2 显示转换——强制类型转换
需要一种特定的类型转换。
dynamic_cast:支持运行时识别指针或引用所指向的对象。
const_cast:转换掉表达式的const性质
static_cast:
- 当需要将一个较大的算术类型赋值给较小的类型时,使用强制转换非常有用
- 使用static_cast找回存放在void*指针中的值 void* p = &d; double *dp = static_cast<double*>(p);
reinterpret_cast:通常为操作数的位模式提供较低层次的重新解释。
int *ip;
char * = reinterpret_cast<char*>(ip);