表达式
零碎小知识
-
取地址符&
解引用符号 * (和乘法相同,由上下文决定) -
优先级 结合律 求值顺序
-
二元运算符要求两个运算对象的类型相同
-
指针不能转成浮点数
-
运算符重载 类型和返回值可以定义,但是运算对象个数、优先级、结合律无法改变(括号万能)
-
对象被用作右值,用的是内容;左值用的是地址。左值可以替代右值,反之不行。
-
左值不能是常量: 因为要赋值
等号结果是一个左值——等号可以连等,很多运算结果都是左值 -
a++;
后改变值;++a;
先改变值 ++a 效率更高 -
decltype(*p)
p是int*,解引⽤运算符&⽣成左值, decltype(p)的结果是int&
p是int,取地址运算符&⽣成右值,decltype(&p)的结果是int**,指向整型指针的指针 -
int i = f1() + f2();
不知道f1,f2哪一个先被调用,没有确认,所以如果改变的是同一个值会产生错误。 -
布尔类型不参与运算:1≠0 -1≠0 c也是true
b = true; c = -b;
-
溢出: int 32767+1 -> -32768; unsigned int v1=0 v1-- ->很大的正数
-
C++ 11 直接截尾取整
-
(-m)%n = -(m%n) m%(-n)=m%n 取余的正负号跟着的m
-
短路运算:
从左到右的运算中前者满足要求,就不再执行后者 -
i < j < k
k只要大于1 就能为真,因为i<j是Bool -
if (value == true)
如果value为int 等价于if (value == 1)
-
赋值运算符 从右往左
if (p=get()!=0)
先算后面再算前面 -
*(++iter)
后自增操作的优先级高于解引用操作
混用解引用和递增运算符iter++ = *(iter++)
*beg = touppwe(*beg++)
beg被改变,会报错
*iter++;
返回迭代器所指向的元素,然后迭代器递增。
iter++->empty()
判断迭代器当前元素是否为空,然后迭代器递增。 -
<=左右两边的运算顺序没有确定,所以++慎用
-
点运算符优先级高于*(指针) 所以要
(*p).high p->high
-
三目运算符
cond? expr1: expr2
但是条件运算符优先级很低 -
强烈建议位运算符仅用于无符号数
-
八进制转二进制:1位变3位
-
&
位运算&&
逻辑运算 -
1UL unsigned long
-
cin cout 优先级介于中间,使用时尽量加括号
-
指针执行sizeof运算,得到指针本⾝所占空间大小
对解引⽤指针执行sizeof运算,得到指针所指对象所占空间⼤⼩,指针不需要有效。
对string vector对象执⾏sizeof运算,只返回固定部分的⼤⼩,不会计算对象中元素占⽤多少空间
对引⽤类型执⾏sizeof运算,得到被引⽤对象所占空间⼤⼩ -
逗号运算符结果是右侧表达式的值
-
隐式转换
赋值语句,右侧转成左侧
能存在int就会转换成int,否则提升为unsigned int
wchar_t,char16_t,char32_t提升为整型中int,long,long long
小类型运算对象转较大的类型
若无符号不小于带符号类型,则带符号运算对象转成⽆符号的(可能有副作用
int i;
const int &j =i;
//⾮常量转为const int 的引⽤
const int *p =&i;
//⾮常量地址转为const 地址
int &r =j,
*q=p;
//错误,不允许const 转成⾮常量
//相反的转换不存在,因为试图删除底层const -
static_cast 任何明确定义的类型转换,只要不包含底层const,都可以使⽤。把较⼤的算数类型赋值给较⼩的类型时,static_cast⾮常有⽤,告诉编译器不在乎精度损失。使⽤时警告信息被关闭。
const_cast 只改变常量属性
reinterpret_cast 通常为运算对象的位模式提供低层次上的重新解释,但是不改变类型,需要特别记忆,不会报错,查错注意
double slope = static_cast<double>(j)/i;
PS: 课堂笔记,记下自己不熟的知识点