《高級程序設計技術(shù)》課件第1章_第1頁
《高級程序設計技術(shù)》課件第1章_第2頁
《高級程序設計技術(shù)》課件第1章_第3頁
《高級程序設計技術(shù)》課件第1章_第4頁
《高級程序設計技術(shù)》課件第1章_第5頁
已閱讀5頁,還剩128頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第1章程序設計基礎(chǔ)

1.1.程序設計語言與語言處理程序1.2程序設計的步驟1.3程序執(zhí)行過程與編程工具1.4程序的調(diào)試方法1.5參數(shù)傳遞相關(guān)技術(shù)1.6完整的C程序結(jié)構(gòu)1.7良好的程序風格習題1

實驗11.1程序設計語言與語言處理程序1.1.1程序設計語言為了有效地實現(xiàn)人與計算機之間的通信,人們設計出多種詞匯少、語法簡單、意義明確的適合于計算機使用的語言,這樣的語言被稱為計算機語言。計算機語言從狹義的角度看是計算機可以執(zhí)行的機器語言,從廣義角度看是一切用于人與計算機通信的語言,包括程序設計語言,各種專用的或通用的命令語言、查詢語言、定義語言等。程序設計語言(programminglanguage)泛指一切用于書寫計算機程序的語言,包括匯編語言、機器語言,以及稱為高級語言的完全符號形式的、獨立于具體計算機的語言。程序設計語言是計算機語言的一個子集。程序設計語言可分為低級語言與高級語言兩大類。低級語言是與機器有關(guān)的語言,包括機器語言和匯編語言。高級語言是與機器無關(guān)的語言。

1.機器語言機器語言是以“0”、“1”二進制代碼形式表示的機器基本指令的集合,是計算機硬件唯一可以直接識別的語言。機器語言是最早出現(xiàn)的計算機語言,屬于第一代程序設計語言。使用機器語言編寫程序十分不便,因為這種語言直觀性較差,難閱讀、難修改。而且,由于每臺計算機的指令系統(tǒng)往往各不相同,因此在一臺計算機上執(zhí)行的程序要想在另一臺計算機上執(zhí)行,必須重新編寫程序,造成了重復工作。但是,由于使用的是針對特定型號計算機的語言,故機器語言的運算效率是所有語言中最高的。

2.匯編語言匯編語言是為了解決機器語言難于理解和記憶的缺點,用易于理解、記憶的名稱和符號表示的機器指令。例如,用“ADD”代表加法,“MOV”代表數(shù)據(jù)傳遞等。匯編語言比機器語言直觀,使程序的編寫、糾錯和維護變得相對簡單了,但其基本上還是一條指令對應一種基本操作,對機器硬件十分依賴,移植性不好。由于匯編語言還是針對特定硬件的一種程序設計語言,因此效率仍十分高,能準確發(fā)揮計算機硬件的功能和特長,程序精練而質(zhì)量高,所以至今仍是一種常用的軟件開發(fā)工具。不論是機器語言還是匯編語言,都是面向硬件具體操作的,語言對機器的過分依賴要求使用者必須對硬件結(jié)構(gòu)及其工作原理都十分熟悉,這對非計算機專業(yè)人員是難以做到的,對于計算機的推廣應用是不利的。

3.高級語言高級語言是人們?yōu)榱私鉀Q低級語言的不足而設計的程序設計語言。它是由一些接近于自然語言和數(shù)學語言的語句組成的,因此更接近于要解決問題的表示方法,并在一定程度上與機器無關(guān)。用高級語言編寫程序,易學、易用、易維護。但是由于機器硬件不能直接識別高級語言中的語句,因此高級語言必須通過編譯系統(tǒng)編譯或解釋成低級語言后才能被計算機執(zhí)行。高級語言不依賴于計算機系統(tǒng),不同的編譯程序可以把相同的高級語言程序編譯成不同計算機下有意義的低級語言,這些低級語言是不同的,但它們的意義是一樣的,執(zhí)行的效果也是一樣的。高級語言分為面向過程的語言和面向?qū)ο蟮恼Z言,現(xiàn)在面向?qū)ο蟮恼Z言已逐步成為程序設計的主流。用高級語言編程的效率高,但執(zhí)行速度沒有低級語言快。高級語言的設計是很復雜的。因為它必須滿足兩種不同的需要:一方面它要滿足程序設計人員的需要,可以方便、自然地描述現(xiàn)實世界中的問題;另一方面還要能夠構(gòu)造出高效率的翻譯程序,能夠把語言中的所有內(nèi)容翻譯成高效的機器指令。從20世紀50年代中期第一個實用的高級語言誕生以來,人們曾設計出幾百種高級語言,但今天實際使用的通用高級語言也不過數(shù)十種。下面介紹幾種目前最常用的高級語言。

(1)?FORTRAN語言。它是使用最早的高級語言。FORTRAN語言從20世紀50年代中期到現(xiàn)在,經(jīng)過幾十年的實踐檢驗,廣泛用于科學計算程序的編制,人們稱之為用于科學計算的“公式翻譯語言”。

(2)?COBOL語言。它是主要面向商業(yè)的通用語言,創(chuàng)始于20世紀50年代末期,使用了十分接近于英語的語句,很容易理解,在事務處理中有著廣泛的應用。

(3)?BASIC語言:它是20世紀60年代初為適應分時系統(tǒng)而研制的一種交互式語言,全稱是Beginner’sAllPurposeSymbolicInstructionCode,意為“初學者通用符號指令代碼”,是最容易掌握的語言之一。BASIC簡化了FORTRAN操作,為無經(jīng)驗的人提供一種簡單的編程語言,目前使用仍很廣泛。VisualBASIC或QBASIC都屬于BASIC語言的發(fā)展,不過VisualBASIC.net和傳統(tǒng)的BASIC已經(jīng)有了很大的區(qū)別。

(4)?LOGO語言。1967年美國麻省理工大學為兒童設計了一種LOGO編程語言,用于啟發(fā)孩子們的學習與思考,于是LOGO成為一種熱門的計算機教學語言。

(5)?Simula67語言。1967年挪威科學家推出了Simula67語言。該語言第一次提出類的概念,能夠把應用中的概念直接用編程語言描述。該語言由于一些原因沒能流行,但它是面向?qū)ο缶幊陶Z言的概念基礎(chǔ)。

(6)?C語言。C語言于1970年由美國貝爾實驗室研制成功。由于它表達簡潔,控制結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)完備,具有豐富的運算符和數(shù)據(jù)類型,移植性強,編譯質(zhì)量高,因此得到了廣泛的使用。

(7)?Pascal語言。它于1971年研制成功,是第一個系統(tǒng)地體現(xiàn)了結(jié)構(gòu)化程序設計概念的高級語言。與BASIC、C等語言相比,Pascal語言更適合科學計算,其運行速度最快,編譯能力也最強。其發(fā)展從Pascal5.5、6.0、7.0一直到現(xiàn)在的Delphi、.NET。

