运算
1. 注意|| &&中的短路运算原则。
2. bool值在转化为整数时,true转化为1 false转化为0
3. 赋值运算返回左值。 while(0 == (ret = getValue())) {}
4. ++i i++
int a,i=0;
a = ++i; // a=1,i=1 先执行++i,再赋值给a
a = i++; // a=1,i=2 先执行a=i再执行i++
// 尽量用++i前置,因为后置需要保存原有值,在迭代器中会非常耗资源
cout<<*it++; // 虽然it++的优先级高于*it,但是后置++会保存原来的it值用于*it,所以相当于先cout<<it,再it++,是一种常用做法,优于分成两句写
cout<<*++it; // 错误,因为先执行++it有可能*it会发生越界,并且取不到原有的it
*it = toupper(*it++); // 错误,等号左右均有it,当it++时,不知道左边it变成什么,是不确定值
5. sizeof
void *p;
sizeof(*p); // 正确,因为sizeof不计算里面真正的值,只返回占用字节数,所以可以解引用空指针
int *p = &a;
sizeof(p); // 返回指针p的大小
sizeof(*p); // 返回a的大小
int a[] = {1,2,3};
auto n = sizeof(a)/sizeof(*a); // 这是一种获取数组长度的方法,返回数组元素个数
6. 类型转化
(1)隐式
比较优先级long double->double->float->long long->long->int->short->char->bool
同级中unsighed更大
转换方向是低等级转换为高等级
所有低于int的均先转化为int,然后再从int向更高级转化
(2)特殊
数组转化为指针,int a[10]; int *p = a; 数组名是指向首元素的指针
空指针转化,0和nullptr可以转化为任意指针;任意指向非常量的指针转化为void*;任意指向对象的指针转化为const void*;
布尔值转化,if() while() 判断语句中自动转化为bool值,0为false 其他为true
常量转化,指针和引用允许由非常量转化为常量,但不能反向。常引用还可以跨类型转化。
(3)显式
四种类型转换代替c语言()转换:dynamic_cast static_cast const_cast reinpreter_cast
static_cast: 强制类型转换,可以从非const转换成const,不能反向。
const_cast:只针对const指针转换成非const指针,不能转换类型。
double a = 10.5;
int b = static_cast<int>(a); // double转换为int
cout<<a<<endl; // 10.5 a不变
cout<<b<<endl; // 10
const int c = 10;
const int *p = &c;
int *q = const_cast<int*>(p);
*q=11; // 只能通过q修改,不能通过c p修改,因为是const类型
cout<<c<<endl; // 10 const类型的变量永远不变,如果c是非const类型,则为11
cout<<*p<<endl; // 11
cout<<*q<<endl; // 11
cout<<&c<<p<<q<<endl; // 三个地址相同
用处:一个方法只能接受非const类型,但是需要传入一个const参数
bool function(int* p);
const int a = 100;
function(const_const<int *>(&a)); // 等价于 const int *temp = &a; int *p = const_cast<int *>(temp); function(p);