C++ Primer 第四章笔记

Chapter 4 Expressions

4.1 基础

4.1.1 基本概念

左值和右值

​ 一个左值表达式的求职结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。当一个对象用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。

4.1.3 求值顺序

​ 对于某些没有执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将会引发错误并产生未定义的行为,例如,<< 运算符没有明确规定何时以及如何对运算对象求值,因此下面的输出表达式是未定义的:

int i = 0;
cout << i << " " << ++i << endl;  // undefined

​ 因为程序是未定义的,所以我们无法推断它的行为。

4.2 算术运算符

07

int i = 1024;
int k = -i;  // i is -1024
bool b = true;
bool b2 = -b;  // b2 is true!

​ 布尔值不应该参与运算,-b 就是一个很好的例子。

​ 对大多数运算来说,布尔类型的运算对象被提升为 int 类型。如上所示,不二变量 b 的值为真,参与运算时将被提升为整数值 1,对它求负后的结果为 -1。将 -1 再转换为布尔值并将其作为 b2 的初始值,显然这个初始值不等于 0,转换成布尔值后应该为 -1。所以,b2 为真!

​ 当计算的结果超出该类型所能表示的范围时就会产生溢出。该值会发生环绕,如:

short short_value = 32767;  // max value if shorts are 16 bits
short_value += 1;  // this calculation overflows
cout << "short_value: " << short_value << endl;

// short_value: -32768

4.8 位运算符

位运算符作用于整数类型的运算对象,并把运算对象看成是二进制的集合。位运算符提供检查和设置二进制位的功能。如果运算对象是带符号的且它的值是负的,那么位运算符如何处理运算对象的 “符号位” 依赖于机器。而且,此时的左移操作可能会改变符号位的值,因此是一种未定义的行为。

08

移位运算符

<< 运算符和 >> 运算符的内置含义是对其运算对象执行基于二进制位的移动操作,首先令左侧运算对象的内容按照右侧运算对象的要求移动指定位数,然后经过移动的(可能还进行了提升)左侧运算对象的拷贝作为求值结果。其中,右侧运算对象一定不能为负,而且值必须严格小于结果的位数,否则将会产生未定义的行为。二进制或者向左移(<<)或者向右移(>>),移出边界之外的位就被舍弃掉了。

09

位求反运算符

将运算对象逐位求反后生成一个新值,将 1 置为 0、将 0 置为 1。

位与、位或、位异或运算符

​ 在两个运算对象上执行相应的逻辑操作:

10

4.9 sizeof 运算符

sizeof 运算符返回一条表达式或一个类型名字所占的字节数。sizeof 运算符满足右结合律,其所得的值是一个 size_t 类型的常量表达式:

11

​ sizeof 运算符的结果部分地依赖于其作用的类型:

12

4.11 类型转换

何时发生隐式类型转换

13

4.11.1 算术转换

14

猜你喜欢

转载自blog.csdn.net/weixin_43217860/article/details/82812563