Skip to content

Commit 2584d55

Browse files
committed
Updated to Chapter 11, Section 5; Renamed images
1 parent d7953a7 commit 2584d55

File tree

133 files changed

+1275
-320
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+1275
-320
lines changed

Structure.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -777,12 +777,6 @@
777777

778778
`is_same` 类模板等。
779779

780-
### 实操:智能指针
781-
782-
带读者写一个`auto_ptr`类模板。
783-
784-
> 虽然`auto_ptr`在C++17中已经被移除了,但是我们泛讲篇不需要考虑得太细,能写出来一个简单的`auto_ptr`对初学者来说就已经是不小的成就了。
785-
786780
### STL简介
787781

788782
#### 容器
@@ -793,12 +787,20 @@
793787

794788
简单介绍下迭代器。
795789

790+
#### 函数对象
791+
796792
#### 算法
797793

798794
带读者试试`copy`, `sort`, `unique`三种算法。
799795

800796
> 更多STL知识及相关概念放精讲篇了,要不然泛讲篇就变成精讲篇了。
801797
798+
### 实操:智能指针
799+
800+
带读者写一个`auto_ptr`类模板。
801+
802+
> 虽然`auto_ptr`在C++17中已经被移除了,但是我们泛讲篇不需要考虑得太细,能写出来一个简单的`auto_ptr`对初学者来说就已经是不小的成就了。
803+
802804
## 异常处理简介
803805

804806
> 本章只做简单介绍,详细的放精讲篇。

