打开浏览器、播放音乐、输入消息,计算机几乎立刻就会作出响应。但究竟是什么告诉计算机,应该怎样完成这些事情?
答案要从计算机程序说起。
欢迎回到 Gate & Kernel。在这里,我们从数字逻辑到操作系统,一起探索计算机的工作原理。
这是编程基础系列的第一课。后续课程将使用 C 语言讲解,但今天不需要任何编程经验。我们先理解所有程序背后的基本思想:描述一组计算机能够执行的操作。
第一章:什么是计算机程序?
计算机程序,是以计算机系统能够执行的形式表达的一组指令。“执行”就是按照指令完成相应的操作,我们也把执行程序称为“运行程序”。
程序可以计算总价、显示图片、处理键盘输入,也可以控制机器的某个部分。有些程序很小,只完成一项任务;另一些程序则由许多相互连接的部分组成,能够支持复杂的活动。
例如,计算器程序需要接收数字、确定运算方式,再显示结果。网页浏览器的任务更多:接收信息、解释网页、显示文字和图片,并响应用户的操作。
虽然规模不同,但它们都依靠指令来规定应该发生什么。
编程,就是设计、编写、测试和改进这些指令的过程。
第二章:硬件与软件
理解程序之前,需要先认识两个概念:硬件和软件。
硬件是计算机中实际存在的物理部件,例如处理器、内存芯片、存储设备、键盘和显示器。软件则包括程序及其相关资源,例如配置信息和辅助数据。
音乐播放器应用属于软件,发出声音的扬声器属于硬件。
中央处理器,英文缩写为 CPU,负责执行机器指令。机器指令是按照处理器能够识别的形式编码的基本操作。
内存,通常指 RAM,用于保存正在使用的指令和数据。存储设备,例如固态硬盘,则可以在计算机关机后继续保存文件和程序。
这些部分相互配合:软件规定操作,硬件完成执行这些操作所需的实际工作。
第三章:指令与数据
程序需要处理数据。数据,就是以计算机能够存储和处理的形式表示的信息,包括数字、文字、图像和声音等。
以一个简单的加法为例:7 加 5 等于 12。
7 和 5 是输入数据,指令要求计算机执行加法,12 则是计算结果。
这里有一个重要区别:指令描述要执行的操作,数据提供这些操作所处理的内容。
对于音乐播放器,程序中的指令规定如何读取和处理音频信息,而歌曲文件提供数据。对于图片编辑器,指令规定各种编辑操作,而照片提供图像数据。
因此,同一个程序接收到不同数据时,可以产生不同结果。计算器不需要为每一组数字准备一个独立程序,同样的加法操作可以处理许多不同的输入。
第四章:输入、处理与输出
许多程序都可以通过三个概念来理解:输入、处理和输出。
输入,是程序接收到的信息。处理,是程序对这些信息执行的操作。输出,是程序产生的信息或结果。
假设我们要编写一个程序,计算购买若干本相同笔记本的总价。
用户输入一本笔记本的价格和购买数量,这些数值就是输入。程序将单价乘以数量,这一步就是处理。最后,程序显示总价,这就是输出。
输入不一定来自键盘,也可以来自文件、传感器、网络连接或其他程序。输出也不一定显示在屏幕上,程序还可以保存文件、发送消息、播放声音,或者向设备发出控制命令。
有些程序处理一次请求后就结束,另一些程序则会在运行期间不断接收输入、产生输出。
第五章:程序需要明确的步骤
人与人交流时,经常会省略一些细节,因为对方可以根据经验补充理解。例如,你让一个人计算购物总价,他通常知道应该把各项价格加起来。
程序则需要明确规定相关操作。
对于购买笔记本的例子,我们可以把步骤写成:
1. 获取一本笔记本的价格。
2. 获取购买数量。
3. 将单价乘以数量。
4. 显示计算结果。
这种为解决问题而制定的明确步骤,称为算法。
算法描述如何完成任务,程序则用编程语言表达这些步骤,并加入实际运行所需的细节。例如,完整程序还需要处理用户怎样输入信息,以及输入无效时应该怎么办。
在编写代码之前,可以先问自己三个问题:我们已经有哪些信息?我们希望得到什么结果?需要哪些步骤才能从输入得到结果?
第六章:程序可以作出判断
程序并不总是执行完全相同的操作,它可以根据条件选择下一步做什么。
条件,就是一个用于判断的测试,其结果决定接下来采取哪种操作。
假设笔记本商店规定,订单总价达到 50 美元即可免运费。程序可以按照这样的规则执行:如果总价不少于 50 美元,运费就是零;否则,增加运费。
这就是条件判断。程序检查总价,然后沿着相应的执行路径继续运行。
同样的思想也出现在许多日常程序中。登录系统检查是否满足访问条件,游戏检查玩家是否拥有足够的积分,温度控制程序检查温度是否低于设定值。
当我们说程序“作出决定”时,意思是它检查某个条件,再按照预先规定的规则处理判断结果。
第七章:程序可以重复执行任务
计算机的重要用途之一,是快速重复执行操作。
循环,就是让一组操作重复执行的编程结构。
假设要计算 100 件不同商品的总价。如果为每件商品分别编写一个加法步骤,会很繁琐。程序可以重复执行一套通用步骤:
1. 将总价设为零。
2. 取得下一件商品的价格。
3. 把这个价格加到总价中。
4. 重复执行,直到所有商品都处理完毕。
5. 显示总价。
每次重复执行的操作类型相同,但处理的商品价格可以不同。
循环可以重复固定次数,也可以在某个条件成立时继续执行,或者持续运行直到收到停止要求。例如,监测传感器的程序可以反复获取读数并检查数值。
顺序、判断和重复,是描述许多程序任务的基础。其中,顺序就是按照一定次序执行操作。
第八章:什么是编程语言?
编程语言,是用于表达程序的形式化语言。常见的编程语言包括 C、C++、Python 和 Java。
每种语言都有规定程序如何书写的规则,这些规则称为语法。就像自然语言中的标点和词序帮助组织句子一样,编程语言的语法帮助组织代码。
程序员编写的文本称为源代码。
下面是一小段 C 语言源代码:
int total = 7 + 5;
现在不需要记住具体写法。可以先把它理解为:计算 7 加 5,并用结果初始化一个名为 total 的整数变量。
整数是不带小数部分的数,例如 7、0 和 −3。变量可以先理解为程序中用名称标识、用于保存数值的位置。初始化,就是在创建变量时为它设置初始值。
这里的 total 是变量名,后续代码可以通过这个名称使用保存的值。末尾的分号用于结束这条声明。
语句是表达操作或控制程序执行的代码单位,声明则用于介绍变量等名称及其类型。现在不必深入区分它们,后续课程会结合实例逐步讲解。
这行代码只是程序的一部分,但它展示了编程语言的作用:让我们能够准确表达希望计算机完成的操作。
第九章:源代码怎样变成计算机可以运行的程序?
处理器不会直接把 C 语言源代码当作机器指令执行,需要软件工具对它进行翻译和处理。
编译器,是把源代码转换为另一种形式的程序。在典型的 C 语言开发流程中,编译过程会生成包含机器代码的中间文件。
机器代码,是处理器能够执行的指令的编码形式。
链接器随后把所需的已编译部分组合起来,并连接它们之间的引用,帮助生成可执行文件。例如,一部分代码调用另一部分代码中的函数时,需要建立相应联系。
可执行文件,是按照操作系统能够加载并运行的格式组织的文件。
后面的课程会专门介绍这一过程。现在只需要理解:程序员编写源代码,开发工具将它转换为可以运行的形式。
不同语言及其实现方式,可能采用不同的执行方法。有些使用解释器,也就是负责执行代码所描述操作的程序;有些则结合解释和编译。
另外,一条源代码语句不一定对应一条机器指令。工具可能将它转换为多条指令,也可能在运行之前简化相关计算。
第十章:运行程序时会发生什么?
保存在硬盘上的程序,与正在运行的程序,并不是同一个概念。
启动应用程序时,操作系统会为它准备执行环境。操作系统是负责管理计算机资源、向程序提供服务的系统软件,Windows 和 Linux 都是操作系统。
程序运行起来之后的一个实例,称为进程。
系统为进程安排内存,并分配使用 CPU 的机会。程序在运行时按照指令处理数据,也可能请求操作系统提供服务,例如读取文件或接收网络信息。
同一个程序可以拥有多个运行实例,每个实例可以处理不同的数据。
例如,两个计算器程序实例可以分别进行不同的计算,即使它们来自同一个可执行文件。
等编程基础建立起来后,我们会继续深入学习进程和操作系统服务。
第十一章:程序出错时会怎样?
程序可能包含错误。软件缺陷通常称为 Bug。
有些错误违反编程语言的规则,编译器能够发现其中许多问题,并提示程序员修改代码。
另一些错误不会阻止程序运行,却会导致错误结果。
例如,笔记本总价程序本来应该把单价乘以数量,却错误地执行了加法。如果单价是 4 美元、数量是 3,程序就会得到 7,而正确结果应该是 12。
加法本身是有效操作,但解决问题的逻辑错了。这类在步骤或推理上出现的错误,称为逻辑错误。
程序还可能在运行过程中遇到文件不存在、输入无效等问题。
测试,是检查程序行为是否符合预期。调试,是调查、定位并修正程序缺陷的过程。
因此,编程不仅是让代码运行起来,还需要确认它能够完成预期任务,并正确处理相关情况。
第十二章:小练习——先描述程序,再编写代码
即使还没有学会编程语法,也可以开始练习编程思维。
假设我们需要一个比较两个数字的程序。它的任务是报告哪个数字更大,或者说明两者相等。
先考虑三个问题:它需要什么输入?它需要作出哪些判断?它应该产生什么输出?
这个程序需要两个数字作为输入。
首先,检查第一个数字是否大于第二个。如果是,就报告第一个数字更大。
否则,再检查第二个数字是否大于第一个。如果是,就报告第二个数字更大。
如果两个数字都不大于对方,就报告它们相等。
可以用三组数据检查这个过程:8 和 3、3 和 8,以及 5 和 5。这三组数据分别对应三种可能的比较结果。
这样,你已经描述了一个简单算法,并选择了几个测试案例。后续课程中,我们会用 C 语言表达这样的处理步骤。
第十三章:总结
计算机程序描述了计算机系统能够执行的操作。
程序处理数据,按照顺序执行步骤,根据条件选择操作,并通过循环重复完成任务。
编程语言让我们能够用源代码表达这些操作,编译器、解释器及其他工具则帮助代码运行起来。
创建一个有用的程序,需要理解任务、制定明确步骤、编写代码,并检查结果。
开始学习时,不需要先掌握计算机的所有内部机制。可以从一个小问题出发,确定输入和输出,再把处理步骤说明白。
下一课,我们将介绍 C 语言:它是什么、能够用来做什么,以及为什么本系列选择使用它。
