### 1.1.1 计算机与计算
计算机是当代最伟大的发明之一。自从人类制造出第一台电子数字计算机,迄今已近 70 年。经过这么多年的发展,现在计算机已经应用到社会、生活的几乎每一个方面。人们用计 算机上网冲浪、写文章、打游戏或听歌看电影,机构用计算机管理企业、设计制造产品或从 事电子商务,大量机器被计算机控制,手机与电脑之间的差别越来越分不清,……总之计算 机似乎无处不在、无所不能。那么,计算机究竟是如何做到这一切的呢?为了回答这个问题, 需要了解计算机的工作原理。
提到计算机,人们头脑中会首先浮现出显示器、键盘、主机箱等一堆设备——计算机硬 件。了解一点硬件设备的基本知识自然是需要的,不过从学习用计算机解决问题这个层次看, 并不需要掌握多少底层硬件知识。在此我们仅介绍现代计算机的主要功能部件,目的是要了 解用计算机解决问题的计算机制。现代计算机的主要功能部件如图 1.1 所示。
![](https://box.kancloud.cn/2016-02-22_56cafcdb6cd84.png)
CPU、指令与程序 中央处理单元(CPU)是计算机的计算部件,能够执行机器指令,或简称指令(instruction)。
每条指令表达的是对特定数据执行特定操作。某种 CPU 能执行的全体指令是由该 CPU 的制 造商设计并保持固定不变的,称为该 CPU 的指令集。例如,Intel 公司为它的 80x86 系列处 理器设计了上百条的指令。
外行人也许会以为,计算机功能如此强大,必定是因为它能执行功能强大的指令。然而 事实并非如此。即使是当今技术最先进、计算能力最强大的计算机,它的 CPU 也只会执行一 些非常简单的指令,例如将两个数相加、测试两个数是否相等、把数据放入指定的存储单元 等等。
由于每条机器指令都只能完成很简单的操作,因此仅靠少数几条指令是做不了什么复杂 的事情的。但是,如果将成千上万条简单指令组合起来,却能解决非常复杂的问题!亦即, 复杂操作可以通过执行按特定次序排列的许多简单操作而实现。这种由许多指令按次序排列 而成并交给计算机逐条执行的指令序列称为程序(program)。为了用计算机解决问题,把问 题的解法表达成一个指令序列(即程序)的过程,称为程序设计或编程(programming)。可 见,计算机所做的所有神奇的事情,都是靠一步一步执行的、平凡而乏味的简单指令序列做 到的。计算机一点也不神奇,它唯一会做的事情就是机械地执行预定的指令序列。
存储器
存储器是计算机的记忆部件,用于存储数据和程序。 存储器分为主存储器和次级存储器,它们是用不同的物理材料制造的。CPU 只能直接访
问主存储器,也只有主存储器才能提供与 CPU 相匹配的存取速度。但主存储器需要靠持续供 电来维持存储,一旦断电,存储的数据或程序就会消失。为了持久存储信息,可以使用即使 断电也能维持存储的次级存储器,如当前普遍使用的磁盘。CPU 不能直接访问次级存储器, 次级存储器上的数据或程序必须先送到主存储器中,才能被 CPU 存取或执行。次级存储器的 读写速度远远低于主存储器,这个差别极大地影响了用计算机解决问题时所使用的方法。
现代计算机在体系结构上的特点是:数据和程序都存储在主存储器中,CPU 通过访问主 存储器来取得待执行的指令和待处理的数据。这称为冯·诺伊曼(von Neumann)体系结构。
输入/输出设备
输入和输出设备提供了人与计算机进行交互的手段。我们通过输入设备向计算机输入信 息,计算机则通过输出设备将计算结果告诉我们。传统的输入设备有键盘和鼠标等,输出设 备有显示器和打印机等。现代的触摸屏则兼具输入和输出的功能。
计算
了解了计算机的组成,就能理解计算机解决问题的过程是怎样的。我们来看一个常见任 务——用计算机写文章——是如何解决的。为了解决这个问题,首先需要编写具有输入、编 辑、保存文章等功能的程序,例如微软公司的程序员们所写的 Word 程序。如果这个程序已 经存入我们计算机的次级存储器(磁盘),通过双击 Word 程序图标等方式可以启动这个程序, 导致该程序从磁盘被加载到主存储器中。然后 CPU 逐条取出该程序的指令并执行,直至最后 一条指令执行完毕,程序即告结束。在执行过程中,有些指令会导致与用户的交互,例如用 户利用键盘输入或删除文字,利用鼠标点击菜单进行存盘或打印等等。就这样,通过执行成 千上万条简单的指令,最终解决了用计算机写文章的问题。
针对一个问题,设计出解决问题的程序(指令序列),并由计算机来执行这个程序,这 就是计算(computation)。
通过计算,使得只会执行简单操作的计算机能够完成神奇的复杂任务,所以计算机的神 奇表现其实都是计算的威力。如果读者对计算的能力还有疑问,下面这个例子或许能打消这 个疑问。Lucy 是一个只学过加法的一年级小学生,她能完成一个乘法运算任务吗?答案是肯 定的!解决问题的关键在于编写出合适的指令序列让 Lucy 机械地执行。例如下列“程序” 就能使 Lucy 算出 m×n:
```
在纸上写下 0,记住结果;
给所记结果加上第 1 个 n,记住结果;
给所记结果加上第 2 个 n,记住结果;
……
给所记结果加上第 m 个 n,记住结果。至此就得到了 m×n。
```
不难看出,这个指令序列的每一步都是 Lucy 能够做到的,因此最后确实能完成乘法运 算。这就是“计算”所带来的成果①。
计算机就是通过这样的“计算”来解决所有复杂问题的。执行大量简单指令组成的程序 虽然枯燥繁琐,但计算机作为一种机器,其特长正在于机械地、忠实地、不厌其烦地执行大 量简单指令!
> ① 当然,这种计算看上去就很繁琐,原因在于用到的基本指令(加法)太简单。如果 Lucy 学习了更“高级” 的指令(如乘法口诀等),就可以更快捷地完成乘法运算。
计算机的通用性
通过前面的介绍,可知计算机就是进行“计算”的机器。显然,这里的“计算”并不是日常说的数学计算。事实上,计算机在屏幕上显示信息,在 Word 文档中查找并替换文本, 播放 mp3 音乐,这些都是计算。
理解了计算机是如何计算的,也就能理解为什么计算机具有通用性,能解决各种不同类 型的问题。其中的奥秘就在于程序。如果想用计算机写文章,就将 Word 之类的程序加载到 主存中让 CPU 去执行,这时计算机就成了一台电子打字机;如果想用计算机听音乐,就将 Media Player 之类的程序加载到主存中让 CPU 去执行,这时计算机就成了一台音频播放机; 如果将 IE 之类的程序加载到主存中让 CPU 去执行,计算机就可以在互联网上浏览信息。总 之,一台计算机的硬件虽然固定不变,但通过加载执行不同的程序,就能实现不同的功能, 解决不同的问题。
我们平时说的计算机都是指通用计算机,能够安装执行各种不同的程序。其实在工业控 制和嵌入式设备等领域,也存在专用计算机,它们只执行预定的程序,从而实现固定的功能。 例如号称电脑控制的洗衣机,其实就是能执行预定程序的计算机。
计算机科学
为了更好地利用计算机解决问题,人们深入研究了关于计算的理论、方法和技术,形成 了专门研究计算的学问——计算机科学(computer science)①。
计算机科学包含很多内容,本书的主题是计算机科学家在用计算机解决问题时建立的一 些思想和方法,这些思想和方法普遍存在于计算机科学的各个分支之中。作为例子,我们来 看计算机科学家思考的一个根本问题:到底什么问题是计算机可计算的?一般人会以为,一 个问题能不能用计算机计算,取决于该计算机的计算能力;而计算机的计算能力又取决于 CPU 的运算速度、指令集、主存储器容量等硬件指标。真如此的话,显然巨型计算机应该具 有比微型计算机更强大的计算能力。然而,作为计算机科学理论基础的可计算性理论却揭示 了一个出人意料的结论:所有计算机的计算能力都是一样的!尽管不同计算机有不同的指令 集和不同性能的硬件,但一台计算机能解决的问题,另一台计算机肯定也能解决。
- 前言
- 第 1 章 计算与计算思维
- 1.1 什么是计算?
- 1.1.1 计算机与计算
- 1.1.2 计算机语言
- 1.1.3 算法
- 1.1.4 实现
- 1.2 什么是计算思维?
- 1.2.1 计算思维的基本原则
- 1.2.2 计算思维的具体例子
- 1.2.3 日常生活中的计算思维
- 1.2.4 计算思维对其他学科的影响
- 1.3 初识 Python
- 1.3.1 Python 简介
- 1.3.2 第一个程序
- 1.3.3 程序的执行方式
- 1.3.4 Python 语言的基本成分
- 1.4 程序排错
- 1.5 练习
- 第 2 章 用数据表示现实世界
- 2.1 数据和数据类型
- 2.1.1 数据是对现实的抽象
- 2.1.1 常量与变量
- 2.1.2 数据类型
- 2.1.3 Python 的动态类型*
- 2.2 数值类型
- 2.2.1 整数类型 int
- 2.2.2 长整数类型 long
- 2.2.3 浮点数类型 float
- 2.2.4 数学库模块 math
- 2.2.5 复数类型 complex*
- 2.3 字符串类型 str
- 2.3.1 字符串类型的字面值形式
- 2.3.2 字符串类型的操作
- 2.3.3 字符的机内表示
- 2.3.4 字符串类型与其他类型的转换
- 2.3.5 字符串库 string
- 2.4 布尔类型 bool
- 2.4.1 关系运算
- 2.4.2 逻辑运算
- 2.4.3 布尔代数运算定律*
- 2.4.4 Python 中真假的表示与计算*
- 2.5 列表和元组类型
- 2.5.1 列表类型 list
- 2.5.2 元组类型 tuple
- 2.6 数据的输入和输出
- 2.6.1 数据的输入
- 2.6.2 数据的输出
- 2.6.3 格式化输出
- 2.7 编程案例:查找问题
- 2.8 练习
- 第 3 章 数据处理的流程控制
- 3.1 顺序控制结构
- 3.2 分支控制结构
- 3.2.1 单分支结构
- 3.2.2 两路分支结构
- 3.2.3 多路分支结构
- 3.3 异常处理
- 3.3.1 传统的错误检测方法
- 3.3.2 传统错误检测方法的缺点
- 3.3.3 异常处理机制
- 3.4 循环控制结构
- 3.4.1 for 循环
- 3.4.2 while 循环
- 3.4.3 循环的非正常中断
- 3.4.4 嵌套循环
- 3.5 结构化程序设计
- 3.5.1 程序开发过程
- 3.5.2 结构化程序设计的基本内容
- 3.6 编程案例:如何求 n 个数据的最大值?
- 3.6.1 几种解题策略
- 3.6.2 经验总结
- 3.7 Python 布尔表达式用作控制结构*
- 3.8 练习
- 第 4 章 模块化编程
- 4.1 模块化编程基本概念
- 4.1.1 模块化设计概述
- 4.1.2 模块化编程
- 4.1.3 编程语言对模块化编程的支持
- 4.2 Python 语言中的函数
- 4.2.1 用函数减少重复代码 首先看一个简单的用字符画一棵树的程序:
- 4.2.2 用函数改善程序结构
- 4.2.3 用函数增强程序的通用性
- 4.2.4 小结:函数的定义与调用
- 4.2.5 变量的作用域
- 4.2.6 函数的返回值
- 4.3 自顶向下设计
- 4.3.1 顶层设计
- 4.3.2 第二层设计
- 4.3.3 第三层设计
- 4.3.4 第四层设计
- 4.3.5 自底向上实现与单元测试
- 4.3.6 开发过程小结
- 4.4 Python 模块*
- 4.4.1 模块的创建和使用
- 4.4.2 Python 程序架构
- 4.4.3 标准库模块
- 4.4.4 模块的有条件执行
- 4.5 练习
- 第 5 章 图形编程
- 5.1 概述
- 5.1.1 计算可视化
- 5.1.2 图形是复杂数据
- 5.1.3 用对象表示复杂数据
- 5.2 Tkinter 图形编程
- 5.2.1 导入模块及创建根窗口
- 5.2.2 创建画布
- 5.2.3 在画布上绘图
- 5.2.4 图形的事件处理
- 5.3 编程案例
- 5.3.1 统计图表
- 5.3.2 计算机动画
- 5.4 软件的层次化设计:一个案例
- 5.4.1 层次化体系结构
- 5.4.2 案例:图形库 graphics
- 5.4.3 graphics 与面向对象
- 5.5 练习
- 第 6 章 大量数据的表示和处理
- 6.1 概述
- 6.2 有序的数据集合体
- 6.2.1 字符串
- 6.2.2 列表
- 6.2.3 元组
- 6.3 无序的数据集合体
- 6.3.1 集合
- 6.3.2 字典
- 6.4 文件
- 6.4.1 文件的基本概念
- 6.4.2 文件操作
- 6.4.3 编程案例:文本文件分析
- 6.4.4 缓冲
- 6.4.5 二进制文件与随机存取*
- 6.5 几种高级数据结构*
- 6.5.1 链表
- 6.5.2 堆栈
- 6.5.3 队列
- 6.6 练习
- 第 7 章 面向对象思想与编程
- 7.1 数据与操作:两种观点
- 7.1.1 面向过程观点
- 7.1.2 面向对象观点
- 7.1.3 类是类型概念的发展
- 7.2 面向对象编程
- 7.2.1 类的定义
- 7.2.2 对象的创建
- 7.2.3 对象方法的调用
- 7.2.4 编程实例:模拟炮弹飞行
- 7.2.5 类与模块化
- 7.2.6 对象的集合体
- 7.3 超类与子类*
- 7.3.1 继承
- 7.3.2 覆写
- 7.3.3 多态性
- 7.4 面向对象设计*
- 7.5 练习
- 第 8 章 图形用户界面
- 8.1 图形用户界面概述
- 8.1.1 程序的用户界面
- 8.1.2 图形界面的组成
- 8.1.3 事件驱动
- 8.2 GUI 编程
- 8.2.1 UI 编程概述
- 8.2.2 初识 Tkinter
- 8.2.3 常见 GUI 构件的用法
- 8.2.4 布局
- 8.2.5 对话框*
- 8.3 Tkinter 事件驱动编程
- 8.3.1 事件和事件对象
- 8.3.2 事件处理
- 8.4 模型-视图设计方法
- 8.4.1 将 GUI 应用程序封装成对象
- 8.4.2 模型与视图
- 8.4.3 编程案例:汇率换算器
- 8.5 练习
- 第 9 章 模拟与并发
- 9.1 模拟
- 9.1.1 计算机建模
- 9.1.2 随机问题的建模与模拟
- 9.1.3 编程案例:乒乓球比赛模拟
- 9.2 原型法
- 9.3 并行计算*
- 9.3.1 串行、并发与并行
- 9.3.2 进程与线程
- 9.3.3 多线程编程的应用
- 9.3.4 Python 多线程编程
- 9.3.5 小结
- 9.4 练习
- 第 10 章 算法设计和分析
- 10.1 枚举法
- 10.2 递归
- 10.3 分治法
- 10.4 贪心法
- 10.5 算法分析
- 10.5.1 算法复杂度
- 10.5.2 算法分析实例
- 10.6 不可计算的问题
- 10.7 练习
- 第 11 章 计算+X
- 11.1 计算数学
- 11.2 生物信息学
- 11.3 计算物理学
- 11.4 计算化学
- 11.5 计算经济学
- 11.6 练习
- 附录
- 1 Python 异常处理参考
- 2 Tkinter 画布方法
- 3 Tkinter 编程参考
- 3.1 构件属性值的设置
- 3.2 构件的标准属性
- 3.3 各种构件的属性
- 3.4 对话框
- 3.5 事件
- 参考文献