作者简介: 博 主 在 读 机 器 人 研 究 生 , 目 前 研 一 。 对 计 算 机 后 端 感 兴 趣 , 喜 欢 c + + , g o , p y t h o n , 目 前 熟 悉 c + + , g o 语 言 , 数 据 库 , 网 络 编 程 , 了 解 分 布 式 等 相 关 内 容 \textcolor{orange}{博主在读机器人研究生,目前研一。对计算机后端感兴趣,喜欢c++,go,python,目前熟悉c++,go语言,数据库,网络编程,了解分布式等相关内容} 博主在读机器人研究生,目前研一。对计算机后端感兴趣,喜欢c++,go,python,目前熟悉c++,go语言,数据库,网络编程,了解分布式等相关内容
个 人 主 页 : \textcolor{gray}{个人主页:} 个人主页: 小呆鸟_coding
支 持 : \textcolor{gray}{支持:} 支持: 如 果 觉 得 博 主 的 文 章 还 不 错 或 者 您 用 得 到 的 话 , 可 以 免 费 的 关 注 一 下 博 主 , 如 果 三 连 收 藏 支 持 就 更 好 啦 \textcolor{green}{如果觉得博主的文章还不错或者您用得到的话,可以免费的关注一下博主,如果三连收藏支持就更好啦} 如果觉得博主的文章还不错或者您用得到的话,可以免费的关注一下博主,如果三连收藏支持就更好啦 就 是 给 予 我 最 大 的 支 持 ! \textcolor{green}{就是给予我最大的支持!} 就是给予我最大的支持!
本文摘要
本专栏主要是对c++ primer这本圣经的总结,以及每章的相关笔记。目前正在复习这本书。同时希望能够帮助大家一起,学完这本书。 本文主要讲解第4章 表达式 文章目录
- ⛄️第4章 表达式
- ☔️4.1 基础
- ❄️4.1.1 基本概念
- ❄️4.1.2 优先级与结合律
- ❄️4.1.3 求值顺序
- ☔️4.2 算术运算符
- ☔️4.3 逻辑和关系运算符
- ☔️4.4 赋值运算符
- ☔️4.5 递增和递减运算符
- ☔️4.6 成员访问
- ☔️4.7 条件运算符
- ☔️4.8 位运算符
- ☔️4.9 sizeof运算符
- ☔️4.10 逗号运算符
- ☔️4.11 类型转换
- ❄️4.11.1 算术转换
- ❄️4.11.2 其他隐式类型转换
- ❄️4.11.3 显示转换
- ☔️4.12 运算符优先级(省略p147)
运算对象转换
小整数类型(如bool、char、short等)通常会被提升成较大的整数类型,主要是 int 型
重载运算符
左值和右值
要么是左值,要么是右值
对象的身份(在内存中的位置)
对象的值(内容)
需要右值的地方可以被左值代替,但是不能把右值当成左值(也就是位置)使用。
例如
int *p;
decltype(*p)的结果是int&;
int i = f1() * f2();
函数f1和函数f2一定会在乘法之前调用,但是到底是f1()在f2()之前调用还是,之后调用,不确定
cout << i << ""<< ++i << end;//错误!未定义的行为,不知道先求 i 还是先求 ++i
处理复合语句
如果改变了某个运算对象的值,在同一表达式中不要再使用该运算对象。
算术运算符(左结合律),有三种
整数除法的结果是向0取整
-21 % -8 = -5
21 % -5 = 1
布尔值
。短路求值
:逻辑与运算符和逻辑或运算符都是先求左侧运算对象的值再求右侧运算对象的值,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。先左再右
vector<string> text;
for(const auto &s: text){
cout << s;
}
注意:如果想要测试一个算术对象或者指针对象的真值,最直接的方法是将其作为 if 语句的条件,不要与布尔值进行比较。
if(a);//正确 只要a 是 正数,则为真
if(a == true);//错误:会将 true 先转换为 int 再比较,比较结果是不相等(只有a = 1时才为真)
返回结果时它的左侧运算对象
,且是一个左值
。类型也就是左侧对象的类型。int i, j;
i = j = 1;//正确,j 被赋值为 1,随后i 被赋值为 j 的值。
等价于
i = (j = 1);
比较低
,在条件语句中,赋值部分通常应该加上括号
+=; -=; *=; /=; %=; <<=; >>=; &=; ^=; |=;
例如a = a + 1; 需要进行俩次运算
而 a += 1; 只需要进行一次运算
递增和递减运算符有俩种形式:
前置版本将对象本身作为左值返回,后置版本将对象的原始值的副本返回。
非必须,不要使用后置版本
原因有俩点:
在一条语句中混用解引用和递增运算符
pbeg++ 等价于 *(pbeg++)
auto pbeg = v.begin();
while(pbeg != v.end())
cout << *pbeg++ << endl;
点运算符
和箭头运算符
都可以访问成员。.
运算符的优先级大于*
,所以要记得加括号ptr->mem
等价于(*ptr).mem
?:
),允许我们把简单的的if-else
逻辑嵌入到单个表达式当中,条件运算符的格式为cond ? expr1: expr2;
条件运算符优先级比较低,一般要加括号
int final = (grade > 90) ? "high pass":(grade < 60)? "fail":"pass"
位运算符作用于整数类型
的对象,并把运算符对象看成是二进制位
的集合。
运算符 | 功能 |
---|---|
~ | 位求反 |
<< | 左移 |
>> | 右移 |
& | 位与 |
^ | 位异或 |
! | 位或 |
不带符号的运算结果是固定的,带符号的运算结果依赖于机器。
左移操作可能会改变符号位的值,因此在c++中建议仅用位运算来处理无符号类型
移位运算符
>>
右移运算符处理无符号数
时,相当于在左侧插入0,右侧移出边界的值舍弃<<
左移运算符处理无符号数
时,相当于在右侧插入0,左侧移出边界的值舍弃对于有符号位:
<<
左移运算符,相当于在右侧插入值为0的二进制位>>
右移运算符:如果该运算对象是无符号类型,相当于在左侧插入值为0的二进制位。如果有符号类型,在左侧插入符号的副本或值为0的二进制位,具体看环境移位运算符满足左结合律
cout << a << b << endl;
((cout << a) <<b ) << endl;
sizeof
返回一条表达式或一个类型名字所占的字节数,返回值是size_t
类型不实际计算其运算对象的值
。sizeof有俩种形式:
Sales_data data *p;
sizeof p; //指针所占空间大小
sizeof *p //P所指类型的大小,例如int * p ;此时p的大小就是int 类型的大小
int ia[10];
// sizeof(ia)返回整个数组所占空间的大小
// sizeof(ia)/sizeof(*ia)返回数组的大小
constexpr size_t sz = sizeof(ia)/sizeof(*ia);
int arr[sz];
按照从左向右顺序依次求值。
左侧求值结果丢弃,逗号运算符结果是右侧表达式的值。
在 for 循环中可以用逗号分隔两个不同的条件
for(int i=0; i!=n; i++,j++)
注意不要在判断条件那里使用逗号分隔不同的条件,那样只会返回逗号分隔的最后一个表达式的值。
在c++中,如果参加运算的俩个对象是不同类型的。则会通过类型转换把,把俩个对象统一一下类型,在进行计算
隐式类型转换
将运算符中的运算对象,转换为最宽的类型
。例如:当表达式中既有浮点数也有整数时。整数值将准换成相应的浮点类型
double c = 3 + 'a';//先将'a'提升成 int,然后把 int 转换成 double
整数提升
整数提升负责把小整数转换成为较大的整数类型。
例如:(bool, short, char等),只要他们所有的可能的值都能存在int
里,他们就会提升成 int
类型
无符号类型的运算对象
数组转换为指针
指针的转换
整数0
或 nullptr
都能转换成任意指针类型。转换成常量
允许将指向非常量类型的指针
转换成指向相应的常量类型
指针。
int i;
const int &j = i; //非常量转换为const int 引用
const int *p = &i; //非常量地址转换为const 的地址
int &r = j, *q = p; //错误:不允许const转换为非常量
类类型定义的转换
string s = "value";//将 c 风格字符串字面值转换为 string类型
while(cin>>s); //将 cin 转换为 bool 值
显示准换就是强制转换
强制转换的具体格式:
castname<type>(expression);
castname有四种:
static_cast
任何类型转换,只要不包含底层 const,都可以用 static_cast
double slope = static_cast<double>(j)/i; //将 j 转换成 double 以便执行浮点数除法
const_cast
string& s;
const_cast <const string&> (s);// 将 s 转换为常量引用
const_cast <string&> (s);// 将 s 转换回非常量引用
reinterpret_cast
不要用它。
旧式的强制类型转换
int(a);// 函数形式的强制类型转换
(int)a;// c 语言风格的强制类型转换