(8)?PROLOG語言。它是1972年誕生于法國,后來在英國得到完善和發(fā)展的一種邏輯程序設計語言,廣泛應用于人工智能領(lǐng)域。

(9)?ADA語言。它是美國國防部直接領(lǐng)導下的、1975年開始開發(fā)的一種現(xiàn)代模塊化語言,便于實現(xiàn)嵌入式應用,已被許多國家選定為軍用標準語言。

(10)?C++語言。20世紀70年代中期,BjarneStroustrup在劍橋大學計算機中心工作。他以C為背景,以Simula思想為基礎(chǔ),在1979年開始從事將C改良為帶類的C的工作。1983年該語言被正式命名為C++。C++?支持C語言語法,但C++?并不只是一個C語言的擴展版本。實際上,在C++?和C語言之間存在著一個很大的區(qū)別,就是面向?qū)ο蠛徒Y(jié)構(gòu)化思想之間的區(qū)別。C++?是面向?qū)ο蟮某绦蛟O計語言,而C語言則是一種標準的結(jié)構(gòu)化語言。C++?在標準化之后迅速成為了程序開發(fā)的主流語言。

(11)?Java語言。Java是純面向?qū)ο箝_發(fā)語言,也是目前非常流行的面向?qū)ο蟮某绦蛟O計語言之一。Java的最大優(yōu)點是它的跨平臺特性,即借助于運行在不同平臺上的Java虛擬機,用Java編寫的程序可以在多種不同的操作系統(tǒng)甚至硬件平臺上運行,實現(xiàn)“一次編寫,處處運行”。Java的語法和C++?具有很多相似的地方,因此,如果在學習Java之前就已經(jīng)對C++?比較了解了,可能會感覺比較容易一些。不過C++?有一些特性卻是Java沒有的。

(12)?C#?語言。C#?是Microsoft公司設計的下一代面向?qū)ο蟮恼Z言產(chǎn)品。微軟給它的定義是:“C#?是從C和C++?派生出來的一種簡單、現(xiàn)代、面向?qū)ο蠛皖愋桶踩木幊陶Z言。C#試圖結(jié)合VisualBASIC的快速開發(fā)能力和C++?的強大靈活的能力。”C#?有很多方面和Java類似。隨著可視化技術(shù)的發(fā)展,出現(xiàn)了VisualBASIC、VisualC++、Delphi、.NET等可視化的開發(fā)環(huán)境,更加方便了程序員寫出更有效率的軟件。1.1.2語言處理程序用高級程序設計語言編寫程序,通常要經(jīng)過編輯、語言處理、裝配連接后,才能夠在計算機上運行。編輯是指計算機通過編輯程序?qū)⑷藗兙帉懙脑闯绦蛩腿胗嬎銠C。編輯程序可以使用戶方便地修改源程序,包括添加、刪除、修改等,直到用戶滿意為止。語言處理程序是把用一種程序設計語言表示的程序轉(zhuǎn)換為與之等價的另一種程序設計語言表示的程序的處理程序。在計算機軟件中經(jīng)常用到的語言處理程序是把匯編語言或高級語言“翻譯”成機器語言的翻譯程序。被翻譯的程序稱為源程序或源代碼,經(jīng)過翻譯程序“翻譯”出來的結(jié)果程序稱為目標程序。翻譯程序有兩種典型的實現(xiàn)途徑,分別稱為解釋方式與編譯方式。

(1)解釋方式。解釋方式是按照源程序中語句的執(zhí)行順序,逐句翻譯并立即予以執(zhí)行。即由事先放入計算機中的解釋程序把匯編語言或高級語言源程序語句逐條翻譯成機器語言,翻譯一句執(zhí)行一句,直到程序全部翻譯、執(zhí)行完為止,如圖1.1所示。解釋方式類似于人類不同語言的口譯工作。翻譯員(解釋程序)拿著外文版的說明書(源程序)在車間現(xiàn)場對操作員作現(xiàn)場指導。對說明書上的語句,翻譯員逐條譯給操作員聽;操作員根據(jù)聽到的話(他能懂的語言)進行操作。翻譯員每翻譯一句,操作員就執(zhí)行該句規(guī)定的操作。翻譯員翻譯完全部說明書,操作員也執(zhí)行完所需全部操作。由于未保留翻譯的結(jié)果,因此若需再次操作,仍要由翻譯員翻譯,操作員操作。圖1.1解釋過程示意圖

(2)編譯方式。編譯方式先由翻譯程序把源程序靜態(tài)地翻譯成目標程序,然后執(zhí)行并得到結(jié)果,如圖1.2所示。這種實現(xiàn)途徑可以劃分為兩個明顯的階段:前一階段稱為生成階段;后一階段稱為連接運行階段。采用這種途徑實現(xiàn)的翻譯程序,如果源語言是一種高級語言,目標語言是某一計算機的機器語言或匯編語言,則這種翻譯程序稱為編譯程序。如果源語言是計算機的匯編語言,目標語言是相應計算機的機器語言,則這種翻譯程序稱為匯編程序。圖1.2編譯過程示意圖編譯方式類似于不同語言的筆譯工作。例如,某國的一個作家發(fā)表了某個劇本(源程序),我們計劃在國內(nèi)上演。首先必須由懂得該國語言的翻譯(編譯程序)把該劇本筆譯成中文本(目的程序)。翻譯工作結(jié)束,得到了中文本后,才能交給演出單位(計算機)去演(執(zhí)行)這個中文本(目標程序)。在后面的演出(執(zhí)行)階段,并不需要原來的外文劇本(源程序),也不需要翻譯(編譯程序)。正像只懂漢語的人與只懂英語的人交談需要英語翻譯,與只懂日語的人交談就需要日語翻譯一樣,使用不同的高級語言也需要不同的翻譯程序。如果使用BASIC語言,需要在計算機系統(tǒng)中安裝BASIC語言的解釋程序或編譯程序;如果使用C語言,就需要在機器內(nèi)安裝C編譯程序。如果機器內(nèi)沒有安裝匯編語言或高級語言的翻譯程序,計算機是決不能夠理解用相應語言編寫的程序的。比較而言,在翻譯同樣一篇外文文章的情況下,逐句翻譯比整篇翻譯的效率低,但一種語言的翻譯程序類型不是由使用者,而是由系統(tǒng)軟件的生產(chǎn)者決定的。目標程序只是一個個獨立的程序段,還不能直接執(zhí)行,因為程序中用到的庫函數(shù)和一些其他資源還沒有掛上,所以需要進行連接。連接的作用就是將各個目標程序,包括庫函數(shù)等整合成一個可執(zhí)行文件。1.2程序設計的步驟程序設計的基本過程一般由分析問題、抽象數(shù)學模型、選擇合適算法、編寫程序、調(diào)試運行程序及整理結(jié)果幾個階段構(gòu)成,如圖1.3所示。圖1.3用計算機解決問題的基本過程分析問題:對要解決的問題進行分析,理解題意。抽象數(shù)學模型:找出問題的運算操作與變化規(guī)律,經(jīng)歸納,建立數(shù)學模型,確定問題的解決方案。選擇合適算法:根據(jù)特定的數(shù)學模型,選擇適合用計算機解決問題的算法,可將處理思路用流程圖表示出來。(算法描述的主要流程圖參見6.1.3節(jié)。)編寫程序:選擇一種程序設計語言,按算法思路編寫程序。調(diào)試運行程序:調(diào)試運行程序,得到執(zhí)行結(jié)果。整理結(jié)果:對程序的執(zhí)行結(jié)果進行分析。如果發(fā)現(xiàn)錯誤,找出錯誤原因,重新調(diào)試,并形成試驗報告。下面以一個古代的“百錢百雞”問題為例進一步說明。中國古代數(shù)學家張丘建在他的《算經(jīng)》中提出了著名的“百錢百雞問題”:雞翁一,值錢五;雞母一,值錢三;雞雛三,值錢一;百錢買百雞,翁、母、雛各幾何?

