C++Primer笔记-表达式

前言

该系列是《C++Primer第五版》的笔记,包含本人认为值得记录和整理的主要的知识点,并不是全部内容,也不是具体的内容。
该系列文章的作用应该是作为复习或预习的参考,有哪些知识点忘记或想学,可以大致浏览下该文章,然后再去书中寻找详细解答。(本系列文章基本是按书本顺序罗列的知识点,便于大家去书中寻找)
所以看该文章前,需要有一定的C++基础,否则阅读起来可能有困难。

本文大致整理了第四章的知识点,本章涉及到的内容比较晦涩枯燥,记忆性的内容较多,没有必要死记硬背,如果忘记了查书即可。

链接目录

基本概念

  • 一元运算符:作用于一个运算对象,例如取地址符&,解引用符*
  • 二元运算符:作用于两个运算对象,例如加法运算符+
  • 多元运算符:函数调用实际上是一种特殊的运算符,它对运算对象的数量没有限制
  • 左值和右值:一个对象被用作左值,使用的是他的身份(在内存中的位置),被用作右值时,使用的是他的值(内容)。

关于左值和右值,举个简单的例子: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()我们知道if1的返回值加f2的返回值,但究竟f1先执行
还是f2先执行,是未知的。

算术运算符

满足左结合律:优先级相同时,从左向右的顺序进行组合
优先级顺序:从上到下优先级从高到低

  • +-:用作一元运算符时(代表一个数是正是负)
  • */%:乘、除、取余
  • +-:用作二元运算符,两个数加减时

逻辑和关系运算符

优先级顺序:从上到下优先级从高到低

  • !:逻辑非
  • <<=>>=
  • ==!=
  • &&:逻辑与,比逻辑或优先级高
  • ||:逻辑或,比逻辑与优先级低

逻辑与规定先求左侧运算对象的值,只有左侧为真时才继续求右侧。逻辑或也类似,当左侧运算对象值为真时,就不会再求右侧运算对象的值了。

赋值运算符

赋值运算符:=,它左侧对象必须是一个左值,而且满足右结合律,即从右向左结合。例如:i = j = 0,它先将值赋给j,再将j的值赋给i

另外,赋值运算符优先级较低。

复合赋值运算符:形如+=-=*=,是一种简写形式。
例如i += 1,等价于i = i + 1

递增递减运算符

  • ++ii++:进行自增操作,区别在于,前置版本得到递增后的值,后置版本得到递增前的值。

例如:递减运算符类似,同理

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:返回一条表达式或类型所占的字节数

  • 对引用类型返回被引用对象所占空间
  • 对指针返回指针本身大小
  • 对解引用指针返回指针指向对象的空间大小
  • 对数组返回数组大小
  • stringvector返回固定部分大小,不会计算元素实际空间(这里原因较复杂,暂时不深究)

隐式类型转换

隐式类型通常有以下几种形式:

  • 在条件表达式中,非布尔值自动转换为布尔值
  • 初始化时,右侧对象自动转换成左侧对象
  • 算术运算或关系运算中,自动转换成同类型
  • 函数调用

其他隐式类型转换:

  • 数组名自动转换为指针
  • nullptr或0可以转换成任意指针类型
  • 任意指向非常量的指针都可以转换成void*
  • 有继承关系的类型间的指针转换

显式转换

C++中的显式转换有以下四种:

  • static_cast:静态类型转换
  • dynamic_cast:在十九章有详细介绍,本章不涉及
  • const_cast:将常量转为非常量
  • reinterpret_cast:在低层次上重解释内存数据,非常危险!

完整运算符优先级表

在书的147页,表格较长,文章不列入。

上一篇 下一篇

评论 | 0条评论