### 1.1.2 計算機語言
如前所述,計算機解決問題的過程實質上是機械地執行人們為它編制的指令序列的過程。為了告訴計算機應當執行什么指令,需要使用某種計算機語言。這種計算機語言能夠精 確地描述計算過程,稱為程序設計語言或編程語言(programming language)。
與計算機打交道的理想語言當然是像科幻電影所展示的那樣,人類用自然語言與計算機(電影中更多的是機器人)進行對話。遺憾的是,由于自然語言的詞語和句子往往有歧義, 既不精確也不簡練,至少目前的計算機還不能很好地理解自然語言。所以計算機科學家設計 了人造語言來與計算機進行交流。編程語言是人工設計的形式語言,具有嚴格的語法和語義, 因此沒有歧義的問題。
機器語言
CPU 制造商在設計某種 CPU 硬件結構的同時,也為其設計了一種“母語”——指令集, 這種語言稱為機器語言(machine language)。機器語言在形式上是二進制的,即所有指令都 是由 0 和 1 組成的二進制序列。利用機器語言寫的程序自然就是二進制指令的序列。我們來
> ① 不能望文生義地以為計算機科學是關于計算機的學問。著名計算機科學家 Dijkstra 有一句名言:計算機之 于計算機科學,正如望遠鏡之于天文學。
看一條 Intel 8086 處理器的機器指令:
```
0000010000000001
```
只要你將這一串 0/1 序列交給 CPU,CPU 就會按指令要求執行特定操作——將 1 存儲 到計算機的某個寄存器①當中。計算機只懂得這種非常低級的機器語言。顯然,用機器語言 編程序與計算機打交道,實在是太麻煩了,畢竟機器語言指令既難理解又難記憶。
匯編語言
為了使編程更容易,人們發明了匯編語言(assembly language)。匯編語言本質上是將機 器指令用更加容易為人們所理解和記憶的“助憶符”形式表現出來。例如前面那條將 1 存入 寄存器的機器指令在匯編語言中可以寫成:
```
MOV AL, 1
```
可見在匯編語言中,指令的操作符是用 MOV(即 move)之類的助憶符表示的,操作數 據也用易理解的數字或符號來表示,因此指令的含義變得非常容易理解,例如上面這條指令 可以讀成“將 1 送入寄存器 AL”。雖然編寫匯編語言程序對程序員來說難度降低了很多,但 是很遺憾,計算機并不懂匯編語言。為了使計算機理解匯編語言程序,需要用一種稱為匯編 器(assembler)的程序把匯編語言程序翻譯成機器語言程序。有了匯編器這個“翻譯”,程 序員“說”的匯編語言就能被計算機“聽”懂并執行了。
即使到了今天,匯編語言在某些場合(如嵌入式系統)仍然非常有用,因為用匯編語言 能夠寫出執行效率很高的程序。但是,匯編語言和機器語言并沒有本質上的差別,同樣屬于 非常低級的語言。而低級語言具有無法克服的缺點:第一,低級語言與機器硬件結構緊密關 聯,因此為掌握低級語言必須了解很多底層硬件知識,導致低級語言的學習和使用都很困難, 開發效率低而且容易出錯;第二,由于不同硬件的計算機具有不同的機器語言和匯編語言, 一類計算機上的低級語言程序不能拿到另一類計算機上執行,我們說低級語言程序不具有可 移植性。
高級編程語言
為了克服低級語言的缺點,計算機科學家設計出了更加易用的高級編程語言(high-level programming language)。高級語言相對于機器語言和匯編語言具有很多優點:第一,高級語 言吸收了人們熟悉的自然語言(英語)和數學語言的某些成分,因此非常易學、易用、易讀; 第二,高級語言在構造形式和意義方面具有嚴格定義,從而避免了語言的歧義性;第三,高 級語言與計算機硬件沒有關系,用高級語言寫的程序可以移植到各種計算機上執行。
如果用高級語言來表達將 1 存入某處的指令,可以寫成這樣:
```
x = 1
```
顯然這更加類似于我們從小就熟悉的數學語言,很容易理解和學會使用。
編譯和解釋
用高級語言所寫的程序是不能直接交給計算機執行的,因為計算機完全不懂 x = 1 之 類的語句。為了讓計算機理解并執行,必須先將高級語言程序翻譯成機器語言程序。
高級語言的翻譯有兩種方式:編譯和解釋。
編譯器(compiler)將高級語言程序(稱為源代碼)完整地翻譯成等價的機器語言程序(稱為目標代碼),如圖 1.2 所示。編譯的特點是“一勞永逸”,整個源代碼一旦翻譯完畢, 今后就可以在任何時候多次執行目標代碼,再也不需要編譯器的參與了。就像翻譯家將一本 英文小說筆譯成中文,這是一次性的工作,作為翻譯結果的中譯本可以多次閱讀。以編譯方
> ① 寄存器是 CPU 里面的高速存儲部件。
式處理源代碼,對目標代碼可以進行很多細致的優化,從而程序的執行速度一般會更快。就 像翻譯家對中譯本可以精雕細琢,從而達到信達雅的境界。