1.分析問題這是一個典型的數(shù)值型問題。對于簡單的問題,這一步驟通常在腦子里會一閃而過,明白題意后,進行下一步。

2.抽象數(shù)學模型對于簡單的問題,數(shù)學模型也就是我們平時說的數(shù)學方程。復雜的問題可能會涉及數(shù)據(jù)結(jié)構(gòu)等因素。假設要買x只公雞、y只母雞、z只小雞,根據(jù)題目的意思可以得到兩個方程:x?+?y?+?z?=?100?①

根據(jù)題目的意思,可以確定x和y的取值范圍:0≤x、y、z≤100。

3.確定算法本題可采用窮舉法進行求解。對于變量x、y、z的不同組合,看它們是否滿足上面的兩個方程。如果滿足了,就是問題的一個解;如果不滿足,就不是問題的解。采用三重嵌套的循環(huán)對變量x、y、z進行組合。

4.編寫程序

【程序1.1】#include<stdio.h>main(){intx,y,z,j=0; /*j為計數(shù)器,記錄解的數(shù)量*/for(x=0;x<=100;x++) /*窮舉變量x*/for(y=0;y<=100;y++) /*窮舉變量y*/for(z=0;z<=100;z++) /*窮舉變量z*/if(x+y+z==100&&5*x+3*y+z/3==100) /*判斷是否滿足兩個方程*/printf("%2d:cock=%2dhen=%2dchicken=%2d\n",++j,x,y,z);}

5.調(diào)試運行

1:cock=0hen=25chicken=75

2:cock=3hen=20chicken=77

3:cock=4hen=18chicken=78

4:cock=7hen=13chicken=80

5:cock=8hen=11chicken=81

6:cock=11?hen=6chicken=83

7:cock=12?hen=4chicken=84

6.整理結(jié)果第2、4、6組解中,小雞的數(shù)量不能被3整除。問題到底出在什么地方呢?我們進行進一步分析,將這些解代入方程②,可以看到:顯然,這三組解不滿足數(shù)學方程,但由于我們在C語言中進行整型除法時,77/3的結(jié)果就是25,80/3的結(jié)果就是26,83/3的結(jié)果就是27,也就是說,計算機在進行整型數(shù)據(jù)除法運算時,對于商的小數(shù)部分不再進行處理,而是直接截斷。所以就造成了在數(shù)學上本來不成立的方程,在計算機中成立了。產(chǎn)生這個問題的根本原因,就是我們在分析問題的過程中忽略了一個重要條件,變量z要能夠被3整除。為了解決這個問題,應在原來兩個方程的基礎(chǔ)上增加一個判斷條件:

z%3==0因此,得到程序1.2?!境绦?.2】

#include<stdio.h>

main()

{intx,y,z,j=0;

for(x=0;x<=100;x++)

for(y=0;y<=100;y++)

for(z=0;z<=100;z++)

if(z%3==0&&x+y+z==100&&5*x+3*y+z/3==100)

printf("%2d:cock=%2dhen=%2dchicken=%2d\n",++j,x,y,z);}

運行結(jié)果:

1:cock=0hen=25chicken=75

2:cock=4hen=18chicken=78

3:cock=8hen=11chicken=81

4:cock=12hen=4chicken=84

結(jié)果正確。思考:該問題可否有更快的解法?1.3程序執(zhí)行過程與編程工具1.3.1C源程序執(zhí)行過程一個C源程序從輸入到執(zhí)行需要經(jīng)過編輯、編譯、連接、執(zhí)行這些步驟。

1.編輯編輯源程序的作用是建立與修改源程序。編輯的對象是源程序,源程序是以ASCII碼的方式輸入與存儲的。Windows中的記事本以及1.3.2節(jié)介紹的編程工具均帶有編輯功能。

2.編譯所謂編譯,就是將編寫好的源程序翻譯為二進制的目標代碼,由相應的編譯程序來完成。不同的高級語言需要不同的編譯程序。編譯以后產(chǎn)生的二進制目標代碼一般擴展名為obj,它不能直接運行。

3.連接編譯產(chǎn)生的二進制目標代碼是對每一個模塊直接翻譯產(chǎn)生的,需要將各個模塊與系統(tǒng)模塊相連接,才可以產(chǎn)生后綴為?.exe的可執(zhí)行文件。

4.執(zhí)行運行可執(zhí)行文件就可以獲得我們所需要的結(jié)果。圖1.4表示了從輸入源程序到產(chǎn)生可執(zhí)行目標程序的全過程。圖1.4C源程序從編輯到運行的過程

1.3.2C語言編程工具介紹很多初學者將C、TurboC(簡稱TC)、VisualC++(簡稱VC)等的關(guān)系搞不清楚,認為TC和VC也是一種編程語言。正確理解是:C是一種編程語言,TC和VC都是C的集成開發(fā)環(huán)境。集成開發(fā)環(huán)境(IntegeratedDevelopmentEnvironment,IDE)是一種集成了代碼編輯器、編譯器、調(diào)試器以及執(zhí)行等與開發(fā)有關(guān)的實用工具的軟件。由于大部分常用工具都集成在一起了,因此使用IDE來進行開發(fā)效率會很高。下面主要介紹C語言的三種集成開發(fā)環(huán)境。

1.TurboC

TurboC(簡稱TC)是Borland公司開發(fā)的DOS下16位C語言集成開發(fā)工具,目前主要有2.0和3.0版本。2.0版本只支持C語言的編譯且不支持鼠標操作,還需設置路徑;而3.0版本可以支持C/C++?兩種語言編譯,而且還支持鼠標和“//”注釋方式,并且在安裝好后就可以使用,無需設置。由于TC最初是在DOS環(huán)境下使用的,一切都需要用鍵盤來操作,對目前絕大多數(shù)習慣用鼠標的Windows用戶來說,很不方便。但TC的編譯速度快,代碼執(zhí)行速度高,程序調(diào)試也比較方便,界面簡單,因此很多高校一般以TC為IDE開發(fā)環(huán)境講授C語言。

