表达式

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

支持运行时类型识别

【后续补充】

posted @   HeyMeteor  阅读(131)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示