code_in_book/11.4-11.6/Definition.tpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#pragma once
2-
#include "array.hpp"
3-
#include <algorithm>
1+
#pragma once //千万不要遗漏
2+
#include "array.hpp" //这句可以没有,但是为了编译器检查方便,还是包含一下吧
3+
#include <algorithm> //包含std::min等实用函数
44
//类模板std::array<T,N>的成员函数及一些非成员函数的定义
55
template<typename T, std::size_t N>
66
user::array<T, N>::array(std::initializer_list<T> ilist) : _elem{} {
@@ -111,6 +111,7 @@ void user::swap(array<T, N> &lhs, array<T, M> &rhs) {
111111
for (std::size_t i = 0; i < minlen; i++)
112112
std::swap(lhs._elem[i], rhs._elem[i]); //可以访问私有成员
113113
}
114+
114115
//类模板特化std::array<bool,N>的成员函数及部分相关非成员函数的定义
115116
template<std::size_t N>
116117
user::array<bool, N>::array(std::initializer_list<bool> ilist) : _elem {} {

code_in_book/11.4-11.6/Specification.tpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#pragma once
2-
#include "array.hpp"
3-
#include <bitset>
1+
#pragma once //千万不要遗漏
2+
#include "array.hpp" //这句可以没有,但是为了编译器检查方便,还是包含一下吧
3+
#include <bitset> //user::array内部的数据需要利用std::bitset来管理
44
namespace user{
55
//array类模板特化部分
66
template<std::size_t N>
77
class array<bool, N>; //特化的声明
8-
template<std::size_t N, std::size_t M>
8+
template<std::size_t N, std::size_t M> //模板参数与另一个不同,所以它是一个重载
99
void swap(array<bool, N>&, array<bool, M>&);
1010
template<std::size_t N>
1111
class array<bool, N> { //定义array<bool,N>部分特化
@@ -24,14 +24,14 @@ public:
2424
constexpr const bool& back()const { return _elem[N - 1]; }
2525
constexpr bool empty()const { return !N; }
2626
constexpr std::size_t size()const { return N; }
27-
void fill(bool); //传值比传常量引用更省内存空间
27+
void fill(bool); //对于bool来说,传值比传常量引用更省内存空间
2828
template<std::size_t I, typename U, std::size_t M>
29-
friend U& get(array<U, M>&); //这里不建议把U改成bool,因为U不是T
29+
friend U& get(array<U, M>&); //不建议把U改成bool,因为U不是T
3030
//声明模板友元,所有的get<U,M>函数实例都是类实例array<bool,N>的友元
3131
template<std::size_t I, typename U, std::size_t M>
3232
friend const U& get(const array<U, M>&);
3333
//同上
34-
template<std::size_t N, std::size_t M> //模板参数变化,所以它是一个重载
34+
template<std::size_t N, std::size_t M>
3535
friend void swap(array<bool, N>&, array<bool, M>&);
3636
template<typename, std::size_t>
3737
friend class array;

code_in_book/11.4-11.6/array.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ template<typename T, std::size_t N>
2323
constexpr bool operator==(const array<T, N>&, const array<T, N>&);
2424
template<typename T, std::size_t N>
2525
constexpr bool operator!=(const array<T, N>&, const array<T, N>&);
26+
2627
//类模板定义部分
2728
template<typename T, std::size_t N>
2829
class array {
@@ -59,7 +60,6 @@ class array {
5960
void swap(array<T, M>&);
6061
//作为array<T,N>的成员函数,它可与array<T,M>对象交换
6162
};
62-
//#include "Specialization_of_bool.hpp"
6363
}; //end namespace user
64-
#include "Specification.tpp"
65-
#include "Definition.tpp"
64+
#include "Specification.tpp" //包含Specification.tpp文件的代码
65+
#include "Definition.tpp" //同上
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <iostream>
2+
#include <list>
3+
#include <set>
4+
int main() {
5+
std::list<char> chs {'c', 'a', 'a', 'b', 'd', 'b', 'a', 'e'};
6+
std::set<char> s; //一个集合,用来表示chs中存在哪些数据
7+
auto it = chs.begin(); //它是一个迭代器类型,我们把它当作指针看待就好
8+
while (it != chs.end()) {
9+
if (s.find(*it) == s.end()) { //*it表示it当前指向的chs元素
10+
s.insert(*it); //s中没有记录*it这个数据,那就把它存进s
11+
++it; //it指向下一个元素
12+
}
13+
else //否则,就说明此前已经有*it这个数据了,当前的元素与前面重复
14+
it = chs.erase(it); //删除it指向的元素,并让it指向下一个元素
15+
}
16+
for (auto ch : chs)
17+
std::cout << ch << ' ';
18+
return 0;
19+
}

generalized_parts/01_welcome_to_cpp/01_start_with_a_cpp_program.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ \section{开始一个C++程序}
1010
\end{enumerate}
1111
\begin{figure}[htbp]
1212
\centering
13-
\includegraphics[width=0.8\textwidth]{../images/generalized_parts/01_From_source_code_to_executable_300.png}
13+
\includegraphics[width=0.8\textwidth]{../images/generalized_parts/01_From_source_code_to_executable.png}
1414
\caption{从源代码到可执行文件}
1515
\end{figure}
1616
实际上的过程会更复杂,比如在编译之前还会进行预处理(Preprocess)。但是我们现在还不需要操心这么多,因为在按下``编译''键之后,预处理和编译都会进行,所以不妨把它统称为一个过程。\par

generalized_parts/01_welcome_to_cpp/04_operators_and_types.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ \subsection*{整数除法问题}
6666
cout << a / b * 1.; //计算a/b的浮点数结果,但事与愿违
6767
\end{lstlisting}
6868
关于第一种方法为什么可行,第二种为什么不可行,我们会在第二章中探讨。\par
69-
总而言之,类型不同,可能会让结果出现一些意想不到的差异。因此类型是很重要的数据特怔,日后编程时我们需要多加留意。\par
69+
总而言之,类型不同,可能会让结果出现一些意想不到的差异。因此类型是很重要的数据特征,日后编程时我们需要多加留意。\par

generalized_parts/01_welcome_to_cpp/05_sizeof_and_memory.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ \subsection*{内存如何存储数据?}
1515
回到我们刚才的比喻。存储器的内部结构是排列有序的房屋。每个房屋代表一个字节,它是相对独立的最小可寻址单元。而每个房屋有8个房间,各自存储一比特的信息。图1.3可以帮助我们更直观地理解这种关系。\par
1616
\begin{figure}[htbp]
1717
\centering
18-
\includegraphics[width=0.75\textwidth]{../images/generalized_parts/01_Memory_byte_and_bit_300.png}
18+
\includegraphics[width=0.75\textwidth]{../images/generalized_parts/01_Memory_byte_and_bit.png}
1919
\caption{存储器、字节与比特}
2020
\end{figure}
2121
\subsection*{信息与容量}

generalized_parts/02_basic_operation_on_data/03_operators.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ \subsection*{运算符的优先级}
6565
C++中的赋值运算符优先级很低,比四则运算都要低。那么按照我们的思路,如果加法,乘法和赋值运算符同时出现,我们应该先给乘法套括号,然后是加法,最后才是赋值。如图2.1所示。\par
6666
\begin{figure}[htbp]
6767
\centering
68-
\includegraphics[width=0.5\textwidth]{../images/generalized_parts/02_Precedence_of_multiply_addition_and_assignment_300.png}
68+
\includegraphics[width=0.5\textwidth]{../images/generalized_parts/02_Precedence_of_multiply_addition_and_assignment.png}
6969
\caption{代码 \lstinline@num=a*b+c*d;@ 的套括号解释}
7070
\end{figure}
7171
再看这段代码:
@@ -103,7 +103,7 @@ \subsection*{运算符的结合性}
103103
除法运算符所在的优先级,其结合性是从左向右的,所以在乘法、除法和取模混合运算时,它就会从左向右套括号,而直观表现上就是``从左向右算''。赋值运算符所在的优先级,其结合性是从右向左的,所以在连续赋值的时候,它就会从右向左套括号,而直观表现上就是``从右向左算''\par
104104
\begin{figure}[htbp]
105105
\centering
106-
\includegraphics[width=0.4\textwidth]{../images/generalized_parts/02_Associativity_of_division_and_assignment_300.png}
106+
\includegraphics[width=0.4\textwidth]{../images/generalized_parts/02_Associativity_of_division_and_assignment.png}
107107
\caption{除法运算符和赋值运算符的结合性}
108108
\end{figure}
109109
所以连续除法中 \lstinline@8/4/2@ 就应该解释成 \lstinline@(8/4)/2@ 而非 \lstinline@8/(4/2)@;而连续赋值中 \lstinline@a=b=0@ 就应该解释成 \lstinline@a=(b=0)@ 而非 \lstinline@(a=b)=0@。如图2.2所示。\par

generalized_parts/02_basic_operation_on_data/04_type_cast.tex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ \subsection*{隐式类型转换}
3030
接下来是这个 \lstinline@double@ 型的 \lstinline@1.*a@ 作为整体与 \lstinline@int@ 型的 \lstinline@b@ 相除,于是 \lstinline@int@ 型的 \lstinline@b@ 也需要被转换成 \lstinline@double@ 型数据再参与运算。而 \lstinline@double@ 型数据的除法就不致于有截尾级别的精度损失了。整个过程如图2.3(a)所示。\par
3131
\begin{figure}[htbp]
3232
\centering
33-
\includegraphics[width=0.95\textwidth]{../images/generalized_parts/02_Implicit_type_cast_from_int_to_double_300.png}
33+
\includegraphics[width=0.95\textwidth]{../images/generalized_parts/02_Implicit_type_cast_from_int_to_double.png}
3434
\caption{\lstinline@1.*a/b@ 与 \lstinline@a/b*1.@ 的隐式类型转换过程图解}
3535
\end{figure}
3636
那么我写成这样行不行呢?
@@ -52,7 +52,7 @@ \subsection*{隐式类型转换}
5252
\textbf{布尔转换(Boolean Conversions)}是隐式类型转换当中比较特殊,而又十分常用的一类转换。如图2.4所示,它的转换规则很简单:如果别的基本数据类型要转换为 \lstinline@bool@ 类型的话,\lstinline@0@ 会转换成 \lstinline@false@,而其它的所有数都会被转换成 \lstinline@true@;如果 \lstinline@bool@ 类型要转换成其它的基本数据类型的话,\lstinline@false@ 会转换成 \lstinline@0@,而 \lstinline@true@ 会转换成 \lstinline@1@。\par
5353
\begin{figure}[htbp]
5454
\centering
55-
\includegraphics[width=0.7\textwidth]{../images/generalized_parts/02_boolean_conversion_300.png}
55+
\includegraphics[width=0.7\textwidth]{../images/generalized_parts/02_boolean_conversion.png}
5656
\caption{布尔转换规则}
5757
\end{figure}
5858
\subsection*{显式类型转换}
@@ -97,7 +97,7 @@ \subsection*{显式类型转换}
9797
在这里,乘法运算符在面临一个 \lstinline@int@ 操作数和 \lstinline@double@ 操作数的时候,它会怎么做呢?如图2.5所示,它将把 \lstinline@int@ 通过隐式类型转换变为 \lstinline@double@ 型!这样一来我们就白干了。\par
9898
\begin{figure}[htbp]
9999
\centering
100-
\includegraphics[width=0.6\textwidth]{../images/generalized_parts/02_Explicit_type_cast_from_double_to_int_in_vain_300.png}
100+
\includegraphics[width=0.6\textwidth]{../images/generalized_parts/02_Explicit_type_cast_from_double_to_int_in_vain.png}
101101
\caption{显式类型转换,但是又被隐式类型转换改回去了}
102102
\end{figure}
103103
总而言之,类型转换是一个非常复杂的话题。限于我们目前接触到的类型尚少,这里只作简单概括。将来我们接触复合类型和自定义类型的时候,还会对此作针对性讲解的。\par

0 commit comments

Comments
 (0)