(1)啟動TC。雙擊TC文件夾下的TC.exe(?.exe由于設置不同可能不顯示),出現(xiàn)如圖1.5所示界面。按Esc鍵后,出現(xiàn)黃色光標閃爍,此時就可以編寫程序了。圖1.5TC界面屏幕最上方是程序下拉菜單,下面是程序的編輯區(qū)域。在編輯窗口上方,是所編輯程序文件的相關(guān)信息。如Line表示正在編輯的行號,Col表示正在編輯的列號,Insert表示正在插入狀態(tài)下編輯,“C:NONAME.C”表示正在編輯的程序文件名以及存放盤符。特別提示:在編輯的過程中有時候會不小心按下鍵盤的Insert鍵,這會把輸入時的插入狀態(tài)變?yōu)楦膶憼顟B(tài),Insert提示也消失。此時按下一個鍵后,光標所在位置的原來字符就會被改寫為當前按下的字符。若要回到插入狀態(tài),只需再次按下Insert鍵即可。編輯區(qū)域的下方是Message窗口,編譯程序時,可顯示編譯的相關(guān)信息。按F5鍵可關(guān)閉該窗口。窗口最下方是一些常用快捷鍵

(2)編寫程序與保存。編寫程序時為了使程序美觀、易懂,最好按層次縮進,而不是全部左對齊。在編寫程序之前、中間或結(jié)束后都可以對程序進行保存。保存程序時選擇“File”菜單下的“Save”命令,或按F2鍵,在彈出的窗口中輸入程序存放的路徑和程序名稱即可,如圖1.6所示。圖1.6保存程序

特別提示:很多初學者在編寫了十幾行甚至更多代碼時,程序的名稱還是默認名稱“NONAME.C”,如果此時電腦出現(xiàn)故障,死機或斷電,所編寫的代碼就會丟失。因此,建議在編寫幾行代碼后即保存程序,之后在編寫若干行后,直接按F2鍵進行快捷保存。另外程序編譯和執(zhí)行前也最好先保存,以免程序運行崩潰而造成代碼丟失。

(3)編譯與連接?!癈ompile”菜單下的“CompiletoOBJ”、“MakeEXEfile”,“LinkEXEfile”分別是“編譯為目標代碼”、“生成可執(zhí)行文件”、“連接為可執(zhí)行文件”。以上步驟可按F9鍵一步完成。此時,程序如果有錯誤,就會在Message窗口中顯示相關(guān)錯誤信息。

(4)運行與查看程序結(jié)果。選擇“Run”菜單下的“Run”,或按Ctrl+F9鍵運行程序,程序界面閃了一下,此時,程序已經(jīng)執(zhí)行完成。選擇“Run”菜單下的“UserScreen”或按Alt+F5鍵,可將界面切換到用戶界面,以觀察程序結(jié)果。之后按任意鍵可回到編輯窗口。特別提示:F9鍵用于編譯、連接;Ctrl?+?F9鍵用于執(zhí)行可執(zhí)行程序,如果按Ctrl?+?F9鍵時沒有可執(zhí)行的程序,則其自動生成可執(zhí)行程序而后再執(zhí)行,如圖1.7所示。在程序最后加入getchar();語句,程序執(zhí)行完后會自動停留在用戶界面下,供用戶觀察結(jié)果,省去了按Alt+F5鍵的麻煩。圖1.7TC環(huán)境下C源程序從編輯到運行的過程在TC下編寫C程序的過程總結(jié)如下:●打開TC。雙擊TC目錄下的TC.exe?!窬帉懘a。如果要打開已有的文件,按F3鍵。●保存文件。用File菜單中的Save或Writeto保存?!窬幾g、連接。直接按F9鍵,如果沒有錯誤則提示成功;否則會提示出錯,調(diào)試并修改錯誤后繼續(xù)編譯、連接●運行、測試。按Ctrl?+?F9鍵?!窨唇Y(jié)果。按Alt?+?F5鍵。

(5)?TC使用中常見問題。開始使用TC時,同學們經(jīng)常會被下面兩個編譯錯誤所困擾,

Unabletoopenincludefile'XXX.h'

Unabletoopeninputfile'COS.OBJ'這些都是因為沒有設置好路徑引起的。TC一般有兩種版本:一種是下載后需要安裝的,安裝過程中路徑已經(jīng)設置好;另一種是不需要安裝的。我們一般使用的是第二種版本,此時,路徑的設置就很重要。要正確設置路徑,首先需要了解幾個路徑的含義:

Includedirectories:TC頭文件路徑。

Librarydirectories:TC庫文件路徑。

Outputdirectories:輸出文件路徑,即obj與exe文件的存放路徑。

TurboCdirectories:TC路徑。假設TC文件夾被放在F盤,如圖1.8所示。圖1.8TC的假設路徑那么,路徑的設置應該為:

Includedirectories:F:\TC\Include

Librarydirectories:F:\TC\Lib

Outputdirectories:

TurboCdirectories:F:\TC如果不設置輸出文件路徑,那么源程序在編譯、連接過程中產(chǎn)生的?.obj和?.exe文件默認放在TC目錄下,這樣會使得TC目錄下很混亂。因此,建議大家設置該路徑。

2.?Win-TC

Win-TC是一個TCWindows平臺開發(fā)工具。該軟件使用TC為內(nèi)核,提供Windows平臺的開發(fā)界面,因此也就支持Windows平臺下的功能,例如剪切、復制、粘貼和查找替換等,方便了程序修改。

Win-TC需要安裝,讀者可從網(wǎng)上下載,默認安裝即可。不過,如果想看到執(zhí)行結(jié)果,就一定要在程序最后加上getch()。另外,Win-TC沒有提供程序調(diào)試工具,這點極大地限制了其推廣使用。圖1.9是Win-TC的界面。圖1.9Win-TC界面

3.?VisualC++

VisualC++(以下簡稱VC)是一個面向?qū)ο蟮目梢暬_發(fā)環(huán)境,主要支持C++?語言,但也可以運行C程序。VC運行于Windows下,因此習慣了圖形界面的用戶非常容易接受。VC需要安裝,本書以使用比較普遍的VisualC++?6.0?為例,介紹如何在VC環(huán)境下編寫C程序。圖1.10啟動VisualC++6.0圖1.11VisualC++6.0界面

(2)創(chuàng)建文件。選擇菜單“File”→“New”,在彈出的對話框中選擇“File”選項卡,在左邊的列表中選擇“C++SourceFile”,同時在右邊輸入文件的名稱以及保存位置,如圖1.12所示。點擊“OK”鍵,在出現(xiàn)的白色區(qū)域內(nèi)編寫代碼,如圖1.13所示。圖1.12給文件起名圖1.13VC程序邊界界面在TC環(huán)境下,我們雖然使用“stdio.h”文中的printf()?和scanf()?等函數(shù),但可以不包含“stdio.h”頭文件,因為C編譯器能找到它們。但在VC環(huán)境下,使用任何函數(shù)時都必須包含其所在的頭文件。另外,在TC環(huán)境下,main()函數(shù)的返回值類型可以不寫(此時默認是int類型),函數(shù)體中也可以不出現(xiàn)return語句;但在VC環(huán)境下,一個函數(shù)如果有返回值,則函數(shù)體中一定要有return語句,若函數(shù)沒有返回值,則必須寫上void,這點要求比較嚴格。

