前言
该系列是《C++Primer第五版》的笔记,包含本人认为值得记录和整理的主要的知识点,并不是全部内容,也不是具体的内容。
该系列文章的作用应该是作为复习或预习的参考,有哪些知识点忘记或想学,可以大致浏览下该文章,然后再去书中寻找详细解答。(本系列文章基本是按书本顺序罗列的知识点,便于大家去书中寻找)
所以看该文章前,需要有一定的C++基础,否则阅读起来可能有困难。
本文大致整理了第四章的知识点,本章涉及到的内容比较晦涩枯燥,记忆性的内容较多,没有必要死记硬背,如果忘记了查书即可。
链接目录
- 第二章:变量与基本类型
- 第三章:字符串、向量和数组
- 第四章:表达式
- 第五章:语句
- 第六章:函数
- 第七章:类
- 第八章:IO库
- 第九章:顺序容器
- 第十章:泛型算法
- 第十一章:关联容器
- 第十二章:动态内存
- 第十三章:拷贝控制
- 第十四章:重载运算与类型转换
- 第十五章:面向对象程序设计
- 第十六章:模板与泛型编程
- 第十七章:标准库特殊设施
- 第十八章:用于大型程序的工具
- 第十九章:特殊工具与技术
基本概念
- 一元运算符:作用于一个运算对象,例如取地址符
&
,解引用符*
- 二元运算符:作用于两个运算对象,例如加法运算符
+
- 多元运算符:函数调用实际上是一种特殊的运算符,它对运算对象的数量没有限制
- 左值和右值:一个对象被用作左值,使用的是他的身份(在内存中的位置),被用作右值时,使用的是他的值(内容)。
关于左值和右值,举个简单的例子:int i = 1
,这里i
是左值,1
是右值。我们将右值(的值)赋给了左值(所代表的地址)(将值1
写到变量i
所在的地址)。而反过来写,则没有意义int 1 = i
,我们不能将一个左值赋给右值。
求值顺序
在复合表达式中,求值顺序依靠优先级和结合律决定,括号可以无视优先级和结合律。有时候对求值顺序不够了解,可能会导致难以排查的问题。
例如:
int arr[] = {2, 4, 6, 8};
int last = *(arr + 1);//先对指针位移,再解引用,值是4
int num = *arr + 1;//先解引用指针,再加1,值是3
在一个表达式中,求值顺序可能是无法确定的。例如:int i = f1() + f2()
我们知道i
为f1
的返回值加f2
的返回值,但究竟f1先执行
还是f2先执行,是未知的。
算术运算符
满足左结合律:优先级相同时,从左向右的顺序进行组合
优先级顺序:从上到下优先级从高到低
+
、-
:用作一元运算符时(代表一个数是正是负)*
、/
、%
:乘、除、取余+
、-
:用作二元运算符,两个数加减时
逻辑和关系运算符
优先级顺序:从上到下优先级从高到低
!
:逻辑非<
、<=
、>
、>=
==
、!=
&&
:逻辑与,比逻辑或优先级高||
:逻辑或,比逻辑与优先级低
逻辑与规定先求左侧运算对象的值,只有左侧为真时才继续求右侧。逻辑或也类似,当左侧运算对象值为真时,就不会再求右侧运算对象的值了。
赋值运算符
赋值运算符:=
,它左侧对象必须是一个左值,而且满足右结合律,即从右向左结合。例如:i = j = 0
,它先将值赋给j
,再将j
的值赋给i
。
另外,赋值运算符优先级较低。
复合赋值运算符:形如+=
、-=
、*=
,是一种简写形式。
例如i += 1
,等价于i = i + 1
。
递增递减运算符
++i
、i++
:进行自增操作,区别在于,前置版本得到递增后的值,后置版本得到递增前的值。
例如:递减运算符类似,同理
int i = 0, j;
j = ++i;//j = 1,得到递增后的值
j = i++;//当前i = 1,j = 1,得到的是递增前的值
//到此之后,i = 2, j = 1
解引用和递增递减运算符:*ptr++
,++
优先级高,等价于*(ptr++)
成员访问运算符
ptr->mem
等价于(*ptr).mem
,因为解引用运算符优先级低于点运算符,所以后者等价形式的括号是必须的。
条件运算符
形如cond ? expr1 : expr2
,其中cond
是条件表达式,当cond
值为真时,返回expr1
的值,否则,返回expr2
的值。
例如:i = i > 0 ? i : -i
,求i
的绝对值。
位运算符
用于处理二进制对象的运算符
优先级顺序:从上到下优先级从高到低
~
:位取反<<
、>>
:位左移、右移&
:位与^
:位异或|
:位或
注意:
- 通常对小整形进行位运算,会自动提升为较大整型,例如对
char
进行位运算,在计算过程中会自动提升为int
进行计算 - 对有符号数的移位操作,结果依赖机器,不推荐
sizeof运算符
sizeof
:返回一条表达式或类型所占的字节数
- 对引用类型返回被引用对象所占空间
- 对指针返回指针本身大小
- 对解引用指针返回指针指向对象的空间大小
- 对数组返回数组大小
- 对
string
或vector
返回固定部分大小,不会计算元素实际空间(这里原因较复杂,暂时不深究)
隐式类型转换
隐式类型通常有以下几种形式:
- 在条件表达式中,非布尔值自动转换为布尔值
- 初始化时,右侧对象自动转换成左侧对象
- 算术运算或关系运算中,自动转换成同类型
- 函数调用
其他隐式类型转换:
- 数组名自动转换为指针
- nullptr或0可以转换成任意指针类型
- 任意指向非常量的指针都可以转换成
void*
- 有继承关系的类型间的指针转换
显式转换
C++中的显式转换有以下四种:
static_cast
:静态类型转换dynamic_cast
:在十九章有详细介绍,本章不涉及const_cast
:将常量转为非常量reinterpret_cast
:在低层次上重解释内存数据,非常危险!
完整运算符优先级表
在书的147页,表格较长,文章不列入。