版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第一章C語言基礎1.1計算機組成1.2數(shù)據表示和數(shù)制1.3算法1.4編程語言和編譯1.5C語言的發(fā)展簡史與優(yōu)點1.6C語言的定義1.7C語言的使用1.8C程序舉例習題1.1計算機組成如今計算機已經滲透到生活的方方面面,可謂無孔不入、無所不在。作為生活在計算機時代的讀者,這種現(xiàn)代化的成長經歷或許會讓你對計算機有一個感性的認識。但是本書并不關心計算機本身,不過了解一些簡單的計算機知識將有助于你理解程序是怎樣在計算機中運行的。計算機是一種可以輸入、存儲、處理和輸出各種數(shù)據的機器。這些機器可以接收、存儲、處理和輸出信息,而且能夠處理各種各樣的數(shù)據:數(shù)字、文本、圖像、圖形、聲音等等。構成計算機系統(tǒng)的各種設備(如鍵盤、屏幕、鼠標、磁盤、內存、光盤和處理器)稱為硬件。它們是有形的,可觸摸得到的。現(xiàn)代計算機是一種通用的機器,可以完成各種各樣的任務。為實現(xiàn)這些通用的功能,計算機必須是可編程的。也就是說需要給計算機提供一組指令來控制計算機解決特定問題所需要的各個具體步驟,這組指令稱為計算機程序或者軟。正是軟件和硬件的互相配合才使得完成各種計算成為可能。從小小的計算器到國家氣象局天氣預報的巨型計算機,其基本組成都是相同的。圖1.1給出了現(xiàn)今計算機系統(tǒng)的基本組成部件:中央處理單元(CPU)、內存、總線、輔助存儲設備(磁盤等)、輸入/輸出(I/O)設備(鼠標、鍵盤等)。圖1.1計算機的基本組成
1.主存儲器每當計算機執(zhí)行一個程序,計算機必須以某種方式存儲程序代碼本身和計算中所涉及的數(shù)據。通常計算機中可以存儲和獲取信息的硬件設備都被認為是存儲設備。但是只有程序運行時所使用的存儲設備才稱得上是主存儲器,也就是我們通常所說的內存。內存是一些有序排列的存儲單元,這些存儲單元包含在由集成電路組成的硅芯片當中,因此其工作效率非常高,使得CPU可以快速訪問其中的內容。各個內存存儲單元既可以保存數(shù)據,也可以保存指令,如圖1.2所示?,F(xiàn)代計算機內存由一片特殊的集成電路芯片——RAM來實現(xiàn)。RAM代表隨機訪問存儲器,允許程序在任何時間訪問任何的內存單元。RAM具有易失性,需要持續(xù)的電源以保存所存儲的數(shù)據,因此,一旦斷電會導致所有已經存儲的數(shù)據丟失。圖1.2內存中的程序和數(shù)據
2.輔助存儲器除內存外,計算機還需要其它存儲器。這主要是因為:第一,計算機需要永久地或者半永久地保存一些信息,以便在計算機掉電或關機后還能夠再使用這些信息;第二,通常計算機需要存儲遠大于內存容量的信息。圖1.3是一些經常使用的輔助存儲設備和存儲介質。由圖可知,訪問輔助存儲單元中的信息要比訪問主內存中的信息慢得多,但輔助存儲單元的單位成本比主內存的單位成本低得多。圖1.3不同存儲器關系圖
3.中央處理單元(CPU)中央處理單元(CentralProcessingUnit,CPU)是計算機的大腦,是硬件系統(tǒng)的核心。它執(zhí)行實際的計算并控制整個計算機的操作。現(xiàn)代計算機的CPU位于采用大規(guī)模集成電路工藝制成的芯片(又稱微處理器芯片)當中,包括兩個主要部分:算術邏輯單元和控制單元。CPU當前的指令和數(shù)據都臨時存儲在稱為寄存器的超高速存儲單元中。
CPU中的控制單元(ControlUnit,CU)負責從存儲器中取出指令,并對指令進行譯碼;根據指令的要求,按時間的先后順序,負責向其它各部件發(fā)出控制信號,保證各部件協(xié)調一致地工作,一步一步地完成各種操作??刂茊卧?CU)主要由指令寄存器、譯碼器、程序計數(shù)器、操作控制器等組成。
CPU中的算術邏輯單元(ArithmeticLogicUnit,ALU)對計算機數(shù)據進行加工處理,包括算術運算(加、減、乘、除等)和邏輯運算(與、或、非、異或、比較等)。
ALU使用寄存器來存取正在處理的數(shù)據,使用稱為累加寄存器的專用寄存器臨時保存運算或比較的結果。圖1.4顯示了CPU如何處理將4和5相加的這條指令。首先,控制器將要處理的數(shù)據(本例中為4和5)從RAM送至ALU中的寄存器;接著控制單元給ALU發(fā)送一個信號,指示ALU把兩個數(shù)相加;然后ALU將結果(本例中為9)存儲到累加寄存器中;最后控制單元把累加寄存器中的數(shù)據發(fā)送到RAM,這樣數(shù)據就可以輸出、存盤或者進行其它處理了。圖1.4CPU如何處理兩個數(shù)相加
4.總線總線(Bus)是一些貫穿整個計算機系統(tǒng)的電子管道,是計算機的神經系統(tǒng),用于在CPU和計算機的其它設備之間傳輸信息。微型計算機硬件結構最重要的特點是總線結構。它將信號線分成三大類,并歸結為數(shù)據總線(DataBus)、地址總線(AddressBus)和控制總線(ControlBus)。這種結構很適合計算機部件的模塊化生產,促進了微型計算機的普及。
5.輸入單元為了使用計算機,我們必須通過某種方式把數(shù)據送入計算機或者從計算機中得到數(shù)據。所有的輸入/輸出設備都通過一個控制器或者適配器連接到I/O總線??刂破鞅旧砭褪禽斎?輸出設備或者系統(tǒng)主板上的芯片組,而適配器則是一種必須插到主板擴展插槽上的接口卡。輸入單元是計算機的感知器,用于從輸入設備(鍵盤、鼠標)獲取信息。鍵盤(Keyboard)是最常見的輸入設備。標準鍵盤上的按鍵排列可以分為三個區(qū)域:字符鍵區(qū)、功能鍵區(qū)和數(shù)字鍵區(qū)(數(shù)字小鍵盤)。
6.輸出單元輸出單元是計算機的受動器,用于輸出信息到屏幕、打印機或者控制其它設備。顯示器(Display)是微型機不可缺少的輸出設備,用戶通過它可以很方便地查看送入計算機的程序、數(shù)據、圖形等信息及經過計算機處理后的中間結果、最后結果。顯示器是人機對話的主要工具。1.2數(shù)據表示和數(shù)制1.2.1數(shù)據表示計算機只能識別“0”和“1”。那么,計算機如何在存儲器中用“0”和“1”來表示上面的這些數(shù)據呢?這就是本小節(jié)數(shù)據表示需要解決的問題。正如1.1節(jié)所討論的,計算機是處理數(shù)據的機器。由于數(shù)據有各種各樣的表示形式,例如,數(shù)、文字、圖像、音頻和視頻等,要為每種不同的數(shù)據使用不同的計算機來處理,顯然是不切實際的和不經濟的。有效的解決辦法就是使用一種統(tǒng)一的數(shù)據表示方法。所有類型的數(shù)據輸入到計算機內部以后都被轉換成一種統(tǒng)一的表示格式,這種統(tǒng)一的表示格式就是比特模式(BitPattern)。在討論比特模式之前,必須先定義什么是比特(bit)。一個比特(二進制數(shù)字)是計算機存儲數(shù)據所使用的最小單元,它要么是0,要么是1。一個比特也表示了一臺設備只能取兩種狀態(tài)之一。例如,開關只能是開(On)或者關(Off)。因此,一個開關可以存儲一個比特?,F(xiàn)在,計算機使用大量的兩種狀態(tài)的設備來存儲數(shù)據。單個比特無法解決數(shù)據的表示問題。對于大數(shù)、文本、圖像等數(shù)據,我們需要使用比特模式,或比特序列來存儲。圖1.5給出了由16個比特組成的比特模式。它是0和1的組合。這意味著需要16個電子開關來存儲這個比特模式。圖1.5比特模式具體到存儲器內所保存的某個比特模式代表什么含義,則是程序的責任所在。例如,比特模式“01000001”我們既可以理解為大寫字母“A”,又可以理解為整數(shù)65。但不管怎樣,有了比特模式,我們就可以用它來表示各種不同的數(shù)據。例如,常見的英文字母符號就可以用不同的比特模式來表示。我們可以把字符串“BYTE”分別用四種不同的比特模式來表示,如圖1.6所示。圖1.6使用比特模式表示字母我們也可以使用比特模式來表示一張圖片上某個像素點的顏色,例如可以用三種比特模式來分別表示一個像素點的紅色(R)、綠色(G)和藍色(B)的強度,如圖1.7所示。圖1.7像素顏色的比特模式表示一般,長度為8的比特模式我們稱之為一個字節(jié)(Byte)。這8個比特總共有256(28)種不同的開-關條件組合,從全關00000000到全開11111111。例如,字母“A”的8比特表示為01000001,星號“*”的8比特表示為00101010。然而計算機怎么知道比特值01000001表示字母“A”呢?當用戶敲擊鍵盤的“A”時,系統(tǒng)就會從這個特定的鍵發(fā)送一個信號到內存里,并設置內存中的一個字節(jié)的比特值為01000001。接下來用戶就可以任意地對這個字節(jié)進行操作,甚至把字母“A”輸出到顯示器或者打印機上,如圖1.8所示。圖1.8字母“A”的輸出內存中的每一個字節(jié)都有一個惟一的地址。由于計算機只能區(qū)分0和1比特,因此其工作模式屬于基2計數(shù)系統(tǒng),我們稱之為二進制系統(tǒng)。事實上,詞“bit”來自于“BinarydigIT”的縮寫。一個字節(jié)當中的比特可以按照從右往左的順序對它進行0到7的編號。圖1.9所示表示對字母“A”的8個比特進行編號。最左邊的比特位我們稱之為最高有效位(MostSignificantBit,MSB),而最右邊的比特位稱為最低有效位(LeastSignificantBit,LSB)。圖1.9比特位的編號1.2.2數(shù)制數(shù)制是指用一組固定的數(shù)字和一套統(tǒng)一的規(guī)則來表示數(shù)目的方法。其中兩個最基本的概念是:
·基數(shù)(Radix):一個計數(shù)制所包含的數(shù)字符號的個數(shù)稱為該數(shù)制的基數(shù),通常用R表示,如二進制的R為2。
·
位值(權):任何一個R進制的數(shù)都是由一串數(shù)碼表示的,其中每一位數(shù)碼所表示的實際值大小,除數(shù)碼本身的數(shù)值外,還與它所處的位置有關,由位置決定的值就叫位值(或稱權,PositionalValue)。位值用基數(shù)R的i次冪(Ri)表示。日常生活采用的是十進制數(shù)制,它由0、1、2、3、4、5、6、7、8、9共10個數(shù)字符號組成,數(shù)字符號在不同的數(shù)位上表示不同的數(shù)值,每個數(shù)位均逢十進一。十進制數(shù)的基數(shù)為10,位權為10的指數(shù)次冪。二進制數(shù)使用“0”和“1”這兩個數(shù)字符號,遵循“逢二進一”的原則。例如:0+0=0;1+0=0+1=1;1+1=10;+10=11;1+11=100。在計算機中,一個二進制位又稱為一個比特(Bit),是表示數(shù)據的最小單位。二進制數(shù)的基數(shù)為2,位權為2的指數(shù)次冪。八進制數(shù)的示數(shù)符號有8個:0、1、2、3、4、5、6、7,“逢八進一”,它的基數(shù)為8,位權為8的指數(shù)次冪。十六進制數(shù)的示數(shù)符號有16個:0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,“逢十六進一”,它的基數(shù)為16,位權為16的指數(shù)次冪。八進制數(shù)和十六進制數(shù)均是為了方便書寫和閱讀時使用的,在計算機內部實際上所有的數(shù)均是二進制數(shù)。表1.1給出了十進制數(shù)字0~15所對應的二、八、十六進制數(shù)。表1.1十進制數(shù)與二、八、十六進制數(shù)對照表1.2.3數(shù)制之間的轉換通常人們習慣在一個數(shù)的后面加上一個字母B、D、H、O來區(qū)分其前面表示的一個數(shù)用的是什么數(shù)制。例如:101.01B表示二進制數(shù)101.01;A2BH表示十六進制數(shù)A2B等。
1)非十進制數(shù)轉換成十進制數(shù)利用按權展開的方法,可以將任意數(shù)制的一個數(shù)轉換成十進制數(shù)。例如:將二進制01000001轉換成十進制數(shù)如下:其轉換結果是:01000001B=0×27+1×26+0×25+0×24+0×23+0×22+0×21+1×20=64+1=65D。假定要將125.7O轉換成十進制數(shù),其轉換過程如下:其轉換結果是:125.7O=1×82+2×81+5×80+7×8-1=64+16+5+0.875=85.875D。在八進制中,小數(shù)點左邊的那位的權是1(80),再左邊一位的權是8(81),依此類推。而小數(shù)點右邊那些位的權,則是用基數(shù)(在此為8)去除,因此緊跟八進制小數(shù)點右邊那位的權是1/8,即0.125,下一位是1/64,即0.015625。
2)十進制數(shù)轉換成二進制數(shù)把十進制數(shù)轉換成二進制數(shù)的方法是采用“除二取余”法。即把十進制數(shù)除以2,所得余數(shù)作為二進制數(shù)的最低位數(shù),然后再除以2,所得余數(shù)作為次低位數(shù),如此反復,直到商為零為止。例如把十進制數(shù)23轉換為二進制數(shù)的過程如圖1.10所示,由此可得,23D=(10111)B。。圖1.10十進制數(shù)轉換為二進制數(shù)
3)二進制數(shù)轉換成十六進制數(shù)將二進制數(shù)轉換成十六進制數(shù)的方法是:從個位數(shù)開始向左按每四位二進制數(shù)一組劃分,不足四位的組前面以0補齊,然后將每組四位二進制數(shù)代之以一位十六進制數(shù)即可。例如,要將二進制數(shù)1111101011011轉換成十六進制數(shù),其轉換過程如下:最終轉換結果為:1111101011011B=1F5BH。
4)十六進制數(shù)轉換成二進制數(shù)將十六進制數(shù)轉換成二進制數(shù),其過程與將二進制數(shù)轉換成十六進制數(shù)相反。即將每一位十六進制數(shù)代之以與其等值的四位二進制數(shù)即可。例如,要將十六進制數(shù)26CE轉換成二進制數(shù),其轉換過程如下:所以:26CEH=10011011001110B1.2.4數(shù)的補碼表示我們知道,一個數(shù),例如十進制84,它的16位二進制表示是0000000001010100。但是,當同一個數(shù)84被看成是+84時,符號也必須作為二進制表示的一部分進行存儲。因此,對于有符號數(shù),最左邊的有效位通常用于存儲數(shù)的符號(Sign),而剩下的比特位表示數(shù)的量值(Magnitude)。這樣,+84的符號-量值表示為0000000001010100,同84的二進制表示一樣。盡管這兩種表示方法一樣,但是最高有效位(MSB)——第15比特的含義完全不一樣。當以二進制存儲84時,MSB是量值的一部分;而存儲帶符號數(shù)+84時,MSB為0表示它是一個正數(shù),其量值由剩下的15個比特位決定。對于負整數(shù),同樣可以用符號-量值表示,如-47可表示為1000000000101111。但是這種符號-量值表示方法有很多不足。首先,注意到0的符號-量值表示有兩種形式:0000000000000000和1000000000000000。其次,對于計算機來說要同時提供整數(shù)的二進制加法和減法運算并非易事。因此,在這一節(jié),我們將尋求計算機整數(shù)的其它存儲方法:1的補碼表示法和2的補碼表示法。
1.
1的補碼表示法對于正整數(shù),其1的補碼表示就是該整數(shù)的符號-量值表示。如+84的1的補碼表示就是0000000001010100。對于負整數(shù),1的補碼表示按下列規(guī)則計算:(2n-1)減去該數(shù)的量值,n為二進制比特數(shù),在此等于16。如-36的1的補碼表示為:步驟一:把整數(shù)的量值轉換為二進制:
+36D=0000000000100100B步驟二:因為n=16,所以
216-1=65535D=1111111111111111B上述求1的補碼表示方法看起來非常繁瑣。我們注意到:+36的1的補碼表示為:0000000000100100-36的1的補碼表示為:1111111111011011我們對+36和-36的1的補碼表示進行逐位比特比較會發(fā)現(xiàn):它們的對應比特位是互反的。因此,更簡潔的求1的補碼表示方法是對相應的正整數(shù)逐位求反。
2.2的補碼表示法對于正整數(shù),其2的補碼表示、1的補碼表示和符號-量值表示一樣。對于負整數(shù),2的補碼表示按下列規(guī)則計算:(2n)減去該數(shù)的量值,n為二進制比特數(shù),在此等于16。顯然,2的補碼表示可以通過1的補碼表示加1來實現(xiàn)。如,-36的2的補碼表示為有了2的補碼表示,我們可以驗證:
36-36=36+(-36)=0,即
(36)(-36)(0)因此,2的補碼表示可以把整數(shù)的加法和減法運算統(tǒng)一起來,而且±0的2的補碼表示也是一樣的,都是0000000000000000。所以,大部分計算機表示有符號數(shù)時都使用2的二進制補碼表示法。1.2.5字符編碼字符編碼(CharacterCode)就是規(guī)定用怎樣的二進制碼來表示字母、數(shù)字以及一些專用符號。由于這是一個涉及世界范圍內有關信息表示、交換、處理、存儲的基本問題,因此字符的編碼都是以國家標準或者國際標準的形式頒布實施的。
1.ASCII
ASCII是由美國國家標準委員會制定的一種包括數(shù)字、字母、通用符號、控制符號在內的字符編碼集,全稱為美國國家信息交換標準碼(AmericanStandardCodeforInformationInterchange),被國際標準化組織(ISO)指定為國際標準。ASCII碼是一種7位二進制編碼,能表示27=128種國際上最通用的西文字符。ASCII碼是單字節(jié)碼,在計算機內部,將最高位設為0。它常用于輸入/輸出設備,如鍵盤輸入、顯示器輸出等。
2.漢字編碼漢字也是字符,要進行編碼后才能被計算機接受。漢字編碼目前有漢字信息交換碼、漢字輸入碼、漢字內碼等。
1)漢字信息交換碼(國標碼)漢字信息交換碼是用于漢字信息處理系統(tǒng)之間或者與通信系統(tǒng)之間進行信息交換的漢字代碼,簡稱交換碼。它是為使系統(tǒng)、設備之間信息交換時采用統(tǒng)一的形式而制定的。
1981年頒布了《信息交換用漢字編碼字符集基本集》,代號“GB2312-80”,簡稱國標碼。它是為使系統(tǒng)、設備之間信息交換時采用統(tǒng)一的形式而制定的。兩個字節(jié)存儲一個國標碼。
2)漢字輸入碼為將漢字輸入計算機而編寫的代碼稱為漢字輸入碼,也叫外碼。如區(qū)位碼、拼音碼、智能ABC碼等。
3)漢字內碼漢字內碼是在計算機內對漢字進行存儲、處理的漢字代碼,它應能滿足存儲、處理和傳輸?shù)囊蟆.斠粋€漢字輸入計算機后,就轉換為內碼,然后才能在計算機中流動和處理。漢字內碼多種多樣。目前,對應于國標碼一個漢字的內碼常用2個字節(jié)存儲,并把每個字節(jié)的最高位置“1”作為漢字內碼的標識,以免與單字節(jié)的ASCII碼產生歧義性。漢字的機內碼=漢字的國標碼+8080H1.3算法計算機科學是借助計算機解決問題的學科。在此我們必須理解一個對于計算機科學和問題解決來說都很基礎的概念——算法(Algorithm)。我們可以簡單地認為算法是一種解決問題的策略。但是,嚴格地說,要使某種解決問題的技術能被定義為是一種算法,必須滿足三個基本要求,即
·有窮性:一個算法應包含有限的操作步驟而不能是無限的。
·確定性:算法中每一個步驟都應當是確定的,而不應當是含糊的、模棱兩可的、有歧義的。
·有效性:算法中每一個步驟應當能有效地執(zhí)行,并得到確定的結果。對于程序設計人員,必須會設計算法,并把算法用某種編程語言來實現(xiàn)。從這個角度來說,編程就是把所選用的算法翻譯成計算機能夠使用的語言。算法:解決問題的步驟和策略。算法的表示方法很多,在此我們主要討論自然語言表示法、偽代碼表示法和流程圖表示法。
1.自然語言表示法自然語言可以是中文、英文、數(shù)學表達式等等。用自然語言表示通俗易懂,缺點是可能文字冗長,不太嚴格,表達分支和循環(huán)的結構不很方便。除了很簡單的問題,一般不用自然語言表示法。
2.偽代碼表示法偽代碼(Pseudocode)是用得最為普遍的定義算法的工具,它使用介于自然語言和計算機語言之間的文字和符號來描述算法。它通常包含類英語描述部分和結構化代碼部分。類英語描述部分提供通俗易懂的、不太嚴格的語法表示;結構化代碼部分提供各種擴展的算法結構,如順序、選擇、循環(huán)、遞歸等。用偽代碼編寫的算法通常以算法名字作為開頭(例如找多個數(shù)的最小數(shù)),后面緊跟著該算法的目的(找最小的數(shù))、前提條件(提供數(shù)的列表)、需要的后處理(是否打印該最小數(shù))以及返回的結果(最小數(shù)),如圖1.11所示。圖1.11一個偽代碼例子我們認為任何一個算法都應該有返回值,即使沒有,也應當返回一個空值(NULL)。算法中的所有指令語句都應當進行編號,且不跟任何符號結尾。在偽代碼中,通常用連續(xù)的數(shù)字或字母來表示同一級模塊中的連續(xù)語句。符號△后的內容表示注釋。在偽代碼中,變量名和保留字不區(qū)分大小寫,變量不需聲明。賦值語句用符號←表示,x←exp表示將exp的值賦給x,其中x是一個變量,exp是一個與x同類型的變量或表達式(該表達式的結果與x同類型);多重賦值i←j←e是將表達式e的值賦給變量i和j,這種表示與j←e和i←e等價。例如:x←y
x←20*(y+1)
x←y←30
3.流程圖表示法流程圖表示算法,直觀形象,易于理解。流程圖是符號的組合,是圖形化表示。這些符號可以增加流程圖的可讀性和功能,但它們并不直接用于表示指令或者命令。常見的符號及其含義見表1.2。表1.2常見的符號及其含義求和是計算機科學中常用的一種算法。圖1.12所示的流程圖是通過循環(huán)結構把多個數(shù)相加來計算其和的。這個求和算法包含三個邏輯部分:
(1)算法一開始對保存和的變量初始化。
(2)循環(huán)部分:每次取一個數(shù)同前面已經計算得到的和相加。
(3)返回求和結果,退出循環(huán)。圖1.12求和算法流程圖表示1.4編程語言和編譯1.4.1什么是程序程序(Program)是指令的集合,它們告訴計算機如何對數(shù)據進行處理以獲得編程者需要的信息,也是計算機在完成某項任務時必須嚴格遵循的。而指令則是由編程語言,如BASIC、C、Java的語句構成的。程序和軟件(Software)這兩個詞可以互換使用。軟件主要有兩大類:系統(tǒng)軟件和應用軟件。
1.系統(tǒng)軟件系統(tǒng)軟件是指管理、監(jiān)控和維護計算機資源以及開發(fā)其它軟件的計算機程序,包括操作系統(tǒng)、程序設計語言處理程序、支持軟件等。其中最重要的是操作系統(tǒng),它是控制和管理計算機的核心,用來對計算機系統(tǒng)中的各種軟、硬件資源進行統(tǒng)一的管理和調度。它也是人和計算機的操作界面,我們使用計算機就是和操作系統(tǒng)打交道,我們學習使用計算機就是學習操作系統(tǒng)的使用。常用的操作系統(tǒng)有DOS、Windows、UNIX等。操作系統(tǒng)的部分程序永久存儲在只讀存儲器(ROM)芯片中,以便計算機開機后即可使用。計算機可以讀出ROM當中的內容,但不能向ROM中寫入數(shù)據。操作系統(tǒng)保存在ROM中的這部分程序,包括將操作系統(tǒng)其余代碼加載到內存所必需的指令,這些代碼一般存儲在磁盤上。加載操作系統(tǒng)的這一過程稱之為引導計算機。
2.應用軟件應用軟件是指為解決各種實際問題而編制的計算機程序,如字處理應用軟件、學籍管理系統(tǒng)等。應用軟件可以由用戶自己編制,也可以由軟件公司編制。如MicrosoftOffice就是微軟(Microsoft)公司開發(fā)的辦公自動化軟件包,包括字處理軟件Word、表格處理軟件Excel、演示軟件Powerpoint等。1.4.2什么是編程編程,也稱為軟件開發(fā),就是為了產生這些指令的集合。這個過程通常包含以下6個步驟:
(1)程序說明書,也稱為程序定義或者程序分析。它需要編程人員詳細說明以下5項內容:①程序的目標;②程序所需的輸入;③所期望的輸出;④處理要求;⑤文檔要求。這些內容要求程序員對問題有一個清晰的概念,能夠不含糊的對問題進行陳述,從而對解決問題的要求有一個準確的理解。
(2)程序設計。在此階段,要求逐步寫出算法的一系列步驟來解決問題并驗證算法能否達到預定目的。這需要借助編程技術(例如結構化編程技術)來得到解決問題的步驟。結構化編程技術包括自頂而下程序設計、偽代碼、流程圖和邏輯結構。所謂自頂而下程序設計就是要列出程序的主要處理步驟或者要解決的各個子問題,然后通過解決每個子問題來解決最終的問題。這些子問題也被稱為程序模塊(ProgramModules)。所以這種方法就是把復雜的大的任務分解成為簡單的小的任務,然后各個擊破、分而治之。理論上任何程序模塊可以用以下三種邏輯結構來實現(xiàn):順序、分支和循環(huán)。使用這三種結構可以編寫出所謂的結構化程序。
(3)程序編碼。編碼是使用某種編程語言來實際編寫程序。程序員必須將算法中的每個步驟轉化為程序設計語言的一條或者多條語句。
(4)程序測試。它就是要檢驗寫好的程序是否能夠像預想的一樣工作。編程人員通常也稱測試為調試(Debug),就是要消除程序的語法和邏輯錯誤,找出程序中的“蟲子(Bug)”。語法錯誤是指違反編程語言規(guī)則的錯誤。例如,在C語言中所有的語句都必須以分號(Semicolon)結束,如果某條語句省略了分號,程序將因為這個錯誤而無法正常運行,如圖1.13所示。常見的錯誤測試方法包括:
·臺面測試(DeskChecking):是常常被忽略的重要測試部分。程序員必須像計算機那樣對程序代碼的每一行進行仔細檢查以尋找其中的語法和邏輯錯誤,并檢驗程序執(zhí)行是否如期望所想。
·帶有樣本數(shù)據的手工測試(ManualTestingwithSampleData):利用正確和錯誤的數(shù)據手工地對程序的執(zhí)行過程進行檢查。
·編譯測試(AttemptatTranslation):程序要在計算機上執(zhí)行,必須依靠編譯器進行翻譯。編譯器試圖把程序員所編寫的編程語言代碼(如C代碼)翻譯成機器語言。在此過程中,程序必須是沒有語法錯誤的才能被正確地翻譯成機器語言。這類錯誤往往可以通過編譯器來識別,如圖1.13所示。圖1.13編譯器進行語法檢查
·帶有樣本數(shù)據的計算機測試(TestingSampleDataonTheComputer):糾正完所有的語法錯誤后,就要使用各種樣本數(shù)據測試程序的邏輯錯誤。
·潛在用戶測試(TestingbyaSelectGroupofPotentialUsers):有時也稱為BetaTesting。這通常是程序測試的最后一個步驟,由潛在的用戶對程序進行測試,并反饋回測試意見。
(5)程序文檔。建檔(Documenting)就是對程序的目的和處理過程進行記錄。程序文檔包含了程序功能的描述、程序的處理流程和使用手冊。建檔貫穿整個軟件生命周期,只不過到此步驟為止,所有以往的文檔必須進行重新檢查和完善,以得到最終的程序文檔。程序文檔對于所有潛在的同程序有關的用戶來說都是非常重要的。例如:對于程序的使用者,必須明確告訴他如何使用你的軟件,有些公司甚至還為此專門進行用戶使用的培訓;對于編程人員,隨著時間的流逝,自己都有可能忘記當初此程序是如何編寫的,更不用說后續(xù)參與到軟件開發(fā)的人員。因此,為了易于程序的后期更新和維護,程序文檔應當足夠詳細,盡量提供各種文字信息、程序的執(zhí)行流圖、程序列表、樣本輸出結果以及程序與系統(tǒng)的依賴關系等。
(6)程序維護。程序維護的目的是確保當前程序能正確無誤地、高效地、穩(wěn)定地運行。隨著軟件的復雜程度日益增加,不可避免地存在各種各樣的軟件缺陷。通過程序維護可以改正先前沒有被發(fā)現(xiàn)的錯誤并從而保持軟件最新。很多軟件公司對程序要維護五年甚至更長時間,因此其費用往往很高,占應用程序整個壽命開支的75%左右。1.4.3編程語言的分類計算機語言(ComputerLanguage)指用于人與計算機之間通信的語言。語言分為自然語言與人工語言兩大類。自然語言是人類在自身發(fā)展的過程中形成的語言,是人與人之間傳遞信息的媒介。人工語言指的是人們?yōu)榱四撤N目的而自行設計的語言。計算機語言就是人工語言的一種,它是人與計算機之間傳遞信息的媒介。計算機語言通常是一個能完整、準確和規(guī)則地表達人們的意圖,并用以指揮或控制計算機工作的“符號系統(tǒng)”。計算機語言通常分為三類,即機器語言、匯編語言和高級語言。
圖1.14給出了C語言指令a=a+1;所對應的匯編語言代碼和機器語言代碼。圖1-14C語言、匯編語言和機器語言代碼
1.機器語言機器語言是用二進制代碼表示的計算機能直接識別和執(zhí)行的一種機器指令的集合。它是計算機的設計者通過計算機的硬件結構賦予計算機的操作功能。機器語言具有靈活、直接執(zhí)行和速度快等特點。不過,編程人員很少用計算機能夠直接理解的語言編程,因為這種機器語言是一串串二進制數(shù)的集合。編程人員要首先熟記所用計算機的全部指令代碼和代碼的涵義。例如,1000001111000000表示加法指令,用1000001111101000作為減法指令,使計算機執(zhí)行一次減法。編程序時,程序員得自己處理每條指令和每一數(shù)據的存儲分配及輸入/輸出,還得記住編程過程中每步所使用的工作單元處在何種狀態(tài)。這是一件十分繁瑣的工作,編寫程序花費的時間往往是實際運行時間的幾十倍或幾百倍。而且,編出的程序全是些0和1的指令代碼,直觀性差,還容易出錯。機器語言通常沒有統(tǒng)一的標準,不同型號的CPU都有各自的機器語言。
2.匯編語言為了克服機器語言難讀、難編、難記和易出錯的缺點,人們就用與代碼指令實際含義相近的英文縮寫詞、字母和數(shù)字等符號來取代指令代碼(如用“addeax,1”代表一次加法,用“subeax,1”代表一次減法),于是就產生了匯編語言。所以說,匯編語言是一種用助記符表示的仍然面向機器的計算機語言。匯編語言亦稱符號語言。匯編語言是采用助記符號來編寫程序的,比用機器語言的二進制代碼編程要方便些,這在一定程度上簡化了編程過程。匯編語言的特點是用符號代替了機器指令代碼,而且助記符與指令代碼一一對應,基本保留了機器語言的靈活性。使用匯編語言能面向機器并較好地發(fā)揮機器的特性,得到質量較高的程序。匯編語言中由于使用了助記符號,用匯編語言編制的程序送入計算機,計算機不能像用機器語言編寫的程序一樣直接識別和執(zhí)行,必須通過預先放入計算機的“匯編程序”的加工和翻譯,才能變成被計算機識別和處理的二進制代碼程序。用匯編語言等非機器語言書寫好的符號程序稱為源程序,運行時匯編程序要將源程序翻譯成目標程序。目標程序是機器語言程序,它一經被安置在內存的預定位置上,就能被計算機的CPU處理和執(zhí)行。匯編語言的實質和機器語言是相同的,都是直接對硬件操作,只不過指令采用了英文縮寫的標識符,更容易識別和記憶,因而仍然是面向機器的語言,使用起來還是比較繁瑣,通用性也差。匯編語言是低級語言。但是,匯編語言用來編制系統(tǒng)軟件和過程控制軟件,其目標程序占用內存空間少,運行速度快,有著高級語言不可替代的用途。
3.高級語言不論是機器語言還是匯編語言都是面向硬件具體操作的,語言對機器的過分依賴,要求編程人員必須對硬件結構及其工作原理都十分熟悉,這對非計算機專業(yè)人員是難以做到的,對于計算機的推廣應用也是不利的。計算機事業(yè)的發(fā)展,促使人們去尋求一些與人類自然語言相接近且能為計算機所接受的語意確定、規(guī)則明確、自然直觀和通用易學的計算機語言。這種與自然語言相近并為計算機所接受和執(zhí)行的計算機語言稱為高級語言。高級語言是目前絕大多數(shù)編程者的選擇。和匯編語言相比,它不但將許多相關的機器指令合成為單條指令,并且去掉了與具體操作有關但與完成工作無關的細節(jié),例如使用堆棧、寄存器等,這就大大簡化了程序中的指令。同時,由于省略了很多細節(jié),編程人員也就不需要有太多的專業(yè)知識。高級語言接近人們習慣使用的自然語言和數(shù)學語言,使人們易于學習和使用。人們認為,高級語言的出現(xiàn)是計算機發(fā)展史上一次驚人的成就,使千萬非專業(yè)人員能方便地編寫程序,按人們的指令操縱和使用計算機。語言進化和抽象過程如圖1.15所示。圖1.15語言進化和抽象過程例如要完成兩個數(shù)的相加,可以用以下語句來實現(xiàn):
a=a+1;這條語句表示“將變量a與1的值相加并把結果存入變量a(替換a原來的值)”。高級語言主要是相對于匯編語言而言的,它并不是特指某一種具體的語言,而是包括了很多編程語言,常用的高級語言有:BASIC(適合初學者應用)、FORTRAN(用于數(shù)據計算)、COBOL(用于商業(yè)管理)、Pascal(用于教學)、C(用于編寫系統(tǒng)軟件)、Ada(用于編寫大型軟件)、LISP(用于人工智能)等。不同的語言有其不同的功能,人們可根據不同領域的需要選用不同的語言。高級語言是面向用戶的語言。無論何種機型的計算機,只要配備上相應的高級語言的編譯或解釋程序,則用該高級語言編寫的程序就可以通用。計算機并不能直接地接受和執(zhí)行用高級語言編寫的源程序,源程序在輸入計算機時,通過“翻譯程序”翻譯成機器語言形式的目標程序,計算機才能識別和執(zhí)行。但是計算機高級語言只定義了程序的屬性而不是程序的執(zhí)行方式,理解這一點很重要。程序執(zhí)行一般有兩種方式,即編譯方式和解釋方式。
·解釋方式:執(zhí)行方式類似于我們日常生活中的“同聲翻譯”,每當源程序進入計算機時,解釋程序邊掃描邊解釋,對逐句輸入進行翻譯,而計算機則一句句執(zhí)行,并不生成可獨立執(zhí)行的可執(zhí)行目標程序。因此應用程序無法脫離其解釋器獨立運行,但這種方式比較靈活,可以動態(tài)地調整、修改應用程序。
·編譯方式:編譯是指在應用源程序執(zhí)行之前,就將程序源代碼“翻譯”成目標代碼(機器語言),因此其目標程序可以脫離其語言環(huán)境獨立執(zhí)行,使用比較方便、效率較高。但應用程序一旦需要修改,必須先修改源代碼,再重新編譯生成新的目標文件(*.OBJ)才能執(zhí)行。如果只有目標文件而沒有源代碼,修改起來很不方便。現(xiàn)在大多數(shù)的編程語言都是編譯型的,例如VisualC++、VisualFoxpro、Delphi等。程序被編譯之后,源代碼行對程序的執(zhí)行就毫無意義了。1.5
C語言的發(fā)展簡史與優(yōu)點
1.C語言的發(fā)展簡史
C語言是國際上廣泛流行的、很有發(fā)展前途的計算機高級語言。它適合于作為系統(tǒng)描述語言,既可用來寫系統(tǒng)軟件,也可用來寫應用軟件。
C語言是第三代語言(面向過程的高級語言,第一代:機器語言;第二代:匯編語言)。以前的操作系統(tǒng)等系統(tǒng)軟件主要是由匯編語言編寫的(包括UNIX操作系統(tǒng)在內)。由于匯編語言依賴于計算機硬件,程序的可讀性和可移植性都比較差。為了提高可讀性和可移植性,最好改用高級語言,但一般高級語言難以實現(xiàn)匯編語言的某些功能(匯編語言可以直接對硬件進行操作,例如,對內存地址的操作、位操作等)。人們設想能否找到一種既具有一般高級語言特性,又具有低級語言特性的語言,集它們的優(yōu)點于一身。于是,C語言就在這種情況下應運而生了。
C語言是在B語言的基礎上發(fā)展起來的,它的根源可以追溯到ALGOL60。1960年出現(xiàn)的ALGOL
60是一種面向問題的高級語言,它離硬件比較遠,不宜用來編寫系統(tǒng)程序。1963年英國的劍橋大學推出了CPL(CombinedProgrammingLanguage)語言,CPL語言在ALGOL60的基礎上接近硬件一些,但規(guī)模比較大,難以實現(xiàn)。1967年英國劍橋大學的MartinRichards對CPL語言作了簡化,推出了BCPL(BasicCombinedProgrammingLanguage)語言。
1970年美國貝爾實驗室的KenThompson以BCPL語言為基礎,又作了進一步簡化,設計出了很簡單的而且很接近硬件的B語言(取BCPL的第一個字母),并用B語言寫了第一個UNIX操作系統(tǒng),在PDP-7計算機上實現(xiàn)。但B語言過于簡單,功能有限。1972年至1973年間,貝爾實驗室的D.M.Ritchie在B語言的基礎上設計出了C語言(取BCPL的第二個字母)。C語言既保持了BCPL和B語言的優(yōu)點(精練、接近硬件),又克服了它們的缺點(過于簡單、數(shù)據無類型等)。最初的C語言只是為描述和實現(xiàn)UNIX操作系統(tǒng)提供一種工作語言而設計的,1973年,K.Thompson和D.M.Ritchie兩人合作把UNIX的90%以上代碼用C改寫(即UNIX第5版,原來的UNIX操作系統(tǒng)是1969年由美國的貝爾實驗室的K.Thompson和D.M.Ritchie開發(fā)成功的,是用匯編語言寫的)。后來,C語言被多次作了改進,但主要還是在貝爾實驗室內部使用。直到1975年UNIX第6版公布后,C語言的突出優(yōu)點才引起人們的普遍注意。隨著UNIX的日益廣泛使用,C語言也迅速得到推廣,C語言和UNIX可以說是一對孿生兄弟,在發(fā)展過程中相輔相成。1978年以后,C語言已先后移植到大、中、小、微型機上,已獨立于UNIX和PDP了?,F(xiàn)在C語言已風靡全世界,成為世界上應用最廣泛的幾種計算機語言之一。以1978年發(fā)表的UNIX第7版中的C編譯程序為基礎,BrianW.Kernighan和DennisM.Ritchie(合稱K&R)合著了影響深遠的名著《TheCProgrammingLanguage》,這本書中介紹的C語言成為后來廣泛使用的C語言版本的基礎,它被稱為標準C。1983年,美國國家標準化協(xié)會(ANSI)根據C語言問世以來各種版本對C的發(fā)展和擴充,經過6年時間的修訂,于1989年發(fā)布了新的標準,稱為ANSIC或者C89。
ANSIC比原來的標準C有了很大的發(fā)展。目前流行的C編譯系統(tǒng)都是以它為基礎的。本書的敘述基本上以ANSIC為基礎。目前廣泛流行的各種版本C語言編譯系統(tǒng)雖然基本部分是相同的,但也有一些不同。讀者可以參閱相關計算機系統(tǒng)的C語法手冊。
1999年又開發(fā)了新的C語言標準,通常稱為C99。C99基本保留了C89的全部特性。新標準的主要改進包括以下兩個方面:增加了數(shù)據庫函數(shù)和開發(fā)了一些專門的新特性,例如可變長度數(shù)組和restrict指針修飾符。
2.C語言的優(yōu)點在最近20年里,C已經成為一種最重要的、最流行的程序設計語言。它是在人們的嘗試與喜愛之中成長起來的。當用戶學習C語言的時候,將體驗到它的很多優(yōu)點。
C語言的優(yōu)點如下:
(1)設計時的考慮。C是一種融入強大控制功能的新式語言。計算機科學的理論和實踐認為,這些控制功能都是需要的。C的設計使得用戶自然而然地去采用自頂向下的、結構化的程序設計原則,以及模塊化的設計方法,從而獲得更加可靠、更加易于理解的程序。
(2)效率。C的效率非常高,它的設計充分發(fā)揮了當代計算機各方面的效能。事實上,C提供了通常僅與匯編語言相聯(lián)系的某些精細的控制。只要用戶愿意,盡可能地微調自己的程序,以達到最快的速度,或者最有效地利用內存。
(3)可移植性。C是一種可移植的語言。這意味著在一個系統(tǒng)上編制的C程序,只需很少的修改,甚至無需修改,即可在別的系統(tǒng)上運行。如果修改是必要的,那么,這些修改僅僅是在伴隨主程序的頭(Header)文件里變動幾個項目。就可移植性而言,C是領先者,C編譯器可供大約40個系統(tǒng)使用,它們運行在從八位的微處理器直至Cray超級巨型機上。
(4)高效而靈活。C高效而靈活(計算機文字中的兩大褒義詞),例如,高效、靈活的UNIX操作系統(tǒng)大部分是用C編寫的,其它的語言——諸如FORTRAN,Pascal、LISP、BASIC等的編譯器和解釋程序均以C來編制。因此,當用戶在一臺UNIX機器上使用FORTRAN的時候,歸根結底,是一個C程序為用戶生成了最終的可執(zhí)行代碼。C程序已被用來求解各種物理和工程等問題,甚至為電影產生了特殊的動畫效果。
(5)面向程序員。C竭力迎合程序設計員的需要。它允許用戶訪問硬件,放手讓用戶去操作內存中的每個字節(jié)位。C的運算符有多種選擇,使用戶得以簡潔地表達自己的意見。C在限制用戶方面,不如Pascal那么嚴格。這既是優(yōu)點,又很危險。說它是優(yōu)點,因為許多工作在C語言里極其簡單;說它危險,因為C使用戶犯一些在其它語言里不可能有的錯誤,C給用戶更多的自由,同時也賦予更大的責任。1.6
C語言的定義
C語言通常被稱為中級計算機語言。這并非貶義,也不是說它功能差或難以使用,或者比其它高級語言原始。相反,C語言之所以被稱為中級語言,是因為它把高級語言的最佳元素同匯編語言的強有力的控制結構和靈活性結合起來了。作為中級語言,C允許對位、字節(jié)和地址這些計算機功能中的基本成分進行操作,因此非常適合編寫經常進行上述操作的系統(tǒng)程序。盡管如此,C語言程序還是非常容易移植的。所謂可移植指的是,易于把為某種計算機編寫的軟件改寫到另一種機器或者操作系統(tǒng)上。例如,為DOS系統(tǒng)寫的一個程序,能夠方便地改為在Windows2000系統(tǒng)下運行。不像高級語言那樣,C幾乎不進行運行時的錯誤檢查,例如不檢查數(shù)組邊界是否溢出。檢查運行時的錯誤完全交給程序來處理。1.7
C語言的使用正如前面所述,C是一種編譯型語言。在接下來的章節(jié)中,我們將指導讀者經歷從C編程目標到最終可執(zhí)行程序的全過程。首先,為了讓讀者對C程序設計有一個大概的了解,我們把C程序的編寫活動分解成七個步驟。在實際當中,特別是針對較大的軟件項目,程序員可能需要在這些步驟之間進行反復,利用后續(xù)步驟所學知識來改進前面的步驟。步驟一:確定程序目標。不言而喻,程序員打算讓這個程序干什么,在編程的最初就應當有清晰的思路。對程序所需要的信息、程序所要完成的計算和操作技巧以及程序應當返回的結果都應當有明確的思路。在程序規(guī)劃階段中,應當概括性地對程序的目標有所考量,而不是使用某種特定的計算機語言來考慮問題。步驟二:設計程序。一旦對這個程序該做什么有了概念上的描述,下面就要確定程序該如何做。用戶界面應該像什么樣子?程序該如何組織?最終用戶是誰?需要多長時間完成?程序員同樣還得決定如何表示程序里的數(shù)據,以及采用哪些方法處理這些數(shù)據。這在剛開始學習C語言編程時,問題都比較簡單,對數(shù)據的處理也相對簡單。而當面臨復雜問題時,學習者會發(fā)現(xiàn)做出這些決策需要更多的思考。選擇一種好的信息表示方法,常常能夠使程序的設計和數(shù)據的處理更為容易。同樣在這個階段,我們應該用常見的算法表示方法來設計程序,而不是某種特定的語言代碼。步驟三:編寫代碼。一旦對程序的設計有了清楚的認識,就可以著手編寫代碼去實現(xiàn)。這意味著把程序的設計翻譯成C語言代碼。這也是真刀真槍地運用C知識的過程。一般而言,程序員使用文本編輯器來創(chuàng)建源代碼(SourceCode)文件。該文件是用戶對程序設計的C語言再現(xiàn),也是一個C程序生命周期的開始。圖1.16給出的Hello程序是由K&R合著的《TheCProgrammingLanguage》給出的第一個C源程序。圖1.16
Hello程序該源程序可以由程序員通過編輯器創(chuàng)建并保存為文本文件,文件名就是Hello.c。源程序實際上就是由一系列的字節(jié)組成的,每個字節(jié)表示程序中的某個文本字符。采用的具體編碼格式遵循1.2節(jié)的ASCII碼規(guī)則。實際上就是用一個惟一的字節(jié)大小的整數(shù)值來表示每個字符,如圖1.17給出了Hello.c源程序的ASCII表示。圖1.17Hello.c的ASCII碼文本表示在圖1.17中,〈sp〉表示空格,其ASCII值為32。由圖1.17可知,hello.c程序實際上就是以字節(jié)序列的形式保存的磁盤文件,也稱為文本文件。每個字符對應一個整數(shù)值。例如第一個字節(jié)的整數(shù)值35對應于字符“#”;第二個字節(jié)的整數(shù)值105對應于字符“i”。值得注意的是,每一行文本都是以不可見的換行(Newline)字符“\n”結束,其整數(shù)值為10。
Hello.c文件的這種表示再次說明一個基本的概念:計算機系統(tǒng)內的所有信息都是用比特串的模式來表示的。作為本步驟的組成部分,程序員應該為自己所做的編程工作編寫文檔。利用C語言的注釋機制在源代碼中加入對程序的說明。步驟四:編譯。本步驟是對源代碼進行編譯,其具體細節(jié)依賴于用戶的程序設計環(huán)境。在此我們只對編譯作一個概念性的討論。
C源程序是用高級編程語言編寫而成的。盡管對程序員來說用高級語言來表示解決問題的方案要來得容易。但是計算機無法理解其具體含義,也就無法直接執(zhí)行一個C源程序。因此,必須借助其他程序把源代碼中的C語句轉換成低級的機器語言指令序列,才能在計算機上執(zhí)行。負責完成翻譯轉換的程序稱為編譯程序或者編譯器。圖1.18顯示了編譯器在高級語言程序的開發(fā)和調試過程中的作用。圖1.18輸入、編譯、運行高級語言程序首先,編譯器本身也是一個程序,它的任務就是把文本類型的源程序轉換成為二進制格式的目標程序,也稱為目標文件。目標程序由計算機的母語或者機器語言組成。這種語言包含各種用數(shù)字代碼表示的詳細指令。如果對Hello.c源程序進行編譯,編譯器將創(chuàng)建一個名為Hello.obj的目標文件。雖然目標文件包含機器指令,但并非所有指令都是完整的。C語言為軟件開發(fā)人員提供了許多完成特定操作的稱為程序塊的代碼——函數(shù),它們存儲在系統(tǒng)可以訪問的其他目標文件中。C程序庫包含大量的標準程序,比如printf()和scanf()輸入/輸出函數(shù)。這些程序可以用于程序員自己編寫的代碼中。鏈接器(Linker)程序把這些預制的函數(shù)和編譯器所創(chuàng)建的目標代碼鏈接起來形成一個完整的可執(zhí)行文件(如Hello.exe),其中包含了計算機可以理解的代碼,它可以由用戶在計算機上運行。編譯器也檢查用戶程序語法是否合法。倘若編譯器發(fā)現(xiàn)錯誤,那么它把出錯信息報告給用戶,并且不會生成最終的可執(zhí)行文件。步驟五:執(zhí)行程序。如果Hello.exe僅僅是存儲在用戶的磁盤上,則它不會做任何事。按照慣例,可執(zhí)行文件就是用戶可運行的程序。在包括MS-DOS,UNIX,Linux控制臺在內的很多常見環(huán)境下的運行程序,只需要輸入可執(zhí)行文件的名字即可。而在集成開發(fā)環(huán)境中,如微軟的WindowsVC++,允許用戶使用菜單選項或者特殊按鍵來編輯和執(zhí)行C程序。當然,這些程序也可以在操作系統(tǒng)中通過雙擊文件或者圖標來運行它們。要執(zhí)行它,加載程序必須把全部指令復制到內存,并指示CPU從第一條指令開始執(zhí)行。
Shell就是命令解釋程序,它一直處于等待用戶輸入命令狀態(tài)。當我們通過鍵盤輸入“hello”時,命令解釋程序把每個字符讀入寄存器,然后保存到內存中,如圖1.19所示。圖1.19從鍵盤讀入hello命令當最后按回車鍵時,命令解釋程序就知道我們已經輸完整條命令。此時,命令解釋程序就會加載hello可執(zhí)行文件,也就是把hello目標文件的代碼和數(shù)據從磁盤拷貝到內存中。通過使用DMA(DirectMemoryAccess)技術,數(shù)據被直接送入內存,而不是通過處理器中轉,如圖1.20所示。圖1.20把可執(zhí)行文件從磁盤加載到內存中一旦hello目標文件的代碼和數(shù)據被加載到內存中,處理器開始執(zhí)行hello程序內main函數(shù)中的機器語言指令。這些指令將把字符串“hello,world\n”中的字符挨個送入寄存器文件,并最終顯示在屏幕上,如圖1.21所示。圖1.21從內存輸出字符串到顯示器步驟六:程序測試與調試。程序可以運行,這是一個好兆頭。然而,運行的結果不正確也是很有可能的。因此,用戶應當檢查程序是否在做它應該做的事情。用戶會發(fā)現(xiàn),自己的程序可能存在某些差錯,即蟲子(Bug)。調試(Debugging)就是尋找并糾正這些錯誤的過程。程序存在缺陷,這本身就是學習語言編程的一個部分,也是一種非常正常的現(xiàn)象,是編程工作所固有的。因此,學習語言編程就是要從錯誤提示中不斷地去糾正自己所犯的錯誤。隨著自己編程能力的提高,用戶所犯的錯誤也將變得更加隱蔽和更加難以捉摸。用戶在很多地方都容易出錯,可能是設計上的錯誤;想法不錯,可是設計不正確;或許忽略了一個意外的輸入;打字錯誤;括號位置不對等等。幸運的是,編譯器能夠捕獲大多數(shù)的錯誤,而且開發(fā)環(huán)境通常還會提供大量的輔助工具幫助用戶監(jiān)視程序的一舉一動,最終經過無數(shù)次的調試編譯,用戶會得到一個正確的程序。步驟七:程序維護與更新。當程序員為自己或者其他人創(chuàng)建了一個程序,這個程序可能得到了廣泛的使用。倘若的確如此,那么程序員大概會有各種各樣的理由去修改它。這或許是因為程序還存在一個細小的缺陷;也許,是程序員想出了一種更好的解決方法來完成程序中的某個功能;或者是為程序添加一個新的功能;或者是需要把程序移植到不同的計算機系統(tǒng)。所有這些任務,如果是在程序有非常清晰的、完整的文檔和遵循合理的設計原則下,那么,實現(xiàn)起來將會簡單得多。程序設計并不總是像我們剛才所述的那樣是一個線性系統(tǒng)。有的時候,用戶將不得不在各個步驟之間來回反復。讀者大多具有輕視步驟一(確定程序目標)和步驟二(設計程序)的傾向,直接進入步驟三(編寫代碼)。讀者最初編寫的程序都很簡單,以至于可以在頭腦里想象出整個過程,一旦發(fā)生錯誤,也容易查清。當程序逐漸變大、變復雜時,思維的可視性開始失效,錯誤隨之難以查找。最后,當忽略計劃步驟的用戶編寫出晦澀難懂的、功能惡化的程序時,就要浪費很多時間,才能讓程序從混亂狀態(tài)中恢復正常。1.8C程序舉例1.8.1舉例1:HelloWorld為了表示對C語言設計人員的敬意,我們介紹的第一個程序來自經典的C著作——《TheCProgrammingLanguage》,由BrianKernighan和DennisRitchie撰寫。該程序的名字為“HelloWorld”,幾乎是所有的學習C語言編程的人都會碰到的、一個無處不在的程序。程序本身(源代碼)是作為一個文件保存在計算機系統(tǒng)的永久性存儲器(如硬盤、U盤)當中的。文件的名字可以是Hello.c,其中后綴.c表示這是一個C程序文件。如圖1.22所示,Hello.c程序由三個部分組成:注釋、庫文件包含和主程序。盡管該程序的功能極其簡單,就是在屏幕上打印輸出"Hello,World"字符串,但是,Hello.c程序的結構非常有代表性,在后續(xù)的程序舉例中,讀者甚至會發(fā)現(xiàn),完全可以把它作為一種C程序的開發(fā)模版或者開發(fā)原型來使用。圖1.22hello.c程序
1.注釋
Hello.c的第一部分是英語注釋,描述了程序的基本功能。在C語言中,只要是包含在“/*”和“*/”這一對標記內的所有的文字都被認為是注釋(Comment)。注釋可以跨越多行,例如,上述Hello.c程序的注釋總共有八行。注釋除了不能出現(xiàn)在關鍵詞、變量名和函數(shù)名字的中間以外,它幾乎可以出現(xiàn)在程序的任何地方。但是,在C語言中,注釋不能出現(xiàn)在其他注釋當中,即注釋不能嵌套(Nested)。這也就意味著注釋當中不能再有其它注釋。一旦編譯器發(fā)現(xiàn)開始標志“/*”,它就忽略后續(xù)的任何字符,直到碰到結束標志“*/”。因此,以下注釋行/*==========/*@@@@@@@@@*/=========*/是無效的和非法的,會導致編譯出錯。注釋是為不同的計算機用戶編寫的,而不是為計算機編寫的。它們主要是對源代碼的用途和含義進行說明,以利于用戶在一段時間后,再回過頭來閱讀這些代碼時能更好地記得和理解它們。這可以幫助編程人員和其他用戶理解程序的功能和操作,也有助于對程序的調試和測試。注釋不影響程序的執(zhí)行速度以及編譯后程序的大小,我們應盡可能在需要的地方對程序進行注釋。C編譯器在把源代碼翻譯成可執(zhí)行程序時,簡單地忽略所有的程序注釋。因此,用戶也可以用注釋臨時移除一行代碼,只要把這行代碼用注釋符號圍起來即可。
2.庫文件包含程序的第二部分包含以下代碼行:
#include<stdio.h>這行代碼表示程序需要使用C語言提供的標準函數(shù)庫(Library)。庫是完成某些特定操作的函數(shù)集合。Hello.c程序使用的庫是一個標準的輸入/輸出庫(stdio是standardinput/output的縮寫)。如果用戶的程序需要使用其他的C語言提供的函數(shù),只要用命令#include把它包含進來即可。庫的使用可以減輕編程人員的負擔,提高軟件的開發(fā)效率。讀者很快會發(fā)現(xiàn),幾乎所有的程序或多或少地需要使用各種庫函數(shù)。以.h結尾的文件我們通常稱為頭文件(HeaderFile)。有關頭文件的內容將在后續(xù)章節(jié)進行詳細討論。
3.主程序
Hello.c文件的最后一部分是程序本身,包含以下代碼行:
main()
{
printf("Hello,World.\n");
}這四行代碼組成了C語言的第一個函數(shù)的例子。這個函數(shù)就是C語言的主函數(shù)——main()函數(shù)。所謂函數(shù),指的是有機組合的單個程序步驟的序列,并給這些序列賦予一個名字,就是函數(shù)的名字。在此例當中,函數(shù)的名字就是第一行給出的main,通常也是所有C程序的標準開頭。函數(shù)要執(zhí)行的步驟則被列于一對花括號之間,通常稱為語句(Statement)。每條語句都必須以分號結束??梢哉f,語句組成了函數(shù)的執(zhí)行體。Hello.c程序的main()函數(shù)只包含一條語句。每次用戶在執(zhí)行一個C程序時,計算機首先執(zhí)行main()函數(shù)內的各條語句。因此main()函數(shù)是惟一一個必須在C程序內出現(xiàn)的函數(shù),且只能有一個main()函數(shù)。在Hello.c程序中,main函數(shù)內只包含一條語句:
printf("Hello,World.\n");這條語句使用了標準輸入/輸出庫當中的printf()函數(shù)。要使用這個函數(shù)必須在程序的開頭部分加入以下代碼:
#include<stdio.h>
printf和main一樣,都是函數(shù)的名字,都表示特定的操作序列。要完成這些操作序列,只要直接使用各自的函數(shù)名即可。在編程環(huán)境下,使用名字來引用函數(shù)的行為被稱為函數(shù)的調用(Call),因此,下列語句
printf("Hello,World.\n");表示調用printf()函數(shù)。在調用函數(shù)時,除了需要有函數(shù)名字表示要執(zhí)行什么操作以外,通常還需要提供額外的一些信息。例如,printf()的功能是在屏幕上顯示數(shù)據,那這些數(shù)據是什么呢?在C語言中,這些額外的數(shù)據是通過函數(shù)名后面的括號當中的參數(shù)(Argument)列表來提供的。這些參數(shù)所提供的信息可以被函數(shù)所使用。在printf()函數(shù)中,只有一個參數(shù),就是字符序列,或者稱為字符串,它們用雙引號括起來,如下:
"Hello,World.\n"這個字符串就是提供給printf()函數(shù)的數(shù)據,它們將最終顯示在計算機屏幕上。對于這個惟一的參數(shù),printf()函數(shù)負責依次顯示H,e,l等字符,直到整條消息都出現(xiàn)在屏幕上為止,如下:
Hello,World.字符串的最后一個字符“\n”是一個特殊字符,稱為換行符(newline)。當printf()函數(shù)碰到一個換行符,屏幕上的光標就會移到下一行的開始,正如在鍵盤上按回車鍵(Return)的效果。在
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年伊利人事考試及答案
- 2025年事業(yè)編b類考試題目及答案
- 2025年人保公司是筆試面試及答案
- 落實審查調查安全各項制度
- 教育干部培訓匯報資料
- 缺少推動落實的剛性制度
- 教育培訓的重要性
- 散文文體知識介紹
- 2025 小學三年級道德與法治上冊班級植物角管理責任分配課件
- 2026年新媒體傳播理論與實踐應用測試題
- 云師大附中 2026 屆高三高考適應性月考(一)-地理試卷(含答案)
- 高中數(shù)學北師大版講義(必修二)第05講1.5正弦函數(shù)、余弦函數(shù)的圖象與性質再認識3種常見考法歸類(學生版+解析)
- 商業(yè)銀行反洗錢風險管理自評估制度研究
- 2025年度法院拍賣合同模板:法院拍賣拍賣保證金退還合同
- 海關特殊監(jiān)管區(qū)域專題政策法規(guī)匯編 2025
- 《膽囊結石伴膽囊炎》課件
- 《浙江省城市體檢工作技術導則(試行)》
- 人教統(tǒng)編版(部編版)小學科學教材目錄
- DB34∕T 1555-2011 存量房交易計稅價格評估技術規(guī)范
- 青少年無人機課程:第一課-馬上起飛
- 煙道安裝服務合同范本
評論
0/150
提交評論