表达式
C++ Primer学习笔记:运算符表达式,只记录不会或不熟悉的地方
左值与右值
a = b;
以上面的语句为基础,a 是左值,b 是右值。
由此引申,a 用到的是它的内存地址,左值是内存地址;b用到的是它内存中的值,右值即变量代表的值。
算术运算符
在除法运算中,如果两个运算对象的符号相同则商为正(如果不为0的话),否则商为负。C++语言早期版本允许结果为负值的商向上或向下取整,C++11新标准则规定商一律向0取整(即直接切除小数部分)。
根据取余运算的定义,如果 m 和 n 是整数且 n 非 0,则表达式 (m / n) * n + m % n 的求值结果与 m 相等。隐含的意思是,如果 m % n 不等于0,则它的符号和 m 相同。C++语言的早期版本允许 m % n 的符号匹配 n 的符号,而且商向负无穷一侧取整,这一方式在新标准中已经被禁止使用了。
除了 -m 导致溢出的特殊情况,其他时候 (-m) / n 和 m / (-n) 都等于 - (m / n),m % (-n) 等于 m % n ,(-m) % n 等于 - (m % n)。
也就是说,除法两个数的负号都看,负负得正,取模只看前面的负号。
赋值运算符
a += b / -= b;
a = a op b;
唯一的区别是左侧运算对象的求值次数:使用复合运算符只求值一次,使用普通的运算符则求值两次。这两次包括:一次是作为右边子表达式的一部分求值,另一次是作为赋值运算的左侧运算对象求值。.... 除了对程序性能有些许影响几乎可以忽略不计。
递增递减运算符
除非必须,否则不用递增递减运算符的后置版本
后置版本需要将原始值存储下来以便于返回这个未修改的内容....是一种浪费。
对于整数和指针类型来说,有一定优化;但对于相对复杂的迭代器类型,额外的工作就消耗巨大了。
递增递减运算符高于解引用运算符,因此 *pbeg++
等价于*(pbeg++)
.
位运算符
运算符 | 功能 |
---|---|
~ | 位求反 |
<< / >> | 左移 、 右移 |
& | 位与 |
^ | 位异或 |
| | 位或 |
关于符号位如何处理没有明确规定,所以强烈建议仅将位运算符用于处理无符号类型。
左移在右侧插入0;
右移插入符号位副本或者0,视具体环境。
sizeof 运算符
返回一条表达式或一个类型名字所占字节数。
sizeof (type);
sizeof expr;
Sale_data data,*p;
sizeof(Sale_data); // 对象所占大小
sizeof data; // 同上
sizeof *p; // 即使指针没有初始化也可以,同上
sizeof data.revenue;// 对象中一个成员的大小
sizeof Sale_data::revenue; // 同上
类型转换
显示转换
// cast-name是 static_cast / dynamic_cast / const_cast / reinterpret_cast 中的一种
// type是转换的目标类型
// expression是要转换的值
cast-name<type>(expression);
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
double *d;
void *p = &d;
double *dp = static_cast<double*>(p);
const_cast
只能改变运算对象的底层const
const char *pc;
char *p = const_cast<char*>(pc); // 正确,但是通过p写值是未定义的行为
const char a = 'a';
const char *pc = &a;
char *p = const_cast<char*>(pc);
cout<<a<<endl; // 输出:a
cout<<*pc<<endl; // 输出:a
cout<<*p<<endl; // 输出:a
*p = 'c';
cout<<a<<endl; // 输出:a
cout<<*pc<<endl; // 输出:c
cout<<*p<<endl; // 输出:c
return 0;
reinterpret_cast
通常为运算对象的位模式提供较低层次上的重新解释。
int *ip;
char *pc = reinterpret_cast<char*>(ip);
虽然进行强制类型转换了,但还需要时刻记住使用的是一个int变量。
早期的(type) expr 形式的强制类型转换,具有上述三种的相似行为,如果替换后合法,则是前两种,如果不合法,则是reinterpret_cast
dynamic_cast
支持运行时类型识别
【后续补充】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?