(3)編譯、連接與運行。選擇菜單“Build”→“CompileHello.c”,會彈出一個對話框,如圖1.14所示,選擇“是(Y)”,如果程序沒有錯誤,則在下方會出現(xiàn)編譯成功的提示,如圖1.15所示。圖1.14編譯時的提示圖1.15編譯成功我們知道,編譯的結(jié)果是生成了目標文件Hello.obj,還不能運行,必須通過連接生成可執(zhí)行文件Hello.exe之后才能運行。選擇菜單“Build”→“BuildHello.exe”,會生成可執(zhí)行文件“Hello.exe”。最后,選擇菜單“Build”→“!ExecuteHello.exe”,執(zhí)行程序,程序的運行結(jié)果會顯示出來,如圖1.16所示。圖1.16程序運行結(jié)果通常我們喜歡將編譯、連接一起進行,因此,可以直接選擇菜單“Build”→“BuildHello.exe”進行連接,中間會自動進行編譯。或者按工具欄上的圖標(編譯)、(連接)、

(執(zhí)行)進行編譯、連接與運行。在文件保存路徑“C:\CTest”下除了生成“Hello.obj”和“Hello.exe”文件之外,還生成如圖1.17所示的文件(夾)。圖1.17VC環(huán)境下運行C程序生成的文件特別提示:作為初學者,我們除了關(guān)心?.c文件、.obj文件和?.exe文件之外,其余的文件可暫時不予關(guān)心。其中?.obj和?.exe文件都在Debug文件夾下。Debug文件夾一般都比較大,因此如果要拷走程序,只需拷貝?.c文件,在目標環(huán)境下重新生成?.obj和?.exe文件即可。除了上述的三種C語言編程工具外,還有BolandC也比較常用,感興趣的讀者可以找有關(guān)資料去學習。

IDE開發(fā)環(huán)境只是方便了程序的編寫、編譯、運行和調(diào)試,程序設計的核心還是程序設計語言。因此,學好程序設計語言才是根本。作者推薦使用TC2.0或VC6.0作為C語言的IDE開發(fā)環(huán)境。1.4程序的調(diào)試方法很多初學者在調(diào)試完程序的語法錯誤后,以為大功告成,但執(zhí)行完程序后,結(jié)果卻很讓人失望。此時,他們往往不知所措,不知道程序什么地方出錯了,不知道下一步該怎么修改。下面我們一起來解決這些問題。1.4.1錯誤分類程序中常見的錯誤有三種:語法錯誤、運行錯誤和邏輯錯誤。語法錯誤是不符合程序設計語言語法規(guī)則的錯誤,這類錯誤通常在源程序被編譯時就能及時發(fā)現(xiàn)(系統(tǒng)提示出錯信息),因此比較容易修改。運行錯誤是程序在運行過程中產(chǎn)生的,比如除數(shù)為0錯誤、數(shù)組下標越界錯誤、空指針或錯誤指針錯誤。這類錯誤有時候會導致程序異常終止,有時候會產(chǎn)生莫名奇妙的結(jié)果,一般需要程序員的細心才能發(fā)現(xiàn)。邏輯錯誤是指程序運行后得不到所期望的結(jié)果(或正確的結(jié)果),也就是說程序并沒有按照程序設計者的思路來運行。比如一個最簡單例子是:我們的目的是求兩個數(shù)的和,應該寫成C?=?A?+?B;,由于書寫錯誤寫成了C?=?A?-?B;,這就是邏輯錯誤。邏輯錯誤是編譯程序發(fā)現(xiàn)不了的,也是最不容易修改的,一般要用戶通過單步跟蹤運行過程才能發(fā)現(xiàn)。下面列出一些初學者常犯的錯誤。1.編程功底不牢固

(1)少加括號。如經(jīng)常有類似下面的程序出現(xiàn):

for(i=0;i<n;i++)

j=i*i;

printf("%d*%d=%d\n",i,i,j);該程序的本意是執(zhí)行一次for循環(huán)時執(zhí)行循環(huán)體內(nèi)的2條語句,但因為缺少括號,使得結(jié)果大不一樣!

(2)忘記加分號。這種錯誤在編譯時就能發(fā)現(xiàn),但一般被指出有錯的一行并不會發(fā)現(xiàn)錯誤,此時需要看一下上一行是否漏掉了分號。

(3)多加分號。如:

inti,k=0;

for(i=0;i<10;i++);

if(i%2==0)k++;最后的if語句本來應在for循環(huán)內(nèi),現(xiàn)在卻在for循環(huán)之外了。

(4)輸入變量時少加&。如:

inta,b;

scanf("%d%d",a,b);這是不合法的,因為scanf函數(shù)的作用是按照a、b在內(nèi)存的地址將a、b的值存進去,所以要加&。

(5)輸入字符串時多加了&。如:

charstr[50];

scanf("%s",&str);數(shù)組名本身就是地址,因此不需要加&。

(6)變量輸入方式與要求方式不符。如:

scanf("%d%d",&a,&b);輸入時不能用逗號作兩個數(shù)據(jù)間的分隔符,那么下面的輸入方式不合法:

3,4

輸入數(shù)據(jù)時,在兩個數(shù)據(jù)之間以一個或多個空格間隔,也可用回車鍵、跳格鍵Tab間隔。如對于

scanf("%d,%d",&a,&b);在“格式控制”字符串中除了格式說明以外還有其他字符,則在輸入數(shù)據(jù)時應輸入與這些字符相同的字符。合法的輸入是:

3,4

若此時不用逗號而用空格或其他字符是不對的,不合法的輸入是:

34

或3:4

如對于

scanf("a=%d,b=%d",&a,&b);輸入應如以下形式:

a=3,b=4

如:

scanf("%7.2f",&a);這樣寫是不合法的,因為輸入數(shù)據(jù)時不能規(guī)定精度。

(7)字符輸入問題。在用“%c”格式輸入字符時,“空格字符”和“轉(zhuǎn)義字符”都作為有效字符輸入。如:

scanf("%c%c%c",&c1,&c2,&c3);如果輸入:abc

,則將字符“a”送給c1,字符“”送給c2,字符“b”送給c3,因為%c只要求讀入一個字符,不需要用空格作為兩個字符的間隔。以下輸入合法:

abc

(將“a”送給c1,“b”送給c2,“c”送給c3)當在一個字符前面輸入過其他類型數(shù)據(jù)時,因為確認輸入時用過回車,因此后面的字符輸入就會“跳過”,而直接將回車送入該字符。如對于

