![第9章c語(yǔ)言譚浩強(qiáng)版頂級(jí)講義.ppt_第1頁(yè)](http://file1.renrendoc.com/fileroot_temp2/2020-3/4/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d1.gif)
![第9章c語(yǔ)言譚浩強(qiáng)版頂級(jí)講義.ppt_第2頁(yè)](http://file1.renrendoc.com/fileroot_temp2/2020-3/4/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d2.gif)
![第9章c語(yǔ)言譚浩強(qiáng)版頂級(jí)講義.ppt_第3頁(yè)](http://file1.renrendoc.com/fileroot_temp2/2020-3/4/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d3.gif)
![第9章c語(yǔ)言譚浩強(qiáng)版頂級(jí)講義.ppt_第4頁(yè)](http://file1.renrendoc.com/fileroot_temp2/2020-3/4/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d4.gif)
![第9章c語(yǔ)言譚浩強(qiáng)版頂級(jí)講義.ppt_第5頁(yè)](http://file1.renrendoc.com/fileroot_temp2/2020-3/4/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d/cfbcd336-1e03-40bf-b7f4-7b29cf0b567d5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、9.1宏定義 9.2“文件包含”處理 9.3條件編譯 習(xí)題,第9章 預(yù)處理命令,ANSI C標(biāo)準(zhǔn)規(guī)定可以在C源程序中加入一些“預(yù)處理命令”(preprocessor DireCtiveS) ,以改進(jìn)程序設(shè)計(jì)環(huán)境,提高編程效率。這些預(yù)處理命令是由ANSI C統(tǒng)一規(guī)定的,但是它不是C語(yǔ)言本身的組成部分,不能直接對(duì)它們進(jìn)行編譯(因?yàn)榫幾g程序不能識(shí)別它們)。必須在對(duì)程序進(jìn)行通常的編譯(包括詞法和語(yǔ)法分析、代碼生成、優(yōu)化等)之前,先對(duì)程序中這些特殊的命令進(jìn)行“預(yù)處理”, 即根據(jù)預(yù)處理命令對(duì)程序作相應(yīng)的處理(例如,若程序中用#define命令定義了一個(gè)符號(hào)常量A,則在預(yù)處理時(shí)將程序中所有的A都置換為指定的
2、字符串。若程序中用#inClude命令包含一個(gè)文件“StDio.h”,,則在預(yù)處理時(shí)將StDio.h文件中的實(shí)際內(nèi)容代替該命令)。經(jīng)過預(yù)處理后程序不再包括預(yù)處理命令了,最后再由編譯程序?qū)︻A(yù)處理后的源程序進(jìn)行通常的編譯處理,得到可供執(zhí)行的目標(biāo)代碼?,F(xiàn)在使用的許多C編譯系統(tǒng)都包括了預(yù)處理、編譯和連接等部分,在進(jìn)行編譯時(shí)一氣呵成。因此不少用戶誤認(rèn)為預(yù)處理命令是C語(yǔ)言的一部分,甚至以為它們是C語(yǔ)句,這是不對(duì)的。必須正確區(qū)別預(yù)處理命令和C語(yǔ)句、區(qū)別預(yù)處理和編譯,才能正確使用預(yù)處理命令。C語(yǔ)言與其他高級(jí)語(yǔ)言的一個(gè)重要區(qū)別是可以使用預(yù)處理命令和具有預(yù)處理的功能。,C提供的預(yù)處理功能主要有以下三種: 1. 宏
3、定義 2. 文件包含 3. 條件編譯 分別用宏定義命令、文件包含命令、條件編譯命令來(lái)實(shí)現(xiàn)。為了與一般C語(yǔ)句相區(qū)別,這些命令以符號(hào)“#”開頭。,9.1 宏定義,9.1.1 不帶參數(shù)的宏定義 用一個(gè)指定的標(biāo)識(shí)符(即名字)來(lái)代表一個(gè)字符串,它的一般形式為#define 標(biāo)識(shí)符字符串。這就是已經(jīng)介紹過的定義符號(hào)常量。如:#definePI3.1415926它的作用是指定用標(biāo)識(shí)符PI來(lái)代替“3.1415926”這個(gè)字符串,在編譯預(yù)處理時(shí),將程序中在該命令以后出現(xiàn)的所有的PI都用“3.1415926”代替。這種方法使用戶能以一個(gè)簡(jiǎn)單的名字代替一個(gè)長(zhǎng)的字符串,因此把這個(gè)標(biāo)識(shí)符(名字)稱為“宏名”,在預(yù)編譯時(shí)
4、將宏名替換成字符串的過程稱為“宏展開”。#define是宏定義命令。,例9.1 #define PI3.1415926 main() float l,s,r,v; printf(input raDiuS); scanf(%f, ,運(yùn)行情況如下: input radius:4 l=25.1328 s=50.2655 v=150.7966 說(shuō)明: (1) 宏名一般習(xí)慣用大寫字母表示,以便與變量名相區(qū)別。但這并非規(guī)定,也可用小寫字母。 (2) 使用宏名代替一個(gè)字符串,可以減少程序中重復(fù)書寫某些字符串的工作量。例如,如果不定義PI代表3.1415926,則在程序中要多處出現(xiàn)3.1415926,不僅麻煩
5、,而且容易寫錯(cuò)(或敲錯(cuò)),用宏名代替,,簡(jiǎn)單不易出錯(cuò),因?yàn)橛涀∫粋€(gè)宏名(它的名字往往用容易理解的單詞表示)要比記住一個(gè)無(wú)規(guī)律的字符串容易,而且在讀程序時(shí)能立即知道它的含義,當(dāng)需要改變某一個(gè)常量時(shí),可以只改變#define命令行,一改全改。例如,定義數(shù)組大小,可以用 #define array- size 1000 int arrayarray-size; 先指定array-size代表常量1000,因此數(shù)組array大小為1000,如果需要改變數(shù)組大小,只需改#define行: #define array-size 500 使用宏定義,可以提高程序的通用性。,(3) 宏定義是用宏名代替一個(gè)字符
6、串,也就是作簡(jiǎn)單的置換,不作正確性檢查。如果寫成 #define PI 3.l4l59 即把數(shù)字1寫成小寫字母l,預(yù)處理時(shí)也照樣代入,不管含義是否正確。也就是說(shuō)預(yù)編譯時(shí)不作任何語(yǔ)法檢查。只有在編譯已被宏展開后的源程序時(shí)才會(huì)發(fā)現(xiàn)錯(cuò)誤并報(bào)錯(cuò)。 (4) 宏定義不是C語(yǔ)句,不必在行末加分號(hào)。如果加了分號(hào)則會(huì)連分號(hào)一起進(jìn)行置換。如: #define PI 3.1415926; area=PI*r*r;,經(jīng)過宏展開后,該語(yǔ)句為 area=3.1415926;*r*r; 顯然出現(xiàn)語(yǔ)法錯(cuò)誤。 (5) #define命令出現(xiàn)在程序中函數(shù)的外面,宏名的有效范圍為定義命令之后到本源文件結(jié)束。通常,#define命令
7、寫在文件開頭,函數(shù)之前,作為文件一部分,在此文件范圍內(nèi)有效。 (6) 可以用#undef命令終止宏定義的作用域。例如:,#define g 8.8 main() | G的有效范圍 #undef g f1() 由于#undef的作用,使G的作用范圍在#undef行處終止,因此在f1函數(shù)中,g不再代表8.8。這樣可以靈活控制宏定義的作用范圍。,(7) 在進(jìn)行宏定義時(shí),可以引用已定義的宏名,可以層層置換。 例9.2 #define R 3.0 #define PI3.1415926 #define L2*PI*R #define SPI*R*R main() printf(L=%fns=%fn,L,
8、S); ,運(yùn)行情況如下: L=18.849556 s=28.274333 經(jīng)過宏展開后,printf函數(shù)中的輸出項(xiàng)L被展開為2*3.1415926*3.0,S展開為3.1415926*3.0*3.0,printf函數(shù)調(diào)用語(yǔ)句展開為printf(L=%fns=%fn,2*3.1415926*3.0,3.1415926*3.0*3.0); (8) 對(duì)程序中用雙括號(hào)括起來(lái)的字符串內(nèi)的字符,即使與宏名相同,也不進(jìn)行置換。如例9.2中的printf函數(shù)內(nèi)有兩個(gè)l字符,一個(gè)在雙引號(hào)內(nèi),它不被宏置換,另一個(gè)在雙引號(hào)外,被宏置換展開。,(9) 宏定義是專門用于預(yù)處理命令的一個(gè)專用名詞,它與定義變量的含義不同,
9、只作字符替換,不分配內(nèi)存空間。 9.1.2帶參數(shù)的宏定義 不是進(jìn)行簡(jiǎn)單的字符串替換,還要進(jìn)行參數(shù)替換。其定義的一般形式為 #define宏名(參數(shù)表)字符串 字符串中包含在括弧中所指定的參數(shù)。如: #defines(a,b)a*b area=s(3,2);,定義矩形面積S,a和B是邊長(zhǎng)。在程序中用了s(3,2),把3、2分別代替宏定義中的形式,圖9.1,參數(shù)a、b,即用3*2代替s(3,2)。因此賦值語(yǔ)句展開為area=3*2; 對(duì)帶參的宏定義是這樣展開置換的:在程序中如果有帶實(shí)參的宏(如S(3,2),則按#define命令行中指定的字符串從左到右進(jìn)行置換。如果串中包含宏中的形參(如a、b),
10、則將程序語(yǔ)句中相應(yīng)的實(shí)參(可以是常量、變量或表達(dá)式)代替形參,如果宏定義中的字符串中的字符不是參數(shù)字符(如a*b中的*號(hào)),則保留。這樣就形成了置換的字符串,見圖9.1。,例9.3 #definePI3.1415926 #defineS(r)PI*r*r main() float a,area; a=3.6; area=S(a); printf(r=%fnarea=%fn,a,area); 運(yùn)行結(jié)果如下: r=3.600000 area=40.715038,賦值語(yǔ)句area=s(a);經(jīng)宏展開后為 area=3.1415926*a*a; 說(shuō)明: (1) 對(duì)帶參數(shù)的宏的展開只是將語(yǔ)句中的宏名后面
11、括號(hào)內(nèi)的實(shí)參字符串代替#define命令行中的形參。例9.3中語(yǔ)句中有S(a),在展開時(shí),找到#define命令行中的S(r),將S(a)中的實(shí)參a代替宏定義中的字符串“PI*r*r”中的形參r,得到PI*a*a。這是容易理解而且不會(huì)發(fā)生什么問題的。但是,如果有以下語(yǔ)句:area=S(a+B);這時(shí)把實(shí)參a+B代替PI*r*r中的形參r,成為area=PI*a+B*a+B;請(qǐng)注意在a+B外面沒有括弧,顯然這與程序設(shè)計(jì)者的原意不符。原意希望得到,area=PI*(a+B)*(a+B);為了得到這個(gè)結(jié)果,應(yīng)當(dāng)在定義時(shí),在字符串中的形式參數(shù)外面加一個(gè)括弧。即#define S(r) PI*(r)*(
12、r)在對(duì)S(a+B)進(jìn)行宏展開時(shí),將a+B代替r,就成了PI*(a+B)*(a+B)這就達(dá)到了目的。 (2) 在宏定義時(shí),在宏名與帶參數(shù)的括弧之間不應(yīng)加空格,否則將空格以后的字符都作為替代字符串的一部分。例如,如果有 #define s (r)PI*r*r 被認(rèn)為s是符號(hào)常量(不帶參的宏名),它代表字符串“(r) PI*r*r”。如果在語(yǔ)句中有area=S (a); 則被展開為 area=(r) PI*r*r (a) 顯然不對(duì)了。,有些讀者容易把帶參數(shù)的宏和函數(shù)混淆。的確,它們之間有一定類似之處,在引用函數(shù)時(shí)也是在函數(shù)名后的括弧內(nèi)寫實(shí)參,也要求實(shí)參與形參的數(shù)目相等。但是帶參的宏定義與函數(shù)是不同
13、的。主要有: (1) 函數(shù)調(diào)用時(shí),先求出實(shí)參表達(dá)式的值,然后代入形參。而使用帶參的宏只是進(jìn)行簡(jiǎn)單的字符替換。例如上面的S(a+b),在宏展開時(shí)并不求a+B的值,而只將實(shí)參字符“a+b”代替形參r。 (2) 函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,分配臨時(shí)的內(nèi)存單元。而宏展開則是在編譯時(shí)進(jìn)行的,在展開時(shí)并不分配內(nèi)存單元,不進(jìn)行值的傳遞處理,也沒有“返回值”的概念。,(3) 對(duì)函數(shù)中的實(shí)參和形參都要定義類型,二者的類型要求一致,如不一致,應(yīng)進(jìn)行類型轉(zhuǎn)換。而宏不存在類型問題,宏名無(wú)類型,它的參數(shù)也無(wú)類型,只是一個(gè)符號(hào)代表,展開時(shí)代入指定的字符即可。宏定義時(shí),字符串可以是任何類型的數(shù)據(jù)。例如: #defineC
14、HAR1CHINA(字符) #definea 3.6 (數(shù)值) CHAR1和a不需要定義類型,它們不是變量,在程序中凡遇CHAR1均以CHINA代之;凡遇a均以3.6代之,顯然不需定義類型。同樣,對(duì)帶參的宏: #defineS(r)PI*r*r,r也不是變量,如果在語(yǔ)句中有S(3.6),則展開后為PI*3.6*3.6,語(yǔ)句中并不出現(xiàn)r。當(dāng)然也不必定義r的類型。 (4) 調(diào)用函數(shù)只可得到一個(gè)返回值,而用宏可以設(shè)法得到幾個(gè)結(jié)果。 例9.4 #definePI3.1415926 #define CIRCLE(r,l,s,v)L=2*PI*R;S=PI*R*R;=4.0/3.0*PI*R*R*R ma
15、in() float r,l,s,v;,scanf(%f,,printf(r=%6.2f,l=%6.2f,S=%6.2f,v=%6.2fn,r,l,S,v); 運(yùn)行情況如下: 3.5 r=3.50,l= 21.99,S= 38.48,v= 179.59 請(qǐng)注意,實(shí)參r的值已知,可以從宏帶回3個(gè)值(l,S,v)。其實(shí),只不過是字符代替而已,將字符r代替R,l代替L,S代替S,v代替,而并未在宏展開時(shí)求出l、S、v的值。,(5) 使用宏次數(shù)多時(shí),宏展開后源程序長(zhǎng),因?yàn)槊空归_一次都使程序增長(zhǎng),而函數(shù)調(diào)用不使源程序變長(zhǎng)。 (6) 宏替換不占運(yùn)行時(shí)間,只占編譯時(shí)間。而函數(shù)調(diào)用則占運(yùn)行時(shí)間(分配單元、保留
16、現(xiàn)場(chǎng)、值傳遞、返回)。 一般用宏來(lái)代表簡(jiǎn)短的表達(dá)式比較合適。有些問題,用宏和函數(shù)都可以。如: #define MAX(x,y)(x)(y)?(x)(y) main() int a,b,c,d,t; ,t=MAX(a+b,c+d); 賦值語(yǔ)句展開后為 t=(a+b)(c+d)?(a+b)(c+d); 注意:MAX不是函數(shù),這里只有一個(gè)main函數(shù),在main函數(shù)中就能求出t的值。 這個(gè)問題也可用函數(shù)來(lái)求: int max(int x,int y) return(xy?xy); main(),int a,B,C,D,t; t=max(a+B,C+D); max是函數(shù),在main函數(shù)中調(diào)用max函數(shù)
17、才能求出t的值。 請(qǐng)仔細(xì)分析以上兩種方法。 如果善于利用宏定義,可以實(shí)現(xiàn)程序的簡(jiǎn)化,如事先將程序中的“輸出格式”定義好,以減少在輸出語(yǔ)句中每次都要寫出具體的輸出格式的麻煩。,例9.5 #define PR printf #define NL n #define D %D #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %S main() int a,B,C,D; char string=CHINA; a=1;B=2;C=3;D=4;,PR(D1,a); PR(D2,a,B
18、); PR(D3,a,B,C); PR(D4,a,B,C,D); PR(S,string); 運(yùn)行時(shí)輸出以下結(jié)果: 1 12 123 1234 CHINA,程序中用PR代表printf。以NL代表執(zhí)行一次“換行”操作。以D代表輸出一個(gè)整型數(shù)據(jù)的格式符。以D1代表輸出完1個(gè)整數(shù)后換行,D2代表輸出2個(gè)整數(shù)后換行,D3代表輸出3個(gè)整數(shù)后換行,D4代表輸出4個(gè)整數(shù)后換行。以S代表輸出一個(gè)字符串的格式符??梢钥吹?,程序中寫輸出語(yǔ)句就比較簡(jiǎn)單了,只要根據(jù)需要選擇已定義的輸出格式即可,連printf都可以簡(jiǎn)寫為PR。 可以參照例9.5,寫出各種輸入輸出的格式(例如實(shí)型、長(zhǎng)整型、十六進(jìn)制整數(shù)、八進(jìn)制整數(shù)、字
19、符型等),把它們單獨(dú)編成一個(gè)文件,它相當(dāng)一個(gè)“格式庫(kù)”,用#inClude命令把它“包括”到自己所編的程序中,用戶就可以根據(jù)情況各取所需了。,顯然在寫大程序時(shí),這樣做是很方便的。 9.2 “文件包含”處理 所謂“文件包含”處理是指一個(gè)源文件可以將另外一個(gè)源文件的全部?jī)?nèi)容包含進(jìn)來(lái),即將另外的文件包含到本文件之中。C語(yǔ)言提供了#inClude命令用來(lái)實(shí)現(xiàn)“文件包含”的操作。其一般形式為 #inClude “文件名” 或 #inClude ,圖9.2 圖9.2表示“文件包含”的含意。圖9.2(a)為文件file1.C,它有一個(gè)#inClude 命令,然后還有其他內(nèi)容(以A表示)。圖9.2(B)為另一
20、文件file2.C,文件內(nèi)容以B表示。在編譯預(yù)處理時(shí),要對(duì)#inClude命令進(jìn)行“文件包含”處理:將file2.C的全部?jī)?nèi)容復(fù)制插入,到#inClude 命令處,即file2.C被包含到file1.C中,得到圖9.2(C)所示的結(jié)果。在編譯中,將“包含”以后的file1.C(即圖9.2(C)所示)作為一個(gè)源文件單位進(jìn)行編譯。 “文件包含”命令是很有用的,它可以節(jié)省程序設(shè)計(jì)人員的重復(fù)勞動(dòng)。例如,某一單位的人員往往使用一組固定的符號(hào)常量(如G=9.81,pi=3.1415926,e=2.718,C=),可以把這些宏定義命令組成一個(gè)文件,然后各人都可以用#inClude命令將這些符號(hào)常量包含到自己
21、所寫的源文件中。這樣每個(gè)人就可以不必重復(fù)定義這些符號(hào)常量。相當(dāng)于工業(yè)上的標(biāo)準(zhǔn)零件,拿來(lái)就用。,例9.6可以將例9.5程序改為: (1) 文件format.h #define PRprintf #define NLn #define D%D #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %S,(2) 文件file1.C #inClude format.h main() int a,B,C,D; char string=CHINA; a=1;B=2;C=3;D=4; PR(
22、D1,a); PR(D2,a,B); PR(D3,a,B,C); PR(D4,a,B,C,D); PR(S,string); ,注意: 在編譯時(shí)并不是作為兩個(gè)文件進(jìn)行連接的,而是作為一個(gè)源程序編譯,得到一個(gè)目標(biāo)(.oBj)文件。因此被包含的文件也應(yīng)該是源文件而不應(yīng)該是目標(biāo)文件。 這種常用在文件頭部的被包含的文件稱為“標(biāo)題文件”或“頭部文件”,常以“h”為后綴(h為heaD(頭)的縮寫),如“format.h”文件。當(dāng)然不用“.h”為后綴,而用“C”為后綴或者沒有后綴也是可以的,但用“h”作后綴更能表示此文件的性質(zhì)。 如果需要修改一些常數(shù),不必修改每個(gè)程序,只需修改一個(gè)文件(頭部文件)即可。但是
23、應(yīng)當(dāng)注意,被包含文件修改后,凡包含此文件的所有文件都要全部重新編譯。,頭文件除了可以包括函數(shù)原型和宏定義外,也可以包括結(jié)構(gòu)體類型定義(見第10章)和全局變量定義等。 說(shuō)明: (1) 一個(gè)inClude命令只能指定一個(gè)被包含文件,如果要包含n個(gè)文件,要用n個(gè)inClude命令。 (2) 如果文件1包含文件2,而文件2中要用到文件3的內(nèi)容,則可在文件1中用兩個(gè)inClude命令分別包含文件2和文件3,而且文件3應(yīng)出現(xiàn)在文件2之前,即在file1.C中定義: #inClude file3.h #inClude file2.h,這樣,file1和file2都可以用file3的內(nèi)容。在file2中不必再
24、用#inClude 了(以上是假設(shè)file2.h在本程序中只被file1.C包含,而不出現(xiàn)在其他場(chǎng)合)。 (3) 在一個(gè)被包含文件中又可以包含另一個(gè)被包含文件,即文件包含是可以嵌套的。例如,上面的問題也可以這樣處理,見圖9.3。它的作用與圖9.4所示相同。,圖9.3,圖9.4 (4) 在#inClude命令中,文件名可以用雙引號(hào)或尖括號(hào)括起來(lái),如可以在file1.C中用 #inClude 或#inClude file2.h都是合法的。二者的區(qū)別是用尖括弧(即形式)時(shí),系統(tǒng)到存放C庫(kù)函數(shù)頭文件所在的目錄中尋找要包含的文件,這稱為標(biāo)準(zhǔn)方式。用雙引號(hào)(即“file2.h”形式)時(shí),系統(tǒng)先在用戶當(dāng)前目
25、錄中尋找要包含的文件,若找不到,再按標(biāo),準(zhǔn)方式查找(即再按尖括號(hào)的方式查找)。一般說(shuō),如果為調(diào)用庫(kù)函數(shù)而用#inClude命令來(lái)包含相關(guān)的頭文件,則用尖括號(hào),以節(jié)省查找時(shí)間。如果要包含的是用戶自己編寫的文件(這種文件一般都在當(dāng)前目錄中),一般用雙引號(hào)。 (5) 被包含文件(file2.h)與其所在的文件(即用#inClude命令的源文件file1.C),在預(yù)編譯后已成為同一個(gè)文件(而不是兩個(gè)文件)。因此,如果file2.h中有全局靜態(tài)變量,它也在file1.C文件中有效,不必用extern聲明。,9.3 條件編譯 一般情況下,源程序中所有的行都參加編譯。但是有時(shí)希望對(duì)其中一部分內(nèi)容只在滿足一定
26、條件才進(jìn)行編譯,也就是對(duì)一部分內(nèi)容指定編譯的條件,這就是“條件編譯”。有時(shí),希望當(dāng)滿足某條件時(shí)對(duì)一組語(yǔ)句進(jìn)行編譯,而當(dāng)條件不滿足時(shí)則編譯另一組語(yǔ)句。 條件編譯命令有以下幾種形式: (1) #ifdef標(biāo)識(shí)符 程序段1 #else 程序段2 #endif,它的作用是當(dāng)所指定的標(biāo)識(shí)符已經(jīng)被#define命令定義過,則在程序編譯階段只編譯程序段1,否則編譯程序段2。其中#else部分可以沒有,即#ifdef標(biāo)識(shí)符程序段1#endif這里的“程序段”可以是語(yǔ)句組,也可以是命令行。這種條件編譯對(duì)于提高C源程序的通用性是很有好處的。如果一個(gè)C源程序在不同計(jì)算機(jī)系統(tǒng)上運(yùn)行,而不同的計(jì)算機(jī)又有一定的差異(例如
27、,有的機(jī)器以16位(2個(gè)字節(jié))來(lái)存放一個(gè)整數(shù),而有的則以32位存放一個(gè)整數(shù)),這樣往往需要對(duì)源程序作必要的修改,這就降低了程序的通用性??梢杂靡韵碌臈l件編譯來(lái)處理:,#ifdefCOMPUTER-A #defineINTEGER-SIZE 16 #else #defineINTEGER-SIZE 32 #endif 即如果COMPUTER-A 在前面已被定義過,則編譯下面的命令行: #define INTEGER-SIZE 16 否則,編譯下面的命令行: #define INTEGER-SIZE 32 如果在這組條件編譯命令之前曾出現(xiàn)以下命令行: #define COMPUTER-A 0,或?qū)?/p>
28、COMPUTER-A定義為任何字符串,甚至是#define COMPUTER-A則預(yù)編譯后程序中的INTEGER-SIZE都用16代替,否則都用32代替。 這樣,源程序可以不必作任何修改就可以用于不同類型的計(jì)算機(jī)系統(tǒng)。當(dāng)然以上介紹的只是一種簡(jiǎn)單的情況,讀者可以根據(jù)此思路設(shè)計(jì)出其他的條件編譯。 例如,在調(diào)試程序時(shí),常常希望輸出一些所需的信息,而在調(diào)試完成后不再輸出這些信息??梢栽谠闯绦蛑胁迦胍韵碌臈l件編譯段: #ifdef DEBUG printf(x=%D,y=%D,Z=%Dn,x,y,Z);,#endif 如果在它的前面有以下命令行: #define DEBUG 則在程序運(yùn)行時(shí)輸出x、y、Z
29、的值,以便調(diào)試時(shí)分析。調(diào)試完成后只需將這個(gè)define命令行刪去即可。有人可能覺得不用條件編譯也可達(dá)此目的,即在調(diào)試時(shí)加一批printf語(yǔ)句,調(diào)試后一一將printf語(yǔ)句刪去。的確,這是可以的。但是,當(dāng)調(diào)試時(shí)加的printf語(yǔ)句比較多時(shí),修改的工作量是很大的。用條件編譯,則不必一一刪改printf語(yǔ)句,只需刪除前面的一條“#define DEBUG”命令即可,這時(shí)所有的用DEBUG作標(biāo)識(shí)符的條件編譯段都使其中的printf語(yǔ)句不起作用,即起統(tǒng)一控制的作用,如同一個(gè)“開關(guān)”一樣。,(2) #ifndef標(biāo)識(shí)符 程序段1 #else 程序段2 #endif 只是第一行與第一種形式不同:將“ifde
30、f”改為“ifndef”。它的作用是若標(biāo)識(shí)符未被定義過則編譯程序段1,否則編譯程序段2。這種形式與第一種形式的作用相反。,以上兩種形式用法差不多,根據(jù)需要任選一種,視方便而定。例如,上面調(diào)試時(shí)輸出信息的條件編譯段也可以改為 #ifndef RUN printf(x=%D,y=%D,Z=%Dn,x,y,Z); #endif 如果在此之前未對(duì)RUN定義,則輸出x、y、Z的值。調(diào)試完成后,在運(yùn)行之前,加以下命令行: #define RUN 則不再輸出x、y、Z的值。,(3) #if表達(dá)式 程序段1 #else 程序段2 #endif 它的作用是當(dāng)指定的表達(dá)式值為真(非零)時(shí)就編譯程序段1,否則編譯程
31、序段2??梢允孪冉o定一定條件,使程序在不同的條件下執(zhí)行不同的功能。 例9.7輸入一行字母字符,根據(jù)需要設(shè)置條件編譯,使之能將字母全改為大寫輸出,或全改為小寫字母輸出。,#define LETTER1 main() char str20=CLanGuaGe,C; int i; i=0 while(C=stri)!=0) i+; #if LETTER 條件編譯 if(C=a #endif,printf(%C,C); 運(yùn)行結(jié)果為: CLANGUAGE 現(xiàn)在先定義LETTER為1,這樣在對(duì)條件編譯命令進(jìn)行預(yù)處理時(shí),由于LETTER為真(非零),則對(duì)第一個(gè)if語(yǔ)句進(jìn)行編譯,運(yùn)行時(shí)使小寫字母變大寫。如果將程序第一行改為#defineLETTER0則在預(yù)處理時(shí),對(duì)第二個(gè)if語(yǔ)句進(jìn)行編譯處理,使大寫字母變成小寫字母(大寫字母與相應(yīng)的小寫字母ASCII代碼差32)。此時(shí)運(yùn)行情況為ClanGuaGe,有的讀者可能會(huì)問,不用條件編譯命令而直接用if語(yǔ)句也能達(dá)到要求,用條件編譯命令有什么好處呢?的確,此問題完全可以不用條件編譯
溫馨提示
- 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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度新型起重機(jī)專利許可及銷售代理合同
- 合作房地產(chǎn)開發(fā)協(xié)議(28篇)
- 師傅和徒弟作文
- 2025年兼職工勞務(wù)合同格式
- 2025年企業(yè)合作投資與合資合同
- 2025年信用卡預(yù)借現(xiàn)金協(xié)議書范本
- 2025年中尺度自動(dòng)氣象站系統(tǒng)項(xiàng)目立項(xiàng)申請(qǐng)報(bào)告
- 2025年區(qū)域飲品代理合作協(xié)議范本
- 2025年式多功能打印機(jī)銷售合同規(guī)范
- 2025年企業(yè)電力安全使用標(biāo)準(zhǔn)協(xié)議書
- 2025年中考物理終極押題猜想(新疆卷)(全解全析)
- 1《讀懂彼此的心》(說(shuō)課稿)2023-2024學(xué)年統(tǒng)編版道德與法治五年級(jí)下冊(cè)
- DB32T 2857-2015 玉米產(chǎn)量現(xiàn)場(chǎng)測(cè)定操作規(guī)程
- 脛骨骨折的護(hù)理查房
- 房顫手術(shù)后護(hù)理流程
- 2024版質(zhì)量管理培訓(xùn)
- 校車駕駛員照管員培訓(xùn)
- 高中師德師風(fēng)培訓(xùn)
- 電動(dòng)工具培訓(xùn)課件
- 建筑總工程師招聘面試題與參考回答2025年
- 房地產(chǎn)市場(chǎng)報(bào)告-沙特阿拉伯房地產(chǎn)簡(jiǎn)介 202411
評(píng)論
0/150
提交評(píng)論