This commit is contained in:
krahets
2023-08-20 23:27:50 +08:00
parent 68e11cfa34
commit 4d55cafd13
46 changed files with 174 additions and 162 deletions

View File

@@ -21,6 +21,7 @@ comments: true
- 整数类型 `int` 占用 $4$ bytes = $32$ bits ,可以表示 $2^{32}$ 个数字。
下表列举了各种基本数据类型的占用空间、取值范围和默认值。此表格无须硬背,大致理解即可,需要时可以通过查表来回忆。
<p align="center"> 表:基本数据类型的占用空间和取值范围 </p>
<div class="center-table" markdown>
@@ -86,7 +87,7 @@ comments: true
=== "Go"
```go title=""
// 使用多种基本数据类型来初始化数组
// 使用多种基本数据类型来初始化数组
var numbers = [5]int{}
var decimals = [5]float64{}
var characters = [5]byte{}

View File

@@ -8,7 +8,7 @@ comments: true
## 3.1.1 &nbsp; 逻辑结构:线性与非线性
**逻辑结构揭示了数据元素之间的逻辑关系**。在数组和链表中,数据按照顺序依次排列,体现了数据之间的线性关系;而在树中,数据从顶部向下按层次排列,表现出祖先与后代之间的派生关系;图则由节点和边构成,反映了复杂的网络关系。
**逻辑结构揭示了数据元素之间的逻辑关系**。在数组和链表中,数据按照顺序依次排列,体现了数据之间的线性关系;而在树中,数据从顶部向下按层次排列,表现出祖先与后代之间的派生关系;图则由节点和边构成,反映了复杂的网络关系。
逻辑结构可被分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈线性排列;非线性结构则相反,呈非线性排列。
@@ -39,7 +39,7 @@ comments: true
内存是所有程序的共享资源,当某块内存被某个程序占用时,则无法被其他程序同时使用了。**因此在数据结构与算法的设计中,内存资源是一个重要的考虑因素**。比如,算法所占用的内存峰值不应超过系统剩余空闲内存;如果缺少连续大块的内存空间,那么所选用的数据结构必须能够存储在离散的内存空间内。
**物理结构反映了数据在计算机内存中的存储方式**,可分为连续空间存储(数组)和离散空间存储(链表)。物理结构从底层决定了数据的访问、更新、增删等操作方法,同时在时间效率和空间效率方面呈现出互补的特点。
**物理结构反映了数据在计算机内存中的存储方式**,可分为连续空间存储(数组)和离散空间存储(链表)。物理结构从底层决定了数据的访问、更新、增删等操作方法,同时在时间效率和空间效率方面呈现出互补的特点。
![连续空间存储与离散空间存储](classification_of_data_structure.assets/classification_phisical_structure.png)

View File

@@ -10,9 +10,9 @@ comments: true
## 3.3.1 &nbsp; 原码、反码和补码
上一节的表格中我们发现,所有整数类型能够表示的负数都比正数多一个例如`byte` 的取值范围是 $[-128, 127]$ 。这个现象比较反直觉,它的内在原因涉及到原码、反码、补码的相关知识。
上一节的表格中我们发现,所有整数类型能够表示的负数都比正数多一个例如 `byte` 的取值范围是 $[-128, 127]$ 。这个现象比较反直觉,它的内在原因涉及到原码、反码、补码的相关知识。
在展开分析之前,我们首先给出三者的定义:
实际上,**数字是以“补码”的形式存储在计算机中的**。在分析这样做的原因之前,我们首先给出三者的定义:
- **原码**:我们将数字的二进制表示的最高位视为符号位,其中 $0$ 表示正数,$1$ 表示负数,其余位表示数字的值。
- **反码**:正数的反码与其原码相同,负数的反码是对其原码除符号位外的所有位取反。
@@ -22,9 +22,7 @@ comments: true
<p align="center"> 图:原码、反码与补码之间的相互转换 </p>
显然「原码」最为直观。但实际上,**数字是以「补码」的形式存储在计算机中的**。这是因为原码存在一些局限性
一方面,**负数的原码不能直接用于运算**。例如,我们在原码下计算 $1 + (-2)$ ,得到的结果是 $-3$ ,这显然是不对的。
「原码 true form」虽然最直观但存在一些局限性。一方面**负数的原码不能直接用于运算**。例如在原码下计算 $1 + (-2)$ ,得到的结果是 $-3$ ,这显然是不对的
$$
\begin{aligned}
@@ -35,7 +33,7 @@ $$
\end{aligned}
$$
为了解决此问题,计算机引入了「反码」。如果我们先将原码转换为反码,并在反码下计算 $1 + (-2)$ ,最后将结果从反码转化回原码,则可得到正确结果 $-1$ 。
为了解决此问题,计算机引入了「反码 1's complement code」。如果我们先将原码转换为反码,并在反码下计算 $1 + (-2)$ ,最后将结果从反码转化回原码,则可得到正确结果 $-1$ 。
$$
\begin{aligned}
@@ -57,7 +55,7 @@ $$
\end{aligned}
$$
与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了「补码」。我们先来观察一下负零的原码、反码、补码的转换过程:
与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了「补码 2's complement code」。我们先来观察一下负零的原码、反码、补码的转换过程:
$$
\begin{aligned}
@@ -144,6 +142,7 @@ $$
**尽管浮点数 `float` 扩展了取值范围,但其副作用是牺牲了精度**。整数类型 `int` 将全部 32 位用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数 `float` 的数值越大,相邻两个数字之间的差值就会趋向越大。
进一步地,指数位 $E = 0$ 和 $E = 255$ 具有特殊含义,**用于表示零、无穷大、$\mathrm{NaN}$ 等**。
<p align="center"> 表:指数位含义 </p>
<div class="center-table" markdown>