scanf("%s",str);

scanf("%c",&c);輸入:northwest

,則輸入結(jié)束,原因是將“northwest”送入str,將“\n”送入c。這種問題的解決辦法是在輸入單個字符前加fflush(stdin)函數(shù),清空輸入流緩沖區(qū),即

scanf("%s",str);

fflush(stdin);

scanf("%c",&c);

(8)字符串輸入。字符串輸入時,以空格或回車作為結(jié)束標志。如對于

scanf("%s",name);輸入:Wangmeili

,則name中的值為“wang”,而不是“wangmeili”。

(9)定義數(shù)組時誤用變量。如:

intn;

scanf("%d",&n);

inta[n];數(shù)組名后用方括號括起來的是常量表達式,可以包括常量和符號常量,不能是變量即C不允許對數(shù)組的大小作動態(tài)定義。

(10)在定義數(shù)組時,將定義的“元素個數(shù)”誤認為是可使用的最大下標值。如:

main()

{staticinta[10]={1,2,3,4,5,6,7,8,9,10};

printf("%d",a[10]);

}

C語言規(guī)定:定義時用a[10],表示a數(shù)組有10個元素,其下標值由0開始,所以數(shù)組元素a[10]是不存在的。

2.書寫錯誤

(1)函數(shù)名字書寫錯誤,一般在連接時會提示出錯,比較容易修改。

(2)變量書寫錯誤,包括大小寫錯誤、漏寫或多寫字符。如果寫錯的變量本身沒有定義,編譯時會提示出錯。但如果寫錯的變量本身已經(jīng)定義,比如在表達式中用到變量j時誤寫成了i,那么編譯程序是找不出來的,修改這種錯誤只能靠用戶自己細心查找。

(3)“=”與“==”的錯誤。如:

if(a=3)

printf("thevalueofais3");該語句的本意是判斷變量a的值是否等于3,如果等于3,則輸入一句話。但寫成上述語句之后,無論a是否等于3,都會輸出“thevalueofais3”,并且將a的值改為3,因為“=”是賦值而不是判斷是否相等。

3.括號不完整大、小括號經(jīng)常不成對出現(xiàn)。該錯誤也很好避免,那就是在需要用到括號的時候,先把一對括號都打出來,然后在中間輸入,這樣就不會忘記另一半括號了。

4.縮進格式這本身不是一種錯誤,但如果編寫的程序沒有任何格式,則其可讀性很差,格式的混亂經(jīng)常會直接導致邏輯錯誤。如果正確地運用縮進格式,大部分的錯誤就會一目了然。1.4.2調(diào)試方法

1.靜態(tài)查錯靜態(tài)查錯是指不執(zhí)行程序,僅根據(jù)程序和框圖對求解過程的描述來發(fā)現(xiàn)錯誤。由于有些錯誤在運行時很難查出,但在靜態(tài)查錯中卻容易發(fā)現(xiàn),比如說前面說到的書寫錯誤,因此,靜態(tài)查錯往往是不可忽視的審查步驟。靜態(tài)查錯一般順序為先查程序局部,后查程序整體。查局部主要是獨立地檢查各個子模塊的功能是否按照算法要求實現(xiàn),查整體主要是檢查各個局部之間的接口是否吻合,是否缺少某些功能。在靜態(tài)查錯階段,可以有針對性地檢查上面所列舉的各類型錯誤。在這個階段查出的錯誤越多,節(jié)省的調(diào)試時間也就越多。

2.動態(tài)查錯靜態(tài)查錯能夠查出錯誤,但無法保證查出所有錯誤,因為這里有一個人為的因素在里面,只要一不小心,就可能漏掉一個錯誤。因此,我們需要動態(tài)查錯與之相結(jié)合來找出遺漏的錯誤。與靜態(tài)查錯相對,動態(tài)查錯是指通過跟蹤程序的執(zhí)行過程,核對輸出結(jié)果來發(fā)現(xiàn)錯誤。動態(tài)查錯的技巧可分為兩大部分:測試用例的設計和測試的方法。我們主要講測試方法。動態(tài)查錯的測試方法可以按照以下兩種標準進行分類:

(1)按照測試用例的設計依據(jù)的不同,可分為黑箱測試法和白箱測試法。只知程序的輸入與輸出功能,而不知程序的具體結(jié)構(gòu),通過列舉各種不同的可能情況來設計測試用例,通過執(zhí)行測試用例來發(fā)現(xiàn)錯誤的測試方法叫做黑箱測試法。已知程序的內(nèi)部結(jié)構(gòu)和流向,根據(jù)程序內(nèi)部邏輯來設計測試用例,通過執(zhí)行測試用例來發(fā)現(xiàn)錯誤的測試方法叫做白箱測試法。在進行底層模塊測試的時候可以使用白箱測試法,通過專門的測試條件和測試數(shù)據(jù)來考查程序在不同點上的狀態(tài)是否符合預期的要求。在總體調(diào)試的時候則可以使用黑箱測試法,脫離程序內(nèi)部結(jié)構(gòu)來考察對于不同情況下的測試數(shù)據(jù),程序是否能夠正確輸出。對于中間模塊,可以用黑箱,也可以用白箱,或是兩者兼用,具體要看適合哪種測試法。一般說來,結(jié)構(gòu)復雜的模塊使用黑箱測試法,結(jié)構(gòu)簡單的使用白箱測試法。最后要說的是,由于白箱測試法測試用例設計比較困難,所以在時間緊張的情況下,可以一律采用黑箱測試法,這樣效率比較高。

(2)按照測試順序的不同,可分為由底向上測試和從頂向下測試。由底向上測試是先測最底層的模塊,然后依次向上測試,最后測試主模塊。從頂向下測試剛好與之相反,先測主模塊,然后按照從頂向下設計的順序依次測試各個模塊。為了加快調(diào)試的速度,建議采用從頂向下的測試順序,只在發(fā)現(xiàn)某個模塊有錯時才進入下一層調(diào)試,這樣對迅速定位錯誤也有很大幫助。在運用這些測試方法時,我們要注意哪些問題呢?首先,對自己所編的程序的結(jié)構(gòu)、模塊的功能一定要了如指掌。采用從頂向下的測試方法時,經(jīng)常是一個模塊還沒有測試完,就轉(zhuǎn)到了下一個模塊,因而特別容易忘記和疏漏。如果對程序結(jié)構(gòu)心中沒有概念,就很容易被弄糊涂。又如果對模塊的功能不是很清楚,則難以判斷模塊執(zhí)行結(jié)果的對錯,從而無法準確確定錯誤所在。其次,測試需要有條理地進行。堅持使用同一個測試用例直到輸出正確為止;在一個模塊沒有測試完畢時,不要進行下一個模塊的測試,除非這個模塊是當前模塊的子模塊且在當前模塊的測試中發(fā)現(xiàn)這個子模塊有錯。最后,在每次修改了源代碼之后一定要把已經(jīng)測過的所有測試用例再測一遍,以防產(chǎn)生新的錯誤。

