杜友福等編著的《C語言程序設(shè)計(第3版)》是《C語言程序設(shè)計》的第三版,為C語言程序設(shè)計課程教材。全書共分13章,全面地介紹了C語言的基本語法及C語言程序的設(shè)計方法,內(nèi)容包括:C語言程序設(shè)計概述,數(shù)據(jù)類型、運算符與表達式,順序結(jié)構(gòu)程序設(shè)計,選擇結(jié)構(gòu)程序設(shè)計,循環(huán)結(jié)構(gòu)程序設(shè)計,數(shù)組,函數(shù),用戶標識符的作用域和存儲類,編譯預(yù)處理,指針,結(jié)構(gòu)體、共用體和用戶定義類型,位運算,文件。每章后面均配有大量的習(xí)題,附錄中介紹了C語言的關(guān)鍵字、AscII代碼表、運算符及其優(yōu)先級和結(jié)合性、C語言的常用庫函數(shù)。為了使于教學(xué)和自學(xué),本書配有《C語言程序設(shè)計導(dǎo)學(xué)》(第三版)。 《C語言程序設(shè)計(第3版)》特別適舍于本、專科非計算機專業(yè)的初學(xué)者,也可供計算機等級考試者和其他各類學(xué)習(xí)者使用參考。
計算機知識已成為在校學(xué)生必須掌握的一門技能,要能熟練地使用計算機,特別是利用計算機開發(fā)軟件,必須至少熟練地掌握一門計算機語言。 杜友福等編著的《C語言程序設(shè)計(第3版)》為《C語言程序設(shè)計》的修訂第三版,全書共十三章,全面地介紹了C語言的基本語法及C語言程序的設(shè)計方法。每章后面均配有大量的習(xí)題,在做選擇題時,不僅要選擇答案,更重要的是要學(xué)會分析,為什么是對的?錯在什么地方?這樣才有收獲。在做程序填空題時,最好是將填空后的完整程序在機器上調(diào)試一下,這樣有助于對程序及算法的分析和理解。編程題,要自己獨立編寫并上機調(diào)試。通過一系列環(huán)節(jié)的訓(xùn)練,才能達到學(xué)好C語言的目的。
第1章 C語言程序設(shè)計概述
1.1 程序和程序設(shè)計語言
1.1.1 程序與程序設(shè)計
1.1.2 程序設(shè)計語言
1.1.3 語言處理程序
1.1.4 設(shè)計程序的基本原則
1.2 算法
1.2.1 算法及算法的特性
1.2.2 算法的表示
1.3 結(jié)構(gòu)化程序設(shè)計方法
1.4 C程序的基本結(jié)構(gòu)
習(xí)題1
第2章 數(shù)據(jù)類型、運算符與表達式
2.1 C語言的數(shù)據(jù)類型
2.2 常量、變量與標識符
2.3 整型數(shù)據(jù)
2.4 實型數(shù)據(jù)
2.5 字符型數(shù)據(jù)
2.6 算術(shù)運算符和算術(shù)表達式
2.7 賦值運算符與賦值表達式
2.8 逗號運算符與逗號表達式
2.9 求字節(jié)數(shù)運算符
習(xí)題2
第3章 順序結(jié)構(gòu)程序設(shè)計
3.1 C語句概述
3.2 賦值語句
3.3 數(shù)據(jù)的輸入與輸出
3.3.1 printf函數(shù)
3.3.2 putchar函數(shù)
3.3.3 scanf函數(shù)
3.3.4 getchar函數(shù)
3.4 順序結(jié)構(gòu)程序舉例
習(xí)題3
第4章 選擇結(jié)構(gòu)程序設(shè)計
4.1 關(guān)系運算和邏輯運算
4.1.1 邏輯值及其在c語言中的表示
4.1.2 關(guān)系運算符與關(guān)系表達式
4.1.3 邏輯運算符與邏輯表達式
4.2 if語句
4.2.1 if語句的三種常用形式
4.2.2 if語句的嵌套
4.3 條件運算符和條件表達式
4.4 switch語句
4.4.1 switch語句的一般形式與執(zhí)行過程
4.4.2 switch語句體中的break語句
4.5 選擇結(jié)構(gòu)程序舉例
習(xí)題4
第5章 循環(huán)結(jié)構(gòu)程序設(shè)計
5.1 語句標號、goto語句及用goto語句構(gòu)成的循環(huán)
5.2 while語句和用while語句構(gòu)成的循環(huán)
5.3 do—while語句和用do—while語句構(gòu)成的循環(huán)
5.4 for語句和用for語句構(gòu)成的循環(huán)
5.5 循環(huán)結(jié)構(gòu)的嵌套
5.6 break語句和continue語句在循環(huán)體中的作用
5.6.1 break語句
5.6.2 continue語句
5.7 循環(huán)結(jié)構(gòu)程序舉例
習(xí)題5
第6章 數(shù)組
6.1 一維數(shù)組
6.1.1 一維數(shù)組的定義
6.1.2 一維數(shù)組元素的引用
6.1.3 一維數(shù)組的初始化
6.1.4 一維數(shù)組的定義和數(shù)組元素引用舉例
6.2 二維數(shù)組
6.2.1 二維數(shù)組的定義
6.2.2 二維數(shù)組元素的引用
6.2.3 二維數(shù)組的初始化
6.2.4 二維數(shù)組的定義和數(shù)組元素引用舉例
6.3 字符數(shù)組
6.3.1 字符數(shù)組的定義與引用
6.3.2 字符數(shù)組的初始化
6.3.3 用字符數(shù)組來存放字符串
6.3.4 字符數(shù)組的輸入與輸出
6.3.5 用于字符串處理的函數(shù)
6.3.6 字符數(shù)組應(yīng)用舉例
習(xí)題6
第7章 函數(shù)
7.1 庫函數(shù)
7.2 函數(shù)的定義和返回值
7.2.1 函數(shù)的定義
7.2.2 函數(shù)的返回值
7.3 函數(shù)的調(diào)用
7.3.1 函數(shù)調(diào)用的一般形式
7.3.2 函數(shù)調(diào)用的方式
7.4 函數(shù)的聲明
7.4.1 函數(shù)聲明的形式
7.4.2 函數(shù)聲明的位置
7.5 調(diào)用函數(shù)和被調(diào)用函數(shù)之間的數(shù)據(jù)傳遞
7.5.1 變量作為參數(shù)
7.5.2 數(shù)組名作為參數(shù)
7.6 函數(shù)的嵌套調(diào)用與遞歸調(diào)用
7.6.1 函數(shù)的嵌套調(diào)用
7.6.2 函數(shù)的遞歸調(diào)用
7.7 程序舉例
習(xí)題7
第8章 用戶標識符的作用域和存儲類
8.1 局部變量、全局變量和存儲分類
8.1.1 用戶標識符的作用域及變量的生存期
8.1 一局部變量、全局變量和存儲分類
8.2 局部變量及其作用域和生存期
8.2.1 auto變量
8.2.2 register變量
8.2.3 靜態(tài)存儲類的局部變量
8.3 全局變量及其作用域和生存期
8.3.1 全局變量的作用域和生存期
8.3.2 全局變量的作用域擴展
8.3.3 靜態(tài)全局變量
8.4 外部函數(shù)與內(nèi)部函數(shù)
8.4.1 外部函數(shù)
8.4.2 內(nèi)部函數(shù)
習(xí)題8
第9章 編譯預(yù)處理
9.1 宏定義
9.1.1 不帶參數(shù)的宏定義
9.1.2 帶參數(shù)的宏定義
9.1.3 終止宏定義
9.2 文件包含
9.3 條件編譯
習(xí)題9
第10章 指針
10.1 指針的基本概念
1O.2 指針變量的定義與引用
10.2.1 指針變量的定義
10.2.2 指針變量的引用
10.2.3 指針變量的賦值運算
10.2.4 二重指針變量
10.2.5 空指針和void類型指針
10.3 函數(shù)之間地址值的傳遞
10.3.1 指針變量作為函數(shù)參數(shù)
10.3.2 返回地址值的函數(shù)
10.4 一維數(shù)組和指針
10.4.1 通過指針引用數(shù)組元素
10.4.2 數(shù)組名或指針變量作形參
lO.4.3 使用指針變量處理一維數(shù)組的應(yīng)用舉例
10.4.4 用指向字符的指針變量處理字符串
10.4.5 使用指針變量處理字符串應(yīng)用舉例
10.5 多維數(shù)組和指針
10.5.1 二維數(shù)組和數(shù)組元素的地址
10.5.2 通過指向數(shù)組元素的指針引用二維數(shù)組
10.5.3 通過行指針引用二維數(shù)組
10.5.4 指針數(shù)組
10.6 函數(shù)和指針
10.6.1 用函數(shù)指針變量調(diào)用函數(shù)
10.6.2 用指向函數(shù)的指針作函數(shù)參數(shù)
10.7 小結(jié)
10.7.1 指針基本概念與性質(zhì)小結(jié)
10.7.2 有關(guān)指針的數(shù)據(jù)類型的小結(jié)
10.7.3 指針運算的小結(jié)
習(xí)題10
第ll章 結(jié)構(gòu)體、共用體和用戶定義類型
11.1 結(jié)構(gòu)體類型及結(jié)構(gòu)體變量
11.1.1 結(jié)構(gòu)體類型的定義
11.1.2 結(jié)構(gòu)體類型變量的定義
11.1.3 結(jié)構(gòu)體變量的內(nèi)存空間大小
11.1.4 結(jié)構(gòu)體變量的引用
11.1.5 結(jié)構(gòu)體變量的初始化
11.2 結(jié)構(gòu)體數(shù)組
11.3 指向結(jié)構(gòu)體的指針
11.3.1 指向結(jié)構(gòu)體變量的指針
11.3.2 指向結(jié)構(gòu)體數(shù)組的指針
11.4 結(jié)構(gòu)體與函數(shù)
11.5 鏈表
11.5.1 鏈表概述
11.5.2 鏈表的基本操作
11.6 共用體
11.6.1 共用體類型的定義
11.6.2 共用體類型變量的定義
11.6.3 共用體變量的引用
11.7 枚舉類型
11.8 用typedef定義一種新類型名
習(xí)題11
第12章 位運算
12.1 位運算符與位運算
12.2 位運算舉例
12.3 位段
習(xí)題12
第13章 文件
13.1 C語言文件的基本概念
13.2 文件指針
13.3 文件的打開與關(guān)閉
13.3.1 文件的打開(foperl函數(shù))
13.3.2 文件的關(guān)閉(fclose函數(shù))
13.4 文件的讀寫
13.4.1 字符的輸入與輸出(fputc函數(shù)、fgetc函數(shù)、putc函數(shù)、getc函數(shù))
13.4.2 檢查文件是否結(jié)束(feof函數(shù))
13.4.3 字符串的輸入與輸出(fgets函數(shù)和fputs函數(shù))
13.4.4 二進制數(shù)據(jù)塊的輸入與輸出(fread函數(shù)和fwrite函數(shù))
13.4.5 格式化的文件輸入與輸出(fscanf函數(shù)和fprintf函數(shù))
13.5 文件的定位
13.5.1 改變文件讀寫位置(fseek函數(shù))
13.5.2 ftell函數(shù)
13.5.3 反繞(rewind函數(shù))
13.6 文件的出錯檢測
13.6.1 出錯檢測(ferror函數(shù))
13.6.2 清除錯誤標志(clearerr函數(shù))
習(xí)題13
附錄A C語言的關(guān)鍵字
附錄B ASCII代碼表
附錄C 運算符及其優(yōu)先級和結(jié)合性
附錄D C語言的常用庫函數(shù)
1.1 程序和程序設(shè)計語言
計算機是在程序的控制下進行工作的。要想讓一臺通用的計算機能夠正常運行,需要預(yù)先安裝好一系列的系統(tǒng)程序,如Windows 系統(tǒng)等,它們是由計算機的專業(yè)人員編制出來的程序。一般的用戶如果要想利用計算機來解決某個具體的實際問題,就需要用戶自己動手編寫相應(yīng)的應(yīng)用程序。程序設(shè)計是計算機應(yīng)用人員的一項基本功,也是當代大學(xué)生必須經(jīng)歷的一項基本的思維方式訓(xùn)練。只有學(xué)會了程序設(shè)計,才能更深入地使用計算機。
1.1.1 程序與程序設(shè)計
所謂程序,就是用計算機能夠識別的語言所描述的解決某個特定問題的方法和步驟,是由一組相關(guān)的指令組成的。通常一個程序主要描述兩個方面的內(nèi)容:一是描述問題的每個對象及它們之間的關(guān)系,即數(shù)據(jù)結(jié)構(gòu)的內(nèi)容;二是描述對這些對象進行處理的動作、動作的先后順序,即求解的算法。因此,程序也可以用經(jīng)典的公式來表示:程序= 數(shù)據(jù)結(jié)構(gòu)+ 算法所謂程序設(shè)計,就是利用計算機解決問題的全過程。通常是對問題進行分析并建立數(shù)學(xué)模型;在此基礎(chǔ)上設(shè)計出相應(yīng)的數(shù)據(jù)結(jié)構(gòu)和算法;然后用某種程序設(shè)計語言編寫相應(yīng)的程序代碼;最后調(diào)試程序,使之運行后能產(chǎn)生預(yù)期的結(jié)果。
1.1.2 程序設(shè)計語言
程序設(shè)計語言是人們根據(jù)計算機的特點及描述問題的需要設(shè)計出來的、介于人與計算機之間的一種中間語言。隨著計算機技術(shù)的發(fā)展,涌現(xiàn)出了幾百種不同風(fēng)格的程序設(shè)計語言,最常用的不過十多種。按照程序設(shè)計語言的發(fā)展過程,可以將它們分為以下四類。
1.機器語言
機器語言是由二進制代碼按一定的規(guī)則組成的、能被機器直接理解和執(zhí)行的指令的集合。機器語言中的每一條語句實際上是一條二進制形式的指令代碼(即機器指令) ,機器指令一般由操作碼和操作數(shù)兩個部分組成,操作碼表示該指令所要完成的功能,操作數(shù)指出完成這個功能所需要的數(shù)據(jù)或數(shù)據(jù)在內(nèi)存中的地址。
例如,某種計算機上計算A = 15 + 10 的機器語言程序如下:10110000 00001111
把15(其二進制值為00001111)放入累加器A中00101100 00001010 把10與累加器A中的值相加,結(jié)果仍放入A中11110100 結(jié)束,停機用機器語言編寫的程序,計算機可以直接識別和執(zhí)行,因而執(zhí)行效率高。但由于機器語言指令跟具體的計算機內(nèi)部結(jié)構(gòu)有關(guān),不同類型的計算機,其指令系統(tǒng)不同,因此機器語言程序通用性差。另外,機器語言的指令不直觀,難認、難記、難理解、難修改、易出錯。
因此,很少有人用機器語言直接編程。
2.匯編語言
為了便于理解和記憶,人們采用能夠幫助記憶的指令助記符來代替機器語言指令代碼中的操作碼,用地址標識符或十進制數(shù)來代替操作數(shù)。指令助記符一般采用描述該指令功能的英文單詞的縮寫,如用ADD 表示加法操作、SUB 表示減法操作、JMP 表示程序跳轉(zhuǎn)等。這種采用指令助記符的語言就是匯編語言,又稱為符號語言。
例如,上述計算A = 15 + 10 的匯編語言程序如下:MOV A,15 把15放入累加器A中ADD A,10 把10與累加器A中的值相加,結(jié)果仍放入A中HLT 結(jié)束,停機計算機不能直接執(zhí)行用匯編語言編寫的程序,必須由一種專門的翻譯程序(即匯編程序)將匯編語言源程序翻譯成機器語言程序,計算機才能執(zhí)行。
3.高級語言
機器語言和匯編語言都是面向機器的語言,一般稱其為低級語言。它們對計算機硬件結(jié)構(gòu)的依賴性很大,這就要求程序的開發(fā)者必須熟悉和了解計算機硬件的內(nèi)部結(jié)構(gòu),因此,它們面對的用戶一般是計算機專業(yè)人員,用它們開發(fā)出來的程序通用性也比較差。
隨著計算機技術(shù)的發(fā)展及計算機應(yīng)用領(lǐng)域的不斷擴大,計算機用戶的隊伍也在不斷壯大,而且這個隊伍中絕大部分人不是計算機專業(yè)人員。為此,從20 世紀50 年代中期開始,逐步發(fā)展并出現(xiàn)了多種面向過程的程序設(shè)計語言,稱為高級語言。高級語言與具體的計算機硬件無關(guān),其表達方式接近于被描述的問題,接近于自然語言和數(shù)學(xué)語言,易為人們接受和掌握。使用高級語言,只要關(guān)心描述問題的求解過程,不必關(guān)心計算機的內(nèi)部結(jié)構(gòu)。因此,用高級語言編寫程序要比用低級語言容易得多,大大簡化了程序的編制和調(diào)試過程,使編程效率得到大幅度的提高。
例如,上述計算A = 15 + 10 的BASIC 語言程序如下:A=15+10 '15與10相加的結(jié)果放入A中PRINT A '輸出AEND '程序結(jié)束用高級語言編寫的程序易學(xué)、易讀、易修改,通用性好。但是,計算機同樣不能直接執(zhí)行高級語言程序,必須經(jīng)過語言處理程序的翻譯后才能被計算機接受。
下面列出幾種最常用的高級語言及其最適用的領(lǐng)域:BASIC 教學(xué)和微小型應(yīng)用程序的開發(fā)FORTRAN 科學(xué)及工程計算程序的開發(fā)PASCAL 專業(yè)教學(xué)和應(yīng)用程序的開發(fā)C 中、小型系統(tǒng)程序的開發(fā)FoxPro 數(shù)據(jù)庫應(yīng)用程序的開發(fā)COBOL 商業(yè)、交通和銀行等行業(yè)應(yīng)用程序的開發(fā)LISP 人工智能程序的開發(fā)Prol og 人工智能程序的開發(fā)4.面向?qū)ο蟮母呒壵Z言面向?qū)ο蟮某绦蛟O(shè)計語言是在早期的高級語言(面向過程)的基礎(chǔ)上發(fā)展而來的。面向?qū)ο蟮某绦虮让嫦蜻^程的程序更清晰、易懂,更適宜于編寫大規(guī)模的應(yīng)用程序,正在成為當代主流的程序設(shè)計工具。常用的面向?qū)ο蟮母呒壵Z言主要有:Visual Basic ,VisualFoxPro ,Visual C + + ,Java 和C # 等。
面向?qū)ο蟮某绦蛟O(shè)計方法是一種結(jié)構(gòu)模擬方法,它把現(xiàn)實世界模擬成由許多對象組成的實體,對象與對象之間通過互相發(fā)送和接收消息進行聯(lián)系;消息激發(fā)對象本身的運動,形成對象狀態(tài)的變化。從程序設(shè)計的角度來看,每個對象都是一個由若干數(shù)據(jù)和方法組成的封裝體―― 抽象數(shù)據(jù)類型。
目前,國內(nèi)外大多數(shù)計算機上運行的程序,大多采用高級語言編寫。因此,應(yīng)當熟練掌握用高級語言編寫程序的方法和技巧。由于面向過程的語言是程序設(shè)計的基礎(chǔ),所以本書以面向過程的C 語言為背景,介紹程序設(shè)計的基本概念和基本方法。
1.1.3 語言處理程序
計算機只能直接識別和執(zhí)行機器語言程序。用匯編語言和高級語言編寫的程序,都必須經(jīng)過一個翻譯過程才能轉(zhuǎn)換為計算機所能識別的機器語言程序,實現(xiàn)這個翻譯過程的工具是語言處理程序,即翻譯程序。翻譯程序除了要完成語言間的轉(zhuǎn)換外,還要進行語法、語義等方面的檢查。針對不同的程序設(shè)計語言編寫出的源程序,有各自對應(yīng)的翻譯程序,不能互相通用。翻譯程序可分為匯編程序和高級語言翻譯程序;高級語言翻譯程序有兩種工作方式,即解釋方式和編譯方式,對應(yīng)的是解釋程序和編譯程序。
1.匯編程序
匯編程序是一種由專業(yè)的軟件開發(fā)商提供的系統(tǒng)軟件,它能將用匯編語言編寫的源程序翻譯成某種類型的計算機的機器語言程序,即目標程序,這一翻譯過程稱為匯編。圖1.1 是匯編語言源程序的匯編、連接與運行過程示意圖。
匯編程序通常是將一條匯編語言指令翻譯成一條機器語言指令。在翻譯的過程中,還要對每一條指令進行語法檢查,若有錯誤,就中斷匯編過程,并以某種方式輸出錯誤的類型及有關(guān)信息,以便用戶進行修改。若沒有錯誤,就自動生成相應(yīng)的目標程序,再經(jīng)過連接處理之后,便可以運行了。運行的是匯編并連接后產(chǎn)生的可執(zhí)行程序,若源程序作了某些修改,則必須再重新進行匯編與連接處理。
2.解釋程序
解釋程序的工作過程是將高級語言源程序一句一句地讀入,每讀入一個語句都要對它進行分析和解釋,若有錯誤就即時中斷其解釋過程,并通知用戶進行修改,若沒有錯誤就按照解釋結(jié)果執(zhí)行所要求的操作,其工作過程如圖1.2 所示。
BASIC 、LISP 等語言采用解釋方式。解釋方式靈活、方便,交互性好,解釋執(zhí)行程序的過程中也不會產(chǎn)生目標程序。但因為是邊解釋邊執(zhí)行,所以程序的執(zhí)行速度很慢,如果源程序中出現(xiàn)循環(huán)結(jié)構(gòu),解釋程序也要重復(fù)多次地解釋循環(huán)體中的每一條語句,造成很大浪費;而且解釋方式在程序運行期間始終離不開翻譯程序。
3.編譯程序
編譯程序的功能是將用高級語言編寫的源程序翻譯成機器語言程序,即目標程序,這一翻譯過程稱為編譯。但目標程序還不能立即裝入機器執(zhí)行,因為還沒有連接成一個整體,在目標程序中還可能要調(diào)用一些其他語言編寫的程序和標準程序庫中的標準子程序。
連接程序的作用是將目標程序與有關(guān)的程序庫組合成一個完整的可執(zhí)行程序,產(chǎn)生的可執(zhí)行程序可以脫離編譯程序和源程序獨立存在并可反復(fù)使用。由于經(jīng)過編譯并連接后所產(chǎn)生的可執(zhí)行程序具有運行速度快、保密性好等優(yōu)點,大多數(shù)高級語言都采用編譯方式,如C/C + + ,PASCAL ,F(xiàn)ORTRAN ,COBOL 等。但每次修改源程序后,都必須重新進行編譯與連接處理,其工作過程如圖1.3 所示。
與匯編程序不同的是,編譯程序往往需要將一條高級語言的語句轉(zhuǎn)換成若干條機器語言指令,而且翻譯的過程也要復(fù)雜得多。
1.1.4 設(shè)計程序的基本原則要設(shè)計出一個好的程序,必須了解利用計算機解決實際問題的過程,掌握程序設(shè)計的基本技術(shù),并熟練地掌握一種程序設(shè)計語言。計算機解決問題的基本過程如圖1.4 所示。
如何才能編寫出高質(zhì)量的程序呢? 下面是設(shè)計程序時應(yīng)遵循的基本原則:
(1) 正確性。正確性是指程序本身必須具備且只能具備程序設(shè)計規(guī)格說明書中所列舉的全部功能。它是判斷程序質(zhì)量的首要標準。
(2) 可靠性。可靠性是指程序在多次反復(fù)使用過程中不失敗的概率。
(3) 簡明性。簡明性的目標是要求程序簡明易讀。
(4) 有效性。程序在計算機上運行需要使用一定數(shù)量的計算機資源,如CPU 的時間、存儲器的存儲空間。有效性就是要在一定的軟、硬件條件下,反映出程序的綜合效率。
(5) 可維護性。程序的維護可分為校正性維護、適應(yīng)性維護和完善性維護。一個軟件的可維護性直接關(guān)系到程序的可用性,因此應(yīng)特別予以關(guān)注。
(6) 可移植性。程序主要與其所完成的任務(wù)有關(guān),但也與它的運行環(huán)境有著一定的聯(lián)系。軟件的開發(fā)應(yīng)盡可能遠離機器的特征,以提高它的可移植程度。
1.2 算 法為了有效地進行程序設(shè)計,不僅要掌握一門程序設(shè)計語言,還應(yīng)該學(xué)會對各類問題擬定出有效的解題步驟,即算法設(shè)計。有了正確的算法,才能夠編制程序。算法的好壞決定了程序的優(yōu)劣,因此程序設(shè)計的核心任務(wù)之一就是設(shè)計算法。
1.2.1 算法及算法的特性
1.算法所謂算法,就是問題的求解方法。例如,期末考試前的復(fù)習(xí)計劃,就是“復(fù)習(xí)算法” ;到醫(yī)院看病,先掛號,后診斷并開出藥方,最后再取藥等,是“看病算法” 。在計算機中,把解題過程準確的、完整的描述稱為解題算法。
一個算法由一些操作組成,而這些操作又是按一定的控制結(jié)構(gòu)所規(guī)定的次序執(zhí)行的,也就是算法由操作與控制結(jié)構(gòu)兩個要素組成。
2.算法的特性一個算法應(yīng)該具有如下特點:
(1) 有窮性。一個算法應(yīng)該包含有限的操作步驟,而不能是無限的;并且能在有限的時間內(nèi)完成。
(2) 確定性。每一個步驟都是確定的,而不能是含糊的、模棱兩可的。
(3) 有效性。每一個步驟都能得到有效地執(zhí)行,并得到確定的結(jié)果。
(4) 有零個或多個輸入。所謂輸入是指執(zhí)行算法時需要從外界取得必要的信息。
(5) 有一個或多個輸出。算法的目的就是為了求解,“解”就是輸出。
上述所講的算法特性約束人們?nèi)フ_地設(shè)計算法,使之能夠正確無誤地執(zhí)行,達到求解問題的預(yù)期效果。同時,算法還應(yīng)該具有直觀、清晰、易懂的表示形式,以利于交流、維護與修改。
1.2.2 算法的表示表示算法的方法有許多種,如自然語言、偽代碼、傳統(tǒng)流程圖、結(jié)構(gòu)化流程圖等。
1.自然語言自然語言表示法是表示算法的最原始方法。自然語言就是人們?nèi)粘J褂玫恼Z言,可以是漢語、英語或其他自然語言。
例1.1 給出求x1 + x2 + x3 + x4 + x5 的值的算法。
算法分析如下:
(1) 適合手工計算的算法。解題步驟為:
① 將x1 與x2 相加,得到兩個數(shù)之和;
② 將第① 步的和與x3 相加,得到三個數(shù)之和;
③ 將第② 步的和與x4 相加,得到四個數(shù)之和;
④ 將第③ 步的和與x5 相加,得到五個數(shù)之和。
這種算法雖然是正確的,但太煩瑣。如果要求x1 + x2 + … + x100 ,則要寫99 個步
驟,顯然是不可取的。
(2)適合計算機處理的算法。該算法能更加簡潔地表達上述解題過程,并具有通用
性。先定義幾個變量:設(shè)置變量s 表示多項式之和,其初值為零;設(shè)置變量a 表示多項式
中的一項,它的值可以為x1 ,x2 ,… ,x5 ;用i 記錄被加了幾次,其初值為1 。解題步驟為:
① s 0 ;
② i 1 ;
③ a xi ; (使a 等于多項式中的第i 項)
④ s s + a ;(求和,并將結(jié)果保留在s 中)
⑤ i i + 1 ;(計數(shù)增值)
⑥ 若i ≤ 5 ,則重復(fù)③ 、④ 、⑤ 步,否則計算結(jié)束;
⑦ 輸出s 。
這個算法就比較靈活,如果想求出100 個數(shù)據(jù)的累加和,只需將上述算法的第⑥ 步中
的“i ≤ 5”改為“i ≤ 100”即可。
例1.2 求兩個正整數(shù)m 和n 的最大公約數(shù)的歐幾里得算法。
歐幾里得算法可描述為:
① 從鍵盤輸入兩個正整數(shù)m 和n 的值;
② 求出m 除以n 的余數(shù)r ;
③ 若r = 0 ,則轉(zhuǎn)至第⑥ 步,否則,執(zhí)行第④ 步;
④ 用n 取代m ,用r 取代n ;
⑤ 轉(zhuǎn)到第② 步,繼續(xù)求新的m 和n 的最大公約數(shù);
⑥ 輸出n 的值,n 的值即為當初那兩個數(shù)的最大公約數(shù)。
用自然語言表示的算法通俗易懂,但文字冗長,容易出現(xiàn)“歧義性” ,在表示包含分支
結(jié)構(gòu)和循環(huán)結(jié)構(gòu)的算法時,不太方便和直觀。因此,除了很簡單的問題以外,一般不用自
然語言來表示算法。
2.偽代碼
偽代碼是一種介于自然語言和計算機語言之間的、用文字和符號表示的算法。算法中的每一行(或幾行)表示一個基本操作,它可以是一行文字,也可以是一個數(shù)學(xué)公式,還可以是一個某種計算機語言的語句等。它不用圖形符號,因此書寫方便,格式緊湊,也比較好懂,便于向計算機語言描述的算法(即程序)過渡。但讀者必須先了解一種計算機語言之后,才能讀懂這些算法,現(xiàn)代的程序設(shè)計一般不采用偽代碼表示方法。