圖 1.2 高級語言的編譯
解釋器(interpreter)直接分析并執行高級語言程序,如圖 1.3 所示。解釋的特點是“見 招拆招”,對源代碼總是臨機進行解釋和執行。就像外交部的口譯人員所做的工作,國家主席 說一句中文,口譯者立即將它翻譯成英文;即使主席后來說了同樣的話,口譯者還是要重新 翻譯,無法重復利用以前的翻譯結果。解釋執行的處理方式無法進行上下文信息來進行優化, 導致程序執行速度較慢,正如口譯者無法琢磨最佳譯文一樣。但解釋性語言具有更靈活的編 程環境,可以交互式地輸入程序語句并立即執行,程序員面對的仿佛是一臺能聽懂高級語言 的計算機。

圖 1.3 高級語言的解釋
高級語言之所以具有前面提到的可移植性,正是因為高級語言的這種先翻譯后執行的特 點。只要一臺計算機上有合適的編譯器或解釋器,用某種高級語言編寫的程序可以在該計算 機上執行。就像國家主席的講話可以被中譯英口譯人員翻譯給英語國家的人聽,也可以被中 譯法口譯人員翻譯給法語國家的人聽一樣。
還要說明的是,編譯器和解釋器本身也是程序,這種程序所執行的計算就是將別的程序 翻譯成機器能夠理解的指令。為了讓一臺計算機能夠執行某種高級語言程序,必須先在該計 算機上安裝特定高級語言的編譯器或解釋器程序!
迄今為止,計算機科學家們發明了數百種高級編程語言。不同語言的細節不盡相同,但 一些基本語言構造在絕大多數語言中都是存在的,例如輸入輸出、基本的數學運算、有條件 地執行和重復地執行等等。一般只要掌握一種編程語言,就足以利用計算機去解決實際問題。 而且一旦掌握了一種編程語言,再去學習其他語言也會變得非常容易。
本書要討論的是用計算機解決問題時的思想和方法,這些內容原則上與使用哪種編程語 言沒有關系。但是,為了更好地掌握本書的內容,需要進行編程實踐,這就要求我們必須學 會某種編程語言。選擇什么編程語言呢?高級編程語言雖多,但流行的并沒有多少。2012 年 4 月公布的 TIOBE 編程語言排行榜①上,位列前 10 名的語言分別是 C、Java、C++、Objective-C、 C#、PHP、(Visual)Basic、Python、JavaScript 和 Perl。本書將采用位列其中的 Python 語言, 選擇這個語言的理由是該語言非常易學易用,而且特別適合教學。
> ① [http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html](http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html)
- 前言
- 第 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 事件
- 參考文獻