3.跟蹤調(diào)試跟蹤調(diào)試通常是一件繁瑣的事,它需要足夠的耐心和細心。選擇哪些變量進行跟蹤也是至關(guān)重要的,準確的變量選擇可以起到事半功倍的效果。一般來說,首先要跟蹤的是存放輸入數(shù)據(jù)的變量,尤其對于那些需要對輸入數(shù)據(jù)進行一定處理的程序來說更是如此,輸入數(shù)據(jù)不正確,即使是正確的程序,其輸出也會與答案不符合;其次是那些頻繁用到的全局變量,這些變量往往貫穿于整個程序中,一旦某處出錯,會影響到其他模塊的正確性,由此造成定位錯誤,出錯的地方?jīng)]有測試,正確的地方反而反復測試,因此對于這些全局變量的變化要密切加以關(guān)注,不可放過任何錯誤;再次就是那些循環(huán)變量了,跟蹤循環(huán)變量可以準確地得知程序的執(zhí)行進度,從時間上把握錯誤所在;最后是其他的變量,需要根據(jù)實際情況加以選擇,對使用較多的變量應優(yōu)先加以跟蹤。1.4.3TC環(huán)境下的程序調(diào)試

TC集成開發(fā)環(huán)境下的程序調(diào)試技術(shù)包括以下兩種:①單步跟蹤程序的執(zhí)行(F7鍵或Run→Traceinto,F(xiàn)8鍵或Run→Stepover);②設置斷點和觀測項。當一個程序的執(zhí)行結(jié)果與預期結(jié)果不同時,首先進行靜態(tài)查錯,對錯誤位置進行人為定位,看看有沒有1.4.1節(jié)中提到的一些常見錯誤。當靜態(tài)查錯失效,也就是查不出錯誤時,就應該進行跟蹤調(diào)試。

(1)直接單步跟蹤調(diào)試。直接按F7鍵或F8鍵,程序便從main函數(shù)開始執(zhí)行。執(zhí)行的過程中,通過設置觀測項(Break/Watch→AddWatch)查看一些變量的值,來診斷程序在何時出錯。其中,F(xiàn)7鍵和F8鍵的區(qū)別是:如果遇到一個用戶自定義函數(shù)時,按F7鍵會進入該函數(shù),繼續(xù)跟蹤調(diào)試;而按F8鍵不會進入該函數(shù),而是直接將該函數(shù)的功能執(zhí)行完。

(2)設置斷點后單步跟蹤調(diào)試。有時候程序比較長,而我們通過靜態(tài)查錯知道開始的一段程序沒有錯誤,那么如果用F7鍵或F8鍵來調(diào)試,則會浪費很多時間,尤其是當這段程序有一個次數(shù)不少的循環(huán)時。此時,就需要先設置斷點。方法是:將光標移到可能會出錯的第一行代碼,選擇Break/watch→Togglebreakpoint,該行變色。此時開始執(zhí)行程序,當程序執(zhí)行到該斷點處時會停止執(zhí)行,此后再用F7鍵或F8鍵,設置一些觀測項來進一步排錯。另外,如果要查看程序的輸出結(jié)果,可以用Run→Userscreen或按Alt?+?F5鍵進行切換。特別提示:有些程序編譯后會出現(xiàn)很多錯誤,初學者往往不知所措。如果有些錯誤不能明顯確定所在位置,那么當改正一條明顯的錯誤后,應該先編譯一下,也許此時就不再有錯誤了。出現(xiàn)這種情況是因為編譯器也不是想象中的那么完美,出現(xiàn)的很多錯誤可能都是因為一條錯誤引起的。1.4.4VC環(huán)境下的程序調(diào)試在VC環(huán)境下調(diào)試程序,首先需要設置斷點:將光標移到斷點處,選擇工具欄上的圖標就設置了一個斷點(可以設置多個斷點);然后選擇開始調(diào)試程序。程序會在斷點處停止執(zhí)行,并出現(xiàn)一個調(diào)試工具欄,如圖1.18所示。常用的幾個功能是第一排的后4個。它們分別代表:進入函數(shù)調(diào)試(類似TC的F7鍵)、跳過函數(shù)執(zhí)行(類似TC的F8鍵)、從函數(shù)中跳出和直接執(zhí)行到光標所在位置。圖1.18VC調(diào)試工具欄調(diào)試的過程中,可在屏幕下方的Varible工具欄(如圖1.19(a)所示)中查看當前變量的值,也可以在Watch工具欄(如圖1.19(b)所示)中輸入需要查看的變量名,在Value欄中會顯示該變量的值。(a)(b)圖1.19VC的Watch和Varible工具欄1.5參數(shù)傳遞相關(guān)技術(shù)1.5.1參數(shù)傳遞

參數(shù)傳遞是函數(shù)之間進行信息交換的重要渠道。首先區(qū)分幾個概念:傳值、傳地址、值傳遞、地址傳遞。傳值和傳地址是主調(diào)函數(shù)向被調(diào)函數(shù)傳的內(nèi)容,分為傳值和傳地址兩類。值傳遞和地址傳遞是實參替換形參的方式,其中,值傳遞表示將實參的值傳遞給形參,地址傳遞表示將實參的地址傳遞給形參。

C語言中,可以傳值,也可以傳地址,但實參代替形參的方式為值傳遞方式。更詳細的內(nèi)容可參見3.4節(jié)。1.5.2函數(shù)結(jié)果的返回方式值傳遞方式最大的缺點是被調(diào)用函數(shù)不能通過參數(shù)向調(diào)用函數(shù)返值,原因是值參數(shù)的作用域只在函數(shù)內(nèi)部,無法返回結(jié)果值。如果要返回一個結(jié)果值,可以使用return方式。如果函數(shù)結(jié)果需要返回多個值,該怎樣實現(xiàn)呢?可以有以下兩類方式實現(xiàn):①通過全局變量方式返回;②通過地址傳遞(數(shù)組方式、結(jié)構(gòu)體方式、指針方式)返回。

(1)全局變量方式:不需要返回,對全局變量修改后,該程序中的其他函數(shù)均可得到改變后的值。

(2)數(shù)組方式:如果要返回的是多個相同類型的值,則可以將這些值放到一個數(shù)組中,然后返回數(shù)組的指針或首地址。

(3)結(jié)構(gòu)體方式:如果要返回的是多個不同類型的值,則可以將這些值放到一個結(jié)構(gòu)體中,然后返回結(jié)構(gòu)體的指針或全局變量。但必須注意的是,該結(jié)構(gòu)體必須是在全局范圍內(nèi)定義的結(jié)構(gòu)體。

(4)指針方式:通過參數(shù)列表傳遞,參數(shù)列表中的參數(shù)如果為指針類型,則在被調(diào)函數(shù)中改變了指針所指單元的值,返回到主調(diào)函數(shù)后,指針所指單元的值保持改變后的值。通過以下示例,說明以上返回方式的使用。【程序1.3】

