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