![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
C++primer (第五版) 读书笔记
文章平均质量分 65
记录学习 C++primer(第五版) 的笔记
奶油麦片糖
滴水穿石
展开
-
第九章_顺序容器_9.3 顺序容器操作
9.3 顺序容器操作9.3.1 向顺序容器添加元素除 array 外,所有标准库容器都提供灵活的内存管理。在运行时可以动态添加或删除元素来改变容器大小。如下图所示:当使用上图所示的操作时,必须记得不同容器使用不同的策略来分配元素空间空间,而这些策略直接影响性能。使用 push_backpush_back 将一个元素追加到一个容器的尾部。// 从标准输入中读取数据,将每个单词放到容器尾部string word;while(cin >> word) { container.原创 2021-09-07 14:27:13 · 221 阅读 · 1 评论 -
第九章_顺序容器_9.2 容器库概览
9.2 容器库概览容器类型上的操作形成了一种层次:某些操作是所有容器类型都提供的另外一些操作仅针对顺序容器、关联容器或无序容器还有一些操作仅适用于一小部分容器一般来说,每个容器都定义在一个头文件中,文件名与类型名相同。容器均定义为模板类,对大多数,但不是所有容器,还需要额外提供元素类型信息。对容器可以保存的元素类型的限制顺序容器几乎可以保存任意类型的元素。特别是,可以定义一个容器,其元素类型是另一个容器:vector<vector<string>> lines;原创 2021-09-03 17:40:52 · 170 阅读 · 0 评论 -
第九章_顺序容器_9.1 顺序容器概述
一个容器就是一些特定类型对象的集合。顺序容器(sequential container) 为程序员提供了控制元素存储和访问顺序的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。9.1 顺序容器概述顺序容器类型如下表:所有顺序容器都提供了快速顺序访问元素的能力。不同的容器在以下两个方面有不同的性能折中:向容器添加或从容器中删除元素的代价非顺序访问容器中元素的代价确定使用哪种顺序容器以下是一些选择容器的基本原则:除非有很好的理由选择其他容器,否则应使用vector如果原创 2021-09-03 17:38:31 · 163 阅读 · 0 评论 -
第七章_类_7.6 类的静态成员
7.6 类的静态成员有时类需要它的一些成员与类本身直接相关,而不是与类的各个对象保持关联,这时需要使用类的静态成员。声明静态成员通过在成员的声明之前加上关键字static使得其与类关联在一起。静态数据成员可以是public或者private的。静态数据成员的类型可以是常量、引用、指针、类类型等。举例如下,定义一个类,表示银行的账户记录:class Account {public: void calculate() { amount += amount * interestRate;原创 2021-03-27 14:22:56 · 125 阅读 · 0 评论 -
第七章_类_7.5 构造函数再探
7.5 构造函数再探7.5.1 构造函数的初始值列表如果没有在构造函数的初始值列表中显式地初始化成员,则该成员在构造函数体之前执行默认初始化:// Sale_data 构造函数的一种写法,虽然合法但是比较草率:没有使用构造函数初始值Sales_data::Sales_data(const string &s, unsigned cnt, double price){ bookNo = s; units_sold = cnt; revenue = cnt * pric原创 2021-03-27 14:22:23 · 143 阅读 · 0 评论 -
第七章_类_7.4 类的作用域
7.4 类的作用域每个类都会定义自己的作用域。在类的作用域之外,普通的数据和函数成员只能由对象、引用或者指针使用成员访问运算符来访问。对于类类型成员则使用作用域运算符访问。不论哪种情况,跟在运算符之后的名字都必须是对应类的成员:Screen::pos ht = 24, wd = 80; // 使用Screen定义的pos类型Screen scr(ht, wd, ' ');Screen *p = &scr;char c = scr.get(); // 访问 scr 对象的 get原创 2021-03-27 14:21:47 · 135 阅读 · 0 评论 -
第七章_类_7.3 类的其他特性
7.3 类的其他特性7.3.1 类成员再探定义一对相互关联的类 Screen 和 Window_mgr.定义一个类型成员Screen 表示显示器中的一个窗口。每个 Screen 包含一个用于保存 Screen 内容的 string 成员和三个 string::size_type 类型的成员,分别表示光标的位置以及屏幕的高和宽。class Screen{public: typedef std::string::size_type pos;private: pos cursor =原创 2021-03-27 14:20:56 · 113 阅读 · 0 评论 -
第七章_类_7.2 访问控制与封装
7.2 访问控制与封装使用访问说明符(access specifiers)加强类的封装性:定义在**public**说明符之后的成员在整个程序内可被访问,public 成员定义类的接口。定义在**private**说明符之后的成员可以被类的成员函数访问,但是不能被使用该类的代码访问。再一次定义 Sales_data 类class Sales_data {public: // 添加了访问说明符 Sales_data() = default; // 默认构造函数原创 2021-03-27 14:19:23 · 85 阅读 · 0 评论 -
第七章_类_7.1 定义抽象数据类型
类的基本思想是数据抽象(data abstraction)和封装(encapsulation)。数据抽象是一种依赖于**接口(interface)和实现(implementation)**分离的编程技术。类的接口包括用户所能执行的操作;类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。7.1 定义抽象数据类型封装实现了类的接口和实现的分离。类要想实现数据抽象和封装,需要首先定义个抽象数据类型(abstract data type)。7.1.1 设计 Sales_dat原创 2021-03-27 14:18:25 · 420 阅读 · 0 评论 -
第六章_函数_6.7 函数指针
6.7 函数指针函数指针指向的是函数而非对象。函数指针指向某种特定的类型,函数的类型由它的返回类型和形参类型共同决定,与函数名无关。如bool lengthCompare(const string&, const string&);该函数的类型是bool(const string&, const string&)声明一个指向该函数的指针bool (*pf)(const string&, const string&); // pf 指向一个函数原创 2021-02-23 12:05:12 · 89 阅读 · 0 评论 -
第六章_函数_6.6 函数匹配
6.6 函数匹配确定候选函数和可行函数函数匹配的第一步是选定本次调用对应的重载函数集,集合中的函数称为候选函数(candidate function)。第二步考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数(viable function)。寻找最佳匹配函数匹配的第三步是从可行函数总选择与本次调用最匹配的函数。在这一过程中,逐一检查函数调用提供的实参,寻找形参类型与实参类型最匹配的那个可行函数。含有多个形参的函数匹配对于多个可行函数,编译器依次检原创 2021-02-23 12:04:27 · 176 阅读 · 0 评论 -
第六章_函数_6.5 特殊用途语言特性
6.5 特殊用途语言特性6.5.1 默认实参形参在函数的多次调用中都被赋予一个相同的值,把这个反复出现的值称为函数的默认实参(default argument)。调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。typedef string::size_type sz;string screen(sz ht = 24, sz wid = 80, char backgrnd = ' ');一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。使用默认实参调用函数使用默认实参,原创 2021-02-23 12:02:03 · 80 阅读 · 0 评论 -
第六章_函数_6.4 函数重载
6.4 函数重载(overload)如果同一作用域内的几个函数名字相同但是形参列表不同,称之为重载函数。定义重载函数对于重载的函数来说,它们应该在形参数量或形参类型上有所不同。不允许两个函数除了返回类型外其他所有要素都相同。判断两个形参的类型是否相异有时候两个型形参列表看起来不一样,但实际上是相同的Record lookup(const Account &acct);Record lookup(const Account&);重载和 const 形参顶层 const 不原创 2021-02-23 12:00:32 · 191 阅读 · 0 评论 -
第六章_函数_6.3 返回类型和 return 语句
6.3 返回类型和 return 语句return 语句终止当前正在执行的函数并将控制权返回到调用该函数的地方。6.3.1 无返回值函数没有返回值的 return 语句只能用在返回类型是 void 的函数中。通常情况下,void 函数如果想在它的中间位置提前退出,可以使用 return 语句,类似 break。6.3.2 有返回值函数只要函数的类型不是 void,则该函数内的每条 return 语句必须返回一个值。return 语句返回值的类型必须与函数的返回类型相同,或者能隐式转换成函数的返回原创 2021-02-23 11:59:00 · 526 阅读 · 0 评论 -
第六章_函数_6.2 参数传递
6.2 参数传递每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化。当形参是引用类型时,对应的实参被引用传递(passed by reference)或者函数被传引用调用(called by reference)。当实参的值被拷贝给形参时,形参和实参是两个相互独立的对象,实参被值传递(passed by value)或者函数被传值调用(called by value)。6.2.1 传值参数当初始化一个非引用类型的变量时,初始值被拷贝给变量。此时,对变量的改动不会影响初始值。传原创 2021-02-23 11:58:12 · 198 阅读 · 0 评论 -
第六章_函数_6.1 函数基础
函数基础6.1 函数基础6.1.1 局部对象6.1.2 函数声明6.1.3 分离式编译(separate compilation)6.1 函数基础函数是一个命名了的代码块,我们通过调用函数执行相应的代码。函数可以有 0 个或多个参数,而且(通常)会产生一个结果。可以重载函数(同一个名字可以对应几个不同的函数)。一个典型的函数(function)定义包括以下几个部分:返回类型(return type)函数名字由 0 个或多个形参(parameter)组成的列表函数体编写函数// val原创 2021-02-23 11:56:55 · 114 阅读 · 0 评论 -
第五章_语句_5.6 try 语句块和异常处理
5.6 try 语句块和异常处理5.6.1 throw 表达式程序的异常检测部分使用 throw 表达式引发一个异常。throw 表达式包含关键字throw和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型。throw 表达式后面通常紧跟一个分号,从而构成一条表达式语句。Sales_item item1, item2;cin >> item1 >> item2;if (item1.isbn() != item.isbn()) throw runtime_原创 2021-02-21 13:16:31 · 114 阅读 · 0 评论 -
第五章_语句_5.5 跳转语句
5.5 跳转语句共有 4 种跳转语句:break、continue、goto、return。5.5.1 break 语句负责终止离它最近的 while、do while、for 或者 switch 语句,并从这些语句之后的第一条语句开始继续执行。break语句只能出现在迭代语句或者 switch 语句内部,作用范围仅限于最近的循环或者 switch。5.5.2 continue 语句终止最近的循环中的当前迭代并立即开始下一次迭代。只能出现在 for、while、do while 循环的内部,或原创 2021-02-21 13:15:14 · 128 阅读 · 0 评论 -
第五章_语句_5.4 迭代语句
5.4 迭代语句while和for语句在执行循环体之前检查条件,do while语句先执行循环体,然后再检查条件。5.4.1 while 语句只要条件为真,while 语句就重复的执行循环体,它的语法形式如下:while (conditon) statement在 while 结构中,只要 condition 的求值结果为真就一直执行 statement。 condition 不能为空,如果 condition 第一次求值就得 false,statement 一次都不执行。定义在 while原创 2021-02-21 13:14:35 · 122 阅读 · 0 评论 -
第五章_语句_5.3 条件语句
5.3 条件语句5.3 条件语句5.3.1 if 语句5.3.2 switch 语句5.3 条件语句有两种条件语句if语句switch语句5.3.1 if 语句if语句的语法形式是if (condition) statement;if else语句的形式是if (condition) statement1;else statement2;使用 if else 语句// 如果 grade 的结果小于 60,对应的字母是 F;否则计算其下标const v原创 2021-02-21 13:13:08 · 116 阅读 · 0 评论 -
第五章_语句_5.2 语句作用域
5.2 语句作用域定义在控制结构当中的变量只在相应语句的内部可见,一旦语句结束,变量也就超出其作用范围了。如果其他代码也需要访问控制变量,则变量必须定义在语句的外部。原创 2021-02-21 13:11:59 · 82 阅读 · 0 评论 -
第五章_语句_5.1简单语句
5.1 简单语句一个表达式,末尾加上分号就变成了表达式语句(expression statement)。空语句(null statement)空语句中只含有一个单独的分号:; // 空语句如果在程序的某个地方,语法上需要一条语句但是逻辑上不需要,此时应该是用空语句。别漏写分号,也别多写分号复合语句(块)复合语句(compound statement)是指用花括号括起来的(可能为空的)语句和声明的序列。复合语句也被称作块(block)。...原创 2021-02-20 13:50:35 · 133 阅读 · 0 评论 -
第四章_表达式_4.12 运算符优先级表
4.12 运算符优先级表原创 2021-02-20 13:49:02 · 248 阅读 · 0 评论 -
第四章_表达式_4.11 类型转换
4.11 类型转换4.11 类型转换4.11.1 算术转换(arithmetic conversion)4.11.2 其他隐式类型转换4.11.3 显式转换4.11 类型转换隐式转换(implicit conversion)是自动执行的,无需介入。何时发生隐式转换在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型在条件中,非布尔值转换成布尔值初始化过程中,初始值转换成变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型如果算术运算或关系运算的运算对象有多种类型,需要转原创 2021-02-20 13:46:32 · 129 阅读 · 0 评论 -
第四章_表达式_4.10 逗号运算符
4.10 逗号运算符4.10 逗号运算符(comma operator)4.10 逗号运算符(comma operator)逗号运算符含有两个运算对象,按照从左到右的顺序依次求值。对于逗号运算符来说,首先对左侧的表达式求值,然后将求值结果丢弃掉。逗号运算符的真正结果是右侧表达式的值。如果右侧运算对象是左值,那么最终的求值结果也是左值。vector<int>::size_type cnt = ivec.size();// 将把从 size 到 1 的值赋给 ivec 的元素for (原创 2021-02-20 13:45:39 · 118 阅读 · 0 评论 -
第四章_表达式_4.9 sizeof 运算符
4.9 sizeof 运算符4.9 sizeof 运算符4.9 sizeof 运算符sizeof运算符返回一条表达式或一个类型名字所占的字节数。sizeof运算符满足右结合律,其所得的值是一个size_t类型的常量表达式。运算符的运算对象又两种形式:sizeof (type)sizeof expr在第二种形式中,sizeof返回的是表达式结果类型的大小,sizeof并不实际计算其运算对象的值。Sales_data data, *p;sizeof(Sales_data); // 存储 Sale原创 2021-02-20 13:44:56 · 460 阅读 · 0 评论 -
第四章_表达式_4.8 位运算符
4.8 位运算符4.8 位运算符4.8 位运算符位运算符作用于整数类型的运算对象,并把运算对象看成是二进制位的集合。位运算符提供检查和设置二进制位的功能。如果运算对象是“小整型”,则它的值会被自动提升成较大的整数类型运算对象可以是带符号的,也可以是无符号的。如果运算对象是带符号的且它的值为负,那么位运算符如何处理运算对象的“符号位”依赖于机器;而且,此时的左移操作可能会改变符号位的值,因此是一种未定义的行为。移位运算符左移运算符<<在右侧插入值为 0 的二进制位;右移运算符&原创 2021-02-20 13:43:02 · 84 阅读 · 0 评论 -
第四章_表达式_4.7 条件运算符
4.7 条件运算符4.7 条件运算符4.7 条件运算符条件运算符?:允许把简单的if-else逻辑嵌入到单个表达式中,条件运算符按照如下形式使用:cond ? expr1 : expr2其中cond是判断条件的表达式,而expr1和expr2是两个类型相同或可能转换为某个公共类型的表达式。条件运算符的执行过程:求cond的值;如果条件为真对expr1求值并返回该值;否则对expr2求值并返回该值。当条件运算符的两个表达式都是左值或者能转换为同一种左值类型时,运算的结果是左值;否则运算的原创 2021-02-20 13:40:50 · 330 阅读 · 0 评论 -
第四章_表达式_4.6 成员访问运算符
4.6 成员访问运算符4.6 成员访问运算符4.6 成员访问运算符点运算符和箭头运算符都可用于访问成员,其中,点运算符获取类对象的一个成员;箭头运算符与点运算符有关,表达式ptr->mem等价于(*ptr)->mem;注意解引用运算符的优先级低于点运算符,所以执行解引用运算的字表达式两端必须加上括号。如果没有括号,代码的含义就不相同了。string s1 = "a string", *p = s1;auto n = s1.size();n = (*p).size();n = p-&原创 2021-02-20 13:39:55 · 196 阅读 · 0 评论 -
第四章_表达式_4.5 递增和递减运算符
4.5 递增和递减运算符4.5 递增和递减运算符4.5 递增和递减运算符递增运算符++,递减运算符--为对象的加 1 和减 1 操作提供了一种简洁的书写形式。递增和递减运算符有两种形式:前置版本首先将运算对象加 1(或减 1),然后将改变后的对象作为求值结果。后置版本将运算对象加 1(或减 1),求值结果是运算对象改变之前那个值的副本。int i = 0, j;j = ++i; // i 的值是 1,j 的值是 1j = i++; // i 的值是 2,j 的值是 1前置原创 2021-02-20 13:38:04 · 283 阅读 · 0 评论 -
第四章_表达式_4.4 赋值运算符
4.4 赋值运算符4.4 赋值运算符4.4 赋值运算符赋值运算符的左侧运算对象必须是一个可修改的左值。赋值运算的结果是它的左侧运算对象,并且是一个左值。结果的类型就是左侧运算对象的类型,如果赋值运算符的左右两个运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型。赋值运算符满足右结合律对于多重赋值语句中的每一个对象,她的类型或者与右边对象的类型相同、或者可由右边对象的类型转换得到:int ival, *pval;ival = pval = 0; // 错误:不能把指针的值赋给 ints原创 2021-02-20 13:36:40 · 177 阅读 · 0 评论 -
第四章_表达式_4.3 逻辑和关系运算符
逻辑和关系运算符4.3 逻辑和关系运算符4.3 逻辑和关系运算符关系运算符作用于算术类型或指针类型,逻辑运算符作用于任意能转换成布尔值的类型。逻辑运算符和关系运算符的返回值都是布尔类型。关系运算符和逻辑运算符的运算对象、求值结果都是右值。逻辑与&&和逻辑或||运算符对于逻辑与:当且仅当两个运算对象都为真时结果为真;对于逻辑或:只要两个运算对象中的一个为真结果就为真。逻辑与和逻辑或运算符都是左结合律,当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值。这种策略原创 2021-02-09 14:53:59 · 384 阅读 · 0 评论 -
第四章_表达式_4.2 算术运算符
4.2 算术运算符上图中按照运算符的优先级将其分组。一元运算符的优先级最高,接下来是乘法和除法,优先级最低的是加法和减法。上述所有运算符都满足做左结合律,意味着当优先级相同时按照从左向右的顺序进行组合。算术运算符能作用于任意算术类型以及任意能转换为算术类型的类型。算术运算符的运算对象和求值结果都是右值。一元运算符作用域一个指针或者算术值时,返回运算对象值的一个(提升后)的副本。int i = 1024;int k = -i; // k = -1024bool b = true;bool原创 2021-02-09 14:48:15 · 137 阅读 · 0 评论 -
第四章_表达式_4.1 基础
4.1 基础4.1 基础4.1.1 基本概念4.1.2 优先级与结合律4.1.3 求值顺序4.1 基础表达式由一个或多个运算对象(operand)组成,对表达式求值将得到一个结果(result),字面值和变量是最简单的表达式(expression),其结果就是字面值和变量的值。把一个运算符(operator)和一个或多个运算对象组合起来可以生成较复杂的表达式。4.1.1 基本概念作用于一个运算对象的运算符是一元运算符(unary operator);作用于两个运算对象的运算符是二元运算符(binar原创 2021-02-09 12:27:42 · 148 阅读 · 0 评论 -
第三章_字符串向量和数组_3.6多维数组
3.6 多维数组3.6 多维数组3.6 多维数组通常所说的多维数组其实是数组的数组。当一个数组的元素仍然是数组时,通常使用两个维度来定义它:一个维度表示数组本身大小,另外一个维度表示其元素(也是数组)大小// 数组定义int ia[3][4]; // 大小为 3 的数组,每个元素都是含有 4 个整数的数组int arr[10][20][30]; // 大小为 10 的数组,每个元素都是大小为 20 的数组,这些数组的元素是含有 30 个整数的数组// 数组下标引用ia[2][3] =原创 2021-02-08 15:10:04 · 561 阅读 · 0 评论 -
第三章_字符串向量和数组_3.5数组
3.5 数组3.5 数组3.5.1 定义和初始化内置数组3.5.2 访问数组元素3.5.3 指针和数组3.5.4 C 风格字符串3.5.5 与旧代码的接口3.5 数组数组的大小确定不变,不能随意向数组中增加元素。3.5.1 定义和初始化内置数组数组的声明形如a[d],其中a是数组的名字,d是数组的维度。维度说明的是数组中元素的个数,必须大于 0 。维度必须是一个常量表达式。显式初始化数组元素可以对数组的元素进行列表初始化,此时允许忽略数组的维度。const unsigned sz = 3;i原创 2021-02-08 15:07:10 · 151 阅读 · 2 评论 -
第三章_字符串向量和数组_3.4迭代器介绍
3.4 迭代器(iterator)迭代器支持一套操作,这套操作使得我们能访问容器的元素或者从某个元素移动到另外一个元素。迭代器提供了对对象的间接访问。迭代器有有效和无效之分,有效的迭代或者指向某个元素,或者指向容器中尾元素的下一位置,其他情况都属于无效。3.4.1 使用迭代器获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。begin成员负责返回指向第一个元素的迭代器,end成员负责返回指向容器尾元素的下一个位置的迭代器。// 由编译器决定 b 和 e 的类型// b 表示 v原创 2021-02-08 15:03:49 · 87 阅读 · 0 评论 -
第三章_字符串向量和数组_3.3标准库类型 vector
3.3 标准库类型 vector3.3 标准库类型 vector3.3.1 定义和初始化 vector 对象3.3.2 向 vector 对象中添加元素3.3.3 其他 vector 操作3.3 标准库类型 vector标准库类型vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象有一个与之对应的索引,索引用于访问对象。也被称为容器(container)要想使用vector,必须包含适当的头文件。使用如下声明#include <vector>using std::ve原创 2021-02-06 20:58:07 · 97 阅读 · 0 评论 -
第三章_字符串向量和数组_3.2标准库类型 string
标准库类型 string3.2 标准库类型 string3.2.1 定义和初始化 string 对象3.2.2 string 对象上的操作3.2.3 处理 string 对象中的字符3.2 标准库类型 string标准库类型string表示可变长的字符序列,使用string类型需要包含头文件string3.2.1 定义和初始化 string 对象以下是声明定义一个string对象的例子string s1; // 默认初始化,s1是一个空字符串 string s2 = s1; // s原创 2021-02-01 21:09:45 · 119 阅读 · 0 评论 -
第三章_字符串向量和数组_3.1命名空间的using声明
命名空间的 using 声明3.1 命名空间的 using 声明(using declaration)3.1 命名空间的 using 声明(using declaration)使用 using声明后无需专门的前缀 (::) 也可以使用所需的名字,using声明具有如下的形式:using namespace::name;每个名字都需要独立的 using 声明每个using声明引入命名空间中的一个成员。用到的名字名字都必须有自己的声明语句,而且每句话都必须以分号结束。头文件不应包含 using 声明原创 2021-02-01 21:04:59 · 72 阅读 · 0 评论