Skip to content

Commit cc092d1

Browse files
committed
Updated to Appendix C, Section 1
1 parent b907ad1 commit cc092d1

30 files changed

+1740
-360
lines changed

generalized_parts/06_custom_types_and_their_use.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ \chapter{自定义类型及其使用}
44
int n {0x63794b37}; //这是一个16进制字面量,其10进制为1668893495
55
cout << (char*)&n; //以字符串形式输出
66
\end{lstlisting}
7-
在某台电脑上,它的输出是\\\noindent\rule{\linewidth}{.2pt}\texttt{
7+
在某个环境下\footnote{不同环境下给出的结果不尽相同},它的输出是\\\noindent\rule{\linewidth}{.2pt}\texttt{
88
7KycT�\$��
99
}\\\noindent\rule{\linewidth}{.2pt}
1010
为什么把 \lstinline@int*@ 类型转换成 \lstinline@char*@ 类型之后再输出就会得到这么奇怪的内容呢?原因就出在类型上。\par

generalized_parts/06_custom_types_and_their_use/03_exercise_example_list.tex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ \subsection*{链表的进阶功能}
183183
return find_tail(head->next); //否则就从head->next开始找
184184
}
185185
\end{lstlisting}\par
186-
其二,这里转移操作的写法很独特(也很简洁,不是吗)。这里用文字很难讲清楚,读者可以直接看图6.9,很直观。在这里我们用标准库中的 \lstinline@swap@ 函数,它可以交换两个指针的值\footnote{实际上 \lstinline@swap@ 是一个函数模版,当我们尝试使用它时,程序会生成一个 \lstinline@Data*@ 类型的实例。我们会在第十一章中介绍相关的知识。},也就相当于交换它们的指向。于是我们可以通过先交换 \lstinline@tail->next@ 和 \lstinline@dest->next@,再交换 \lstinline@head->next@ 和 \lstinline@dest->next@ 的方式来实现这个功能。\par
187-
\begin{figure}[htbp]
186+
其二,这里转移操作的写法很独特(也很简洁,不是吗)。这里用文字很难讲清楚,读者可以直接看图6.9,很直观。在这里我们用标准库中的 \lstinline@swap@ 函数,它可以交换两个指针的值\footnote{实际上 \lstinline@swap@ 是一个函数模版,当我们尝试使用它时,程序会生成一个关于 \lstinline@Data*@ 类型的实例。我们会在第十一章中介绍相关的知识。},也就相当于交换它们的指向。于是我们可以通过先交换 \lstinline@tail->next@ 和 \lstinline@dest->next@,再交换 \lstinline@head->next@ 和 \lstinline@dest->next@ 的方式来实现这个功能。\par
187+
\begin{figure}
188188
\centering
189189
\includegraphics[width=\textwidth]{../images/generalized_parts/06_range_transfer_between_lists_300.png}
190190
\caption{片段转移操作的示意图}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
\section{联合体}
2+
联合体初看上去很像结构体,它们的定义语法极其相似,但是它们是完全不同的事物。
3+
\begin{lstlisting}
4+
union ValType {
5+
int val_i;
6+
long long val_ll;
7+
char val_c;
8+
double val_d;
9+
long double val_ld;
10+
};
11+
int main() {
12+
cout << sizeof(ValType); //输出8或16,总之不是29或者更大的数
13+
}
14+
\end{lstlisting}
15+
一个结构体会把所有成员分别存储在不同的内存区域中,所以这个类型的内存占用不能小于所有成员的总和。以第2节中定义的 \lstinline@Cuboid@ 类型为例,我们可以用这样一段代码来观察某个对象各成员的地址:
16+
\begin{lstlisting}
17+
Cuboid cub;
18+
cout << &cub.length << endl << &cub.width << endl << &cub.height;
19+
\end{lstlisting}
20+
下面是一种可能的运行结果:\\\noindent\rule{\linewidth}{.2pt}\texttt{
21+
0x7ffeea18b070\\
22+
0x7ffeea18b074\\
23+
0x7ffeea18b078
24+
}\\\noindent\rule{\linewidth}{.2pt}\par
25+
从结果中我们可以看到,\lstinline@cub@ 的三个 \lstinline@int@ 型成员分别在不同的内存空间中,\lstinline@cub.length@ 在 \lstinline@...070@ 到 \lstinline@...073@ 位置,\lstinline@cub.width@ 在 \lstinline@...074@ 到 \lstinline@...077@ 位置,\lstinline@cub.height@ 在 \lstinline@...078@ 到 \lstinline@...07b@ 位置。它们之间没有任何重叠,互不干扰。\par
26+
但联合体不然,它会把所有成员存储到同一个内存区域中。
27+
\begin{lstlisting}
28+
ValType a;
29+
cout << &a.val_i << endl
30+
<< &a.val_ll << endl
31+
<< (void*)&a.val_c << endl //记得把char*转成void*输出
32+
<< &a.val_d << endl
33+
<< &a.val_ld << endl;
34+
\end{lstlisting}
35+
下面是一种可能的运行结果:\\\noindent\rule{\linewidth}{.2pt}\texttt{
36+
0x7ffc00a4d280\\
37+
0x7ffc00a4d280\\
38+
0x7ffc00a4d280\\
39+
0x7ffc00a4d280\\
40+
0x7ffc00a4d280
41+
}\\\noindent\rule{\linewidth}{.2pt}
42+
这说明联合体的所有成员都在同一个位置存着呢。
54.2 KB
Loading

images/generalized_parts/drawio/06_range_transfer_between_lists.drawio

Lines changed: 302 additions & 154 deletions
Large diffs are not rendered by default.
19.5 KB
Loading
21.5 KB
Loading
44.7 KB
Loading
4.08 KB
Loading
20.9 KB
Loading

0 commit comments

Comments
 (0)