人生最可悲的事情,莫过于胸怀大志,却又虚度光阴。 ​​​​

《C++ Primer》读书笔记 第4章 表达式

2017.03.01

4.1 基础

4.1.1 基本概念

组合运算符和运算对象

运算对象转换

重载运算符

左值和右值

4.1.2 优先级与结合律

括号无视优先级与结合律

优先级与结合律有何影响

4.1.3 求值顺序

求值顺序、优先级、结合律

4.2 算术运算符

运算符%俗称“取余”或“取模”运算符,负责计算两个整数相除所得的余数,参与取余运算的运算对象必须是整数类型。

int ival = 42;
double dval = 3.14;
cout << ival % 12 << endl; //正确:结果是6
// ival % dval; 错误:运算对象是浮点数

在除法运算中,如果两个运算对象的符号相同则商为整,否则商为负。C++语言的早起版本允许结果为负值的商向上或向下取整,C++11新标准则规定商一律向0取整。

根据取余运算的定义,如果m和n是整数且n非0,则表达式(m/n)*n+m%n的求值结果与m相等。隐含的意思是,如果m%n不等于0,则它的符号和m相同。C++语言的早期版本允许m%n的符号匹配n的符号,而且商向负无穷一侧取整,这一方是在新标准中已经被禁止使用了。除了-m导致溢出的特殊情况,其他时候(-m)/n和m/(-n)都等于-(m/n),m%(-n)等于m%n,(-m)%n等于-(m%n)。

cout << 21/6 << endl; //3
cout << 21/7 << endl; //3
cout << -21/-8 << endl; //2
cout << 21/-5 << endl; //-4
cout << 21%6 << endl; //3
cout << 21%7 << endl; //0
cout << -21%-8 << endl; //-5

4.3 逻辑和关系运算符

逻辑与和逻辑或运算符

短路求值(short-circuit evaluation)

  • 对于逻辑与运算符来说,当且仅当左侧运算对象为真才对右侧运算对象求值。
  • 对于逻辑或运算符来说,当且仅当左侧运算对象为假时才对右侧运算对象求值。

逻辑非运算符

关系运算符

相等性测试与布尔字面值

4.4 赋值运算符

赋值运算满足左右结合律

赋值运算优先级较低

切勿混淆相等运算符和赋值运算符

复合赋值运算符

4.5 递增和递减运算符

在一条语句中混合解引用和递增运算符

运算对象可按任意顺序求值

4.6 成员访问运算符

点运算符和箭头运算符都可用于访问成员,其中,点运算符获取类对象的一个成员;箭头运算符与点运算符有关,表达式ptr->mem等价于(*ptr).mem:

#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;

int main()
{   
    string s1 = "a string",*p = &s1;
    auto n = s1.size();
    n = (*p).size(); //p所指对象的size成员
    n = p->size(); //等价于(*p).size()
    cout << n << endl; // 8
    return 0;
}

因为解引用运算符的优先级低于点运算符,所以执行解引用运算的子表达式两端必须加上括号。

4.7 条件运算符

条件运算符(?:)允许我们把简单的if-else逻辑嵌入到单个表达式中,条件运算符按照如下形式使用:

cond?expr1:expr2;

嵌套条件运算符

在输出表达式中使用条件运算符

4.8 位运算符

移位运算符

位求反运算符

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

使用位运算符

移位运算符(又叫IO运算符)满足左结合律

4.9 sizeof运算符

sizeof运算符返回一条表达式或一个类型名字所占的字节数。

4.10 逗号运算符

4.11 类型转换

4.11.1 算术转换

4.11.2 其他隐式类型转换

4.11.3 显式转换