第2章
第2章着重讲述了不同的计数系统以及他们的种种关系,其中二进制,八进制,十六进制计数系统的存在使得原本枯燥无味的数字有了紧密而有趣的联系。在二进制中,0和1是计数系统的基数,每多一位位数,计数系统所表示的情况便是原来的两倍,而因为存在8=2³,16=2⁴的关系,二进制与八进制,十六进制的转换显得尤为简单。例如二进制向八进制的转换,就是从左向右三位比特数为一组(十六进制则为四位比特数一组),但向十进制的转换则相比之下较为复杂。因为现代计算机都是二进制机器的原因,二进制的学习也显得尤为重要,第3章就讲到二进制补码的问题(一种计算机负数的表达方法),由此可见,二进制是学习计算机的基石,也是通向计算机复杂计算的阶梯。
第3章则是在第2章的基础上深化了信息层面的内容——数据表示法。没有数据,计算机就毫无用处,而没有具体的管理数据的方式,计算机便失去了其诞生的目的。如今的信息类型有很多:数字,文本,音频,图像图形,视频等等。如何表达这种种信息,以及如何更好的传输它们,正是第3章所想描述的内容。因为计算机的精确性要求,数字化数据的储存,校准,传输等是每位计算机工作者所要清楚明白的。同时为何现代计算不使用十进制而转向二进制计数系统的原因也得以在这一章节列举:
1.脉冲编码调制(PCM)的出现使得二进制计数系统优势得以体现。
2.传统数据对负数的表示法并不适用于计算机语言(计算机对-0的难以理解等),在十进制补码的基础上出现的二进制补码完美解决的计算机负数表达的问题(Negative(I)=2∧k-I)即将每一位取反再加一,使得八位二进制补码可以轻松表示-128~127的所有数据,同时数据最左边一位表示正负的优点,使二进制解释了其记录数据的优势
第6章——低级程序设计语言与伪代码
6.1 计算机操作
计算机的定义:计算机是能够储存、检索和处理数据的可编程电子设备
故而,储存、检索和处理是计算机能够对数据执行的操作。
6.2 机器语言
机器语言(machine language):由计算机直接使用的二进制编码指令构成的语言
第一章中曾提到过,机器语言是最初人们编写指令所需的语言。后来才有其他程序设计语言的诞生,书中也提到,每条机器语言指令只能执行一个非常低级的任务。
机器语言处理过程中,每个微小的步骤都必须被明确地编码,故而有句话说得好:编程永远比看上去要难。
虚拟机:Pep/8
教材借助Pep/8虚拟机帮助理解机器语言的具体表现形式。首先其内存单元是65536字节的储存空间组成,Pep/8中字长为2字节或者16比特。
Pep/8的指令格式为两部分组成:8位的指令说明符和16位的操作说明符。
其中指令说明符(指令的第一个字节)说明了要执行什么操作和如何解释操作数的位置。
而操作数说明符(指令的第二和第三个字节)存放的则是操作数本身或者是操作数地址。有些指令没有操作数说明符。
3比特的寻址模式说明符表示了怎样解析指令中的操作数部分。
-
如果寻址模式是000,那么指令的操作数说明符中存储的就是操作数。这种寻址模式称为立即寻址(i) 。
-
如果寻址模式是001,那么操作数说明符中存储的是操作数所在的内存地址名称。这种寻址模式称为直接寻址(d) 。
立即寻址模式和直接寻址模式之间的差别十分重要,因为++它决定了操作中涉及的数据存储或将要被存储的位置 。++
没有操作数(要处理的数据)的指令称为一元指令,这些指令没有操作说明符 → 一元指令的长度是1个字节而并非3字节
一些示例指令
操作码 | 指令含义 |
---|---|
0000 | 停止执行 |
1100 | 将操作数载入寄存器A中 |
1110 | 将寄存器A的内容储存到操作数中 |
0111 | 将操作数加到寄存器A中 |
1000 | 在寄存器A的值中减去操作数的值 |
01001 | 把字符输入操作数 |
01010 | 从操作数输出字符 |
6.3 一个程序示例
前面提到过:机器语言处理过程中,每个微小的步骤都必须被明确地编码
而书中用最简单的机器语言程序向我们生动的解释了这句话的具体含义,其操作如下:
行为 | 二进制指令 | 十六进制指令 |
---|---|---|
Write'H' | 01010000 0000000001001000 | 50 0048 |
Write'e' | 01010000 0000000001100101 | 50 0065 |
Write'l' | 01010000 0000000001101100 | 50 006C |
Write'l' | 01010000 0000000001101100 | 50 006C |
Write'o' | 01010000 0000000001101111 | 50 006F |
Stop | 00000000 | 00 |
而在Python中只需要一条指令即可:
print('Hello')
机器语言作为最低级的程序设计语言的原因一目了然。
6.4 汇编语言
-
汇编语言(assembly language):一种低级语言,用助记码表示特定计算机的机器语言部分。
-
汇编器(assembler):把汇编语言程序翻译成机器代码的程序。
如下为Pep/8汇编语言:
助记忆码 | 操作数、寻址地址说明符 | 指令的含义 |
---|---|---|
STOP | 停止执行 | |
LDA | 0x008B,i | 把008B载入寄存器A |
LDA | 0x008B,d | 把内存单元8B中的内容载入寄存器A |
STA | 0x008B,d | 把寄存器A中的内容存入内存单元8B |
ADDA | 0x008B,i | 把008B加到寄存器A中 |
ADDA | 0x008B,d | 把内存单元8B中的内容加到寄存器A中 |
SUBA | 0x008B,i | 从寄存器A中减去008B |
SUBA | 0x008B,d | 从寄存器A中减去内存单元8B中的内容 |
BR | 分支到操作数说明符中指定的位置 | |
CHARI | 0x008B,d | 读取一个字符,把它存入内存单元8B中 |
CHARO | 0x008B,i | 输出字符B |
CHARO | 0x008B,d | 输出存储在内存单元8B中的字符 |
DECI | 0x008B,d | 读取一个十进制数,把它存储在内存单元8B中 |
DECO | 0x008B,i | 输出十进制数139(即十六进制的8B) |
DECO | 0x008B,d | 输出存储在内存单元8B中的十进制数 |
6.4.3 Hello程序的汇编语言版本
注释:为程序读者提供的解释性文字
Pep/8汇编语言中,注释符为;类似于Python中的#
CHARO 0x0048,i; Output an 'H'
CHARO 0x0065,i; Output an 'e'
CHARO 0x006C,i; Output an 'l'
CHARO 0x006C,i; Output an 'l'
CHARO 0x006F,i; Output an 'o'
STOP
.END
这段代码即为输出Hello的程序源代码。
而书中又举例了一个程序,并引导了具有分支的程序和具有循环结构的程序。在这里并不一一赘述。其类似与Python中的判断和循环语句。
6.5 表达算法
算法是解决方案的计划或概要,或者是解决问题的逻辑步骤顺序。在中学中我们也学了逻辑语句,即如下图。
graph LR
A-->B
B-->C
C-->B
伪代码(pseudocode):一种表达算法的语言
- 在6.5.1(伪代码的功能)的学习中,我们主要学习了伪代码的表达方式:复制、输入输出、选择以及重复
- 在6.5.2(执行伪代码)学习中则详细介绍了伪代码的执行
- 在6.5.3(写伪代码)中则介绍了伪代码编辑方法
- 在6.5.4(翻译伪代码算法)中则介绍了伪代码的翻译问题。
6.6 测试
测试计划:说明如何测试程序的文档
代码覆盖(明箱)测试法:通过执行代码中的所有语句测试程序或子程序的测试方法
数据覆盖(暗箱)测试法:把代码作为一个暗箱,基于所有可能的输入测试程序或子程序的测试方法。
测试计划实现:用测试计划中规定的测试用例验证程序是否输出了预期的结果。
第7章——问题求解与算法设计
7.1 如何解决问题
“如何解决它”
graph TD
理解问题-->设计方案
设计方案-->执行方案
执行方案-->回顾
算法(algorithm):在有限的时间内用有限的数据解决问题或子问题的明确指令集合
第9章-面向对象设计与高级程序设计语言
第一章中曾介绍,随着时间的推移如何围绕硬件建立不同层次的程序设计语言,从而简化 码农 程序员的工作。
第六章中介绍了机器码,然后出现了助记忆码以及表示指令的汇编语言。虽然汇编语言前进了一步,但是对于不同机器,程序员仍然需要需要记住不同的机器指令,故诞生了高级语言。
9.1 面向对象的方法
对象:在问题背景中相关的事物或实体。
对象类/类:一组具有相似的属性和行为的对象的描述。
域:类中的特定项,可以是数据或子程序。
方法:定义了类的一种行为的特定算法。
封装:把数据和动作集中在一起,使数据和动作的逻辑属性与他们实现细节分离。
9.2 翻译过程
编译器:把用高级语言编写的程序翻译成机器码的程序。
解释器:输入用高级语言编写的程序,指导计算机执行每个语句指定的动作的程序。
字节码:编译Java源代码使用的标准机器语言。
9.3 命令式范型
包括命令式范型和声明式范型。
9.4 高级程序设计语言的功能性
本节涵盖了
- 布尔表达式
- 数据归类
- 输入/输出结构
- 控制结构
9.5 面向对象语言的功能性
- 封装
- 类
- 继承
- 多态