函數(shù)結(jié)果返回方式示例。

#include<stdio.h>

#include<stdlib.h>

typedefstruct

{

intmax,min;

}Data;

intMIN;/*全局變量*/intfun1(inta[],intn)/*通過函數(shù)return返回最大值,通過全局變量MIN返回最小值*/{inti,max;max=MIN=a[0];//給最大值、最小值賦初值

for(i=0;i<n;i++){if(a[i]>max)max=a[i];if(a[i]<MIN)MIN=a[i];}return(max);}int*fun2(inta[],intn)/*將最大、最小值放到數(shù)組b中,通過return返回*/{staticintb[2];b[0]=b[1]=a[0];//給最大值、最小值賦初值

inti;for(i=1;i<n;i++){ if(a[i]>b[0]) b[0]=a[i]; if(a[i]<b[1]) b[1]=a[i];}return(b);}Data*fun3(inta[],intn)/*將最大、最小值放到結(jié)構(gòu)體指針p中,通過return返回*/{ Data*p; inti; p=(Data*)malloc(sizeof(Data*));//指針初始化

p->max=p->min=a[0];//給最大值、最小值賦初值

for(i=1;i<n;i++) { if(a[i]>p->max) p->max=a[i]; if(a[i]<p->min) p->min=a[i]; } return(p);}Datafun4(inta[],intn)/*將最大、最小值放到結(jié)構(gòu)體p中,通過結(jié)構(gòu)體p返回值*/{ Datap; inti; p.max=p.min=a[0];//給最大值、最小值賦初值

for(i=1;i<n;i++) { if(a[i]>p.max) p.max=a[i]; if(a[i]<p.min) p.min=a[i]; } return(p);}voidfun5(inta[],intn,int*p,int*q)/*用指針返回值,指針p指向最大值,指針q指向最小值*/{ inti; *p=*q=a[0];//給最大值、最小值賦初值

for(i=1;i<n;i++) { if(*p<a[i]) *p=a[i]; if(*q>a[i]) *q=a[i]; }}voidmain(){inta[10]={1,3,9,8,4,2,5,0,7,6},max,*p;Data*q;

Dataz;int*x,*y;

x=(int*)malloc(sizeof(int*));y=(int*)malloc(sizeof(int*));max=fun1(a,10);printf("max=%dmin=%d\n",max,MIN);p=fun2(a,10);printf("max=%dmin=%d\n",p[0],p[1]);

q=fun3(a,10);printf("max=%dmin=%d\n",q->max,q->min);z=fun4(a,10);printf("max=%dmin=%d\n",z.max,z.min);

fun5(a,10,x,y);printf("max=%dmin=%d\n",*x,*y);}1.6完整的C程序結(jié)構(gòu)一個結(jié)構(gòu)合理的C程序是由很多函數(shù)組成的,每個函數(shù)稱為一個模塊。模塊是一個具有獨立功能的程序,可以單獨設計、調(diào)試與管理。模塊化程序的設計思想是將一個大的程序按功能分割成一些模塊,使每一個模塊都成為功能單一、結(jié)構(gòu)清晰、接口簡單、容易理解的小程序。模塊化程序設計的原則有:

(1)用“自頂向下”的方法進行系統(tǒng)設計,即由整體到局部。

(2)按功能劃分法把模塊組成樹狀結(jié)構(gòu),使層次清楚。

(3)模塊的大小要適中,代碼量一般在100行以內(nèi)。

(4)各模塊間的接口要簡單,盡可能使每個模塊只有一個入口,一個出口。模塊化設計的優(yōu)點是:

(1)復雜系統(tǒng)化大為小,化繁為簡。

(2)便于維護。

(3)提高系統(tǒng)設計效率(多人可并行開發(fā))。

C語言的函數(shù)式程序結(jié)構(gòu)即是模塊化的一種體現(xiàn)。通過參數(shù)傳遞,可實現(xiàn)各模塊間的數(shù)據(jù)交換。因此,一個完整的、可執(zhí)行的C程序文件一般有兩種結(jié)構(gòu),如圖1.20所示。圖1.20C程序文件的兩種結(jié)構(gòu)圖1.20中的每行表示一段語句或程序,[]中的內(nèi)容表示可選。所謂可選,并不是說可有可無,而是要根據(jù)實際情況看是否需要它們。對于一個完整的、可執(zhí)行的C程序而言,主函數(shù)是必不可少的,它是一個程序的入口。換句話說,計算機執(zhí)行一個程序的時候,是從主函數(shù)的位置開始執(zhí)行的。還有一點需要說明的是,主函數(shù)的函數(shù)名必須使用main()。另外,如果子函數(shù)的返回值為int類型,則可以不在主函數(shù)之前聲明,而直接在主函數(shù)之后實現(xiàn),但不建議這樣做。圖1.20(a)所示結(jié)構(gòu)有一個缺點:當子函數(shù)之間互相有調(diào)用,且被調(diào)用函數(shù)返回值類型不是int時,被調(diào)用函數(shù)必須出現(xiàn)在調(diào)用函數(shù)之前,這樣限制太多。因此,建議采用圖1.20(b)的結(jié)構(gòu),這樣子函數(shù)在聲明時不受互相調(diào)用的限制,其最簡單的方式為:返回值類型函數(shù)名();/*參數(shù)可以暫時省略*/思考:包含文件語句可否出現(xiàn)在宏定義語句之后?【程序1.4】C程序結(jié)構(gòu)舉例。/*****************************************************文件名稱:test.c功能:演示C程序一般結(jié)構(gòu)作者:XXX修改日期:2008年11月12日*****************************************************/#include"stdio.h"#defineN5voidadd();/*函數(shù)聲明時可以沒有參數(shù),但必須寫清返回值類型*/voidsubstract();main(){inta[N]={1,3,5,7,9},b[N]={2,4,6,8,10},c[N],d[N];

add(a,b,c);/*兩個一維數(shù)組相加,結(jié)果放在c中*/substract(a,b,d);/*兩個一維數(shù)組相減,結(jié)果放在d中*/}/************************************************************函數(shù)名稱:add函數(shù)功能:將兩個整型一維數(shù)組相加后的結(jié)果放在另一個一維數(shù)組中參數(shù)說明:x,y,z均為一維數(shù)組,大小為N。將x和y相加后,結(jié)果放在z中返回值:無返回值************************************************************/voidadd(intx[],inty[],intz[]){inti;/*i為循環(huán)變量*/for(i=0;i<N;i++)z[i]=x[i]+y[i];}voidsubstract(intx[],inty[],intz[]){inti;for(i=0;i<N;i++)

z[i]=x[i]-y[i];}1.7良好的程序風格雖然我們開始寫的程序很簡單,但良好的風格應該從一開始就培養(yǎng)直至形成習慣。良好的風格能使程序結(jié)構(gòu)一目了然,幫助你和別

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論