《C++ Primer》笔记 第4章 表达式
- C++的表达式要不然是右值(right-value or read-value),要不然就是左值(left-value or location-value)。
- 当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
- 需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。当一个左值被当成右值使用时,实际使用的是它的内容(值)。到目前为止,已经有几种我们熟悉的运算符是要用到左值的:
- 赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。
- 取地址符作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值。
- 内置解引用运算符、string和vector的下标运算符的求值结果都是左值。
- 内置类型和迭代器的递增递减运算符作用于左值运算对象,其前置版本所得的结果也是左值。
- 如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。
- 如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。
- 如果m%n不等于0,则它的符号和m相同。
- 逻辑与(&&)和逻辑或(||)的短路求值。
- 赋值运算符:如果左侧运算对象是内置类型,那么初始值列表最多只能包含一个值,而且该值即使转换的话其所占空间也不应该大于目标类型的空间。对类类型来说,赋值运算的细节由类本身决定。无论左侧运算对象的类型是什么,初始值列表都可以为空。此时,编译器创建一个值初始化的临时量并将其赋给左侧运算对象。(例:
int a[5] = {};
)k = {3.14}; // 错误:窄化转换(换成圆括号正确)
vector<int> vi; // 初始值为空
vi = {0, 1, 2, 3, 4, 5}; // vi现在含有6个元素了,0到5
- 箭头运算符作用于一个指针类型的运算对象,结果是一个左值。点运算符分成两种情况:如果成员所属的对象是左值,那么结果是左值;反之,如果成员所属的对象是右值,那么结果是右值。
- 随着条件运算(?:)嵌套层数的增加,代码的可读性急剧下降。因此,条件运算的嵌套最好别超过两到三层。
- 条件运算符的优先级非常低,因此当一条长表达式中嵌套了条件运算子表达式时,通常需要在它两端加上括号。
- 关于符号位如何处理没有明确的规定,所以强烈建议仅将位运算符用于处理无符号类型。
- 使用位运算:
quiz1 |= 1UL << 27; // 表示学生27通过了测验
quiz1 &= ~(1UL << 27); // 学生27没有通过测验
bool status = quiz1 & (1UL << 27); // 学生27是否通过了测验
- sizeof运算符的运算对象有两种形式
sizeof (type)
或sizeof expr
。在第二种形式中,sizeof返回的是表达式结果类型的大小。与众不同的一点是,sizeof并不实际计算其运算对象的值(有点像decltype)。例:sizeof data.revenue;
等价于sizeof Sales_data::revenue;
- sizeof不需要真的解引用指针也能知道它所指对象的类型。
- sizeof运算符的结果部分地依赖于其作用的类型:
- 对char或者类型为char的表达式执行sizeof运算,结果得1。
- 对引用类型执行sizeof运算得到被引用对象所占空间的大小。
- 对指针执行sizeof运算得到指针本身多占空间的大小。
- 对解引用指针执行sizeof运算得到指针指向的对象所占空间的大小,指针不需有效(因为不实际解引用)。
- 对数组执行sizeof运算得到整个数组所占空间的大小(这里不再是数组首地址,和decltype类似),等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。注意,sizeof运算不会把数组转换成指针来处理。
- 对string对象或vector对象执行sizeof运算只返回该类型固定部分的大小,不会计算对象中的元素占用了多少空间。
- 因为执行sizeof运算能得到整个数组的大小,所以可以用数组的大小除以单个元素的大小得到数组中元素的个数
- 因为sizeof的返回值是一个常量表达式,所以我们可以用sizeof的结果声明数组的维度。
- 当表达式中既有浮点类型也有整数类型时,整数值将转换成相应的浮点类型。
- 整型提升负责把小整数类型转换成较大的整数类型。对于bool、char、signed char、unsigned char、short和unsigned short等类型来说,只要它们所有可能的值都能存在int里,他们就会提升成int类型(直接一步提升至int,没有中间类型);否则,提升成unsigned int类型。
- 较大的char类型(wchar_t、char16_t、char32_t)提升成int、unsigned int、long、unsigned long、long long和unsigned long long中最小的一种类型,前提是转换后的类型要能容纳原类型所有可能的值。
- 如果一个运算对象是无符号类型、另外一个运算对象是带符号类型,而且其中的无符号类型不小于带符号类型,那么带符号的运算对象转换成无符号的。如果带符号类型大于无符号类型,此时转换的结果依赖于机器。如果无符号类型的所有值都能存在该带符号类型中,则无符号类型的运算对象转换成带符号类型。如果不能,那么带符号类型的运算对象转换成无符号类型。
- 当数组被用作decltype关键字的参数,或者作为取地址符(&)、sizeof及typeid等运算符的运算对象时,数组转换成指针的转换不会发生。
- 指针的转换:C++还规定了几种其他的指针转换方式,包括常量整数值0或者字面值nullptr能转换成任意指针类型;指向任意非常量的指针能转换成
void*
;指向任意对象的指针能转换成const void*
。 - 允许将指向非常量类型的指针转换成指向相应的常量类型的指针,对于引用也是这样。(即非常量转换成常量)
- 类类型定义的转换:一处是在需要标准库string类型的地方使用C风格字符串,例:
string s = "a value";
;另一处是在条件部分读入istream,例:while (cin >> s)
。 - static_cast:任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
double slope = static_cast<double>(j) / i; // 进行强制类型转换以便执行浮点数除法
void* p = &d; // 正确:任何非常量对象的地址都能存入void*
double *dp = static_cast<double*>(p); // 正确:将void*转换回初始的指针类型
- const_cast:const_cast只能改变运算对象的底层const。
const char *pc;
char *p = const_cast<char*>(pc); // 正确:但是通过p写值是未定义的行为 const char *cp;
char *q = static_cast<char*>(cp); // 错误:static_cast不能转换掉const性质
static_cast<string>(cp); // 正确:字符串字面值转换成string类型
const_cast<string>(cp); // 错误:const_cast只改变常量属性 // const_cast常常用于有函数重载的上下文中。
- reinterpret_cast:reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释。reinterpret_cast本质上依赖于机器,想要安全地使用reinterpret_cast必须对涉及的类型和编译器实现转换的过程都非常了解。
int *ip;
char *pc = reinterpret_cast<char*>(ip);
// 我们必须牢记pc所指的真实对象是一个int而非字符,如果把pc当成普通的字符指针使用就可能在运行时发生错误。例如:string str(pc);
- 旧式的强制类型转换:
type (expr);
或(type) expr;
- ++运算符:前置递增运算符(++i)得到一个左值,它给运算符加1并得到运算对象改变后的值。后置递增运算符(i++)得到一个右值,它给运算符加1并得到运算对象原始的、未改变的值的副本。
《C++ Primer》笔记 第4章 表达式的更多相关文章
- 《C++ Primer 4th》读书笔记 第5章-表达式
原创文章,转载请注明出处: http://www.cnblogs.com/DayByDay/p/3912114.html
- C++ Primer 笔记 第三章
C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...
- C++ Primer 5th 第4章 表达式
表达式是运算对象及运算符组成的式子,表达式求值将得到一个结果,单独的变量或者字面值也算表达式,结果是其本身. 运算符分为:一元运算符.二元运算符.三元运算符.一元即一个作用对象,二元两个作用对象,以此 ...
- The C++ Programming Language 学习笔记 第6章 表达式和语句
1.关于strcpy函数. 书中说c风格的字符串尽量少用,strcpy这样的函数应该也要少用.这里讲这个函数主要是要通过本章课后练习第十题来讲一下前面提及的要点.巩固一下前几章的知识.写了一段,本来感 ...
- C Primer Plus_第5章_运算符、表达式和语句_编程练习
Practice 1. 输入分钟输出对应的小时和分钟. #include #define MIN_PER_H 60 int main(void) { int mins, hours, minutes; ...
- <<C++ Primer>> 第四章 表达式
术语表 第 4 章 表达式 算术转换(arithmetic conversion): 从一种算术类型转换成另一种算术类型.在二元运算符的上下文中,为了保留精度,算术转换通常把较小的类型转换成较大的类型 ...
- Programming Entity Framework-dbContext 学习笔记第五章
### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...
- SQL Server2012 T-SQL基础教程--读书笔记(1-4章)
SQL Server2012 T-SQL基础教程--读书笔记(1-4章) SqlServer T-SQL 示例数据库:点我 Chapter 01 T-SQL 查询和编程背景 1.3 创建表和定义数据的 ...
- 《简明Python编程》核心笔记(1~5章)
2014年8月20日 <简明Python编程>核心笔记 (1~5章) 昨天和今天两天时间里.把<简明Python编程>这一本书学完了,包含书上的代码.现把核心笔记记录下来,以 ...
随机推荐
- 2019HDU多校 Round4
08 K-th Closest Distance 题意:询问区间l,r中与数p的距离为第k大的数 求这个距离 题解:很裸的主席树 二分答案 然后可以用主席数判断在这个区间内 一段值域内出现的数 之前没 ...
- c语言文件的读取和写入
文件打开类型: 文件打开输出就用: 1 #include <stdio.h> 2 3 int main() 4 { 5 FILE *fp = NULL; 6 7 fp = fopen(&q ...
- 洛谷 P4017 最大食物链计数 (拓扑排序,思维)
题意:有\(n\)个点,连\(m\)条边,求最多有多少条食物链(从头走到为有多少条路径). 题解:之前抽了点时间把拓扑排序补完了,这题其实就是一道拓扑排序的裸题.关于拓扑排序: 1.首先,我们用\ ...
- Codeforces Round #649 (Div. 2) C. Ehab and Prefix MEXs (构造,贪心)
题意:有长度为\(n\)的数组\(a\),要求构造一个相同长度的数组\(b\),使得\({b_{1},b_{2},....b_{i}}\)集合中没有出现过的最小的数是\(a_{i}\). 题解:完全可 ...
- windows server 2016 安装有线网卡驱动
为自己的本本安装了server 2016系统,但是官网下载的有线网卡驱动一直安不上,解决方法如下: 1.到Intel官网下载一个叫PROWinx64的驱动程序,解压到任意文件夹.依次进入PRO1000 ...
- 微信小程序swiper实现 句子控app首页滑动卡片
微信小程序swiper实现 句子控app首页滑动卡片 引言:最近看到句子控APP首页的效果很清新,可是发现他的微信小程序端没有实现这个功能,我看了一下难度不大,于是尝试着去实现. 实现效果如下: 1. ...
- 鸟哥的linux私房菜——第七章学习(Linux 磁盘与文件系统管理)
1.1).文件系统特征 我们称呼一个可被挂载的数据为一个文件系统而不是一个分区! 文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到 inode 中,至于实际数据则放置到 data ...
- Leetcode(15)-三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- C# 类(9) - 接口 Interface
Interface 接口 类似 抽象类,也不能被实例化...(前面说的静态类,加上抽象类,还有这个,都3个了)接口其实比 抽象类 更加抽象.接口的方法(这个方法还不能有实体代码,和抽象类的抽象方法差不 ...
- spring-cloud-netflix-hystrix-dashboard
Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...