c語(yǔ)言基礎(chǔ)教程第六章預(yù)處理功能和類型定義_第1頁(yè)
c語(yǔ)言基礎(chǔ)教程第六章預(yù)處理功能和類型定義_第2頁(yè)
c語(yǔ)言基礎(chǔ)教程第六章預(yù)處理功能和類型定義_第3頁(yè)
c語(yǔ)言基礎(chǔ)教程第六章預(yù)處理功能和類型定義_第4頁(yè)
c語(yǔ)言基礎(chǔ)教程第六章預(yù)處理功能和類型定義_第5頁(yè)
已閱讀5頁(yè),還剩16頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第六章預(yù)處理功能和類型定義6. 1 預(yù)處理功能概述 本節(jié)主要講述預(yù)處理功能的特點(diǎn)。 預(yù)處理功能是由很多預(yù)處理命令組成,這些命令將在編譯時(shí)進(jìn)行通常的編譯功能包含詞法和語(yǔ)法分析、代碼生成、優(yōu)化等之前進(jìn)行處理,故稱為預(yù)處理.預(yù)處理后的結(jié)果和源程序一起再進(jìn)行通常的編譯操作,進(jìn)而得到目標(biāo)代碼。 預(yù)處理功能主要包括如下三種;宏定義、文件包含和條件編譯。 這些功能是通過(guò)相應(yīng)的宏定義命令、文件包含命令和條件編譯命令來(lái)實(shí)現(xiàn)。這些命令不同于C語(yǔ)言的語(yǔ)句,因?yàn)樗鼈兙哂腥缦碌奶攸c(diǎn): (1)多數(shù)預(yù)處理命令只是一種替代的功能,這種替代是簡(jiǎn)單的替換,而不進(jìn)行語(yǔ)法檢查。 (2)預(yù)處理命令都是在通常的編譯之前進(jìn)行的,編譯時(shí)已經(jīng)

2、執(zhí)行完了預(yù)處理命令,即對(duì)預(yù)處理后的結(jié)果進(jìn)行編譯,這時(shí)進(jìn)行詞法和語(yǔ)法分析等通常的程序編譯。 (3)預(yù)處理命令后面不加分號(hào),這也是在形式_七與語(yǔ)句的區(qū)別。 (4)為了使預(yù)處理命令與一般C語(yǔ)言語(yǔ)句相區(qū)別,凡是預(yù)處理命令都以井號(hào)(#)開頭。 (5)多數(shù)預(yù)處理命令根據(jù)它的功能而被放在文件開頭為宜,但是根據(jù)需要,也可以放到文件的其他位置。不要產(chǎn)生錯(cuò)覺,好像所有的預(yù)處理命令都必須放在文件開頭。 學(xué)習(xí)和掌握預(yù)處理功能時(shí),應(yīng)該了解它的上述規(guī)定,以便正確地使用和理解這些預(yù)處理命令。6.2.1 簡(jiǎn)單宏定義1.簡(jiǎn)單宏定義的格式和功能 簡(jiǎn)單宏定義的格式如下: #define標(biāo)識(shí)符)(字符串 其中,define是關(guān)鍵字,

3、它表示該命令為宏定義,悅標(biāo)識(shí)符)是宏名,它的寫法同標(biāo)識(shí)符。用來(lái)表示所代表的字符串。 簡(jiǎn)單宏定義是定義一個(gè)標(biāo)識(shí)符(宏名)來(lái)代表一個(gè)字符串。 前面講過(guò)的符號(hào)常量就是用這種簡(jiǎn)單宏定義來(lái)實(shí)現(xiàn)的。例如: #define PI 3. 這是一條宏定義的命令,它的作用是用指定的標(biāo)識(shí)符PI來(lái)代替字符串3.在程序中出現(xiàn)的是PI,在編譯前預(yù)處理時(shí),將所有的PI都用3. 來(lái)代替,即使用宏名來(lái)代替指定的字符串。這一過(guò)程又稱為宏替換或稱為宏展開.例6.1給出半徑求圓的面積。 執(zhí)行該程序,出現(xiàn)如下信息:#dfine PI 3.main ( ) fioat r, s, Printf(Input radius;) scanf(

4、%f,&r); A=PI *r*rPrintf(:a=%.4fn:,a);執(zhí)行該程序,出現(xiàn)如下信息:Input radius; 5 輸出結(jié)果如下 s=78. 5398 說(shuō)明:該例中,開始率義了符號(hào)常量PI,它是用宏定義來(lái)實(shí)現(xiàn)的。程序中出現(xiàn)的PI,在編譯前預(yù)處理時(shí)將用3.來(lái)替換。 2.使用簡(jiǎn)單宏定義時(shí)的注意事項(xiàng) (1)宏定義中的標(biāo)識(shí)符)(即宏名)一般習(xí)慣用大寫字母,以便與變量名區(qū)別。這樣。在C語(yǔ)言程序的各表達(dá)式語(yǔ)句中,凡是大寫字母的標(biāo)識(shí)符(指全部大寫字母)一般是符號(hào)常量。但是,宏定義中的宏名也可以用小寫字母。 (2)宏定義是預(yù)處理功能中的一種命令,它不是語(yǔ)句。因此。行末不需加分號(hào)。如果加了分號(hào),

5、則該分號(hào)將作為所定義的字符串的一部分,即按字符串的一部分來(lái)處理。 (3)宏替換是一種簡(jiǎn)單的代替,替換時(shí)不作語(yǔ)法檢查。如果所定義的字符申中有錯(cuò),例如,將數(shù)字。,誤寫為字母。,預(yù)處理照樣代換,并不報(bào)錯(cuò),而在編譯中進(jìn)行語(yǔ)法檢查時(shí)才報(bào)錯(cuò)。因此,要記住宏替換操作只是簡(jiǎn)單的代換,用宏定義時(shí)的字符串來(lái)替換其宏名。 (4)宏定義中宏名的作用域?yàn)槎x該命令的文件中,并從定義時(shí)起,到終止宏定義命令( #undef() 其甲,是標(biāo)識(shí)符,一般習(xí)慣上用大寫字母,是由一個(gè)或多個(gè)參數(shù)組成的,多個(gè)參數(shù)之間用逗號(hào)分隔;(宏體)是一個(gè)字符串,其中包含中所指定的參數(shù),它可以是由若干個(gè)語(yǔ)句組成的。該命令末尾一般不加分號(hào)。 帶參數(shù)的宏

6、定義在宏替換時(shí)。不是簡(jiǎn)單的用宏體替換宏名,而是用實(shí)參替換形參.這里所說(shuō)的實(shí)參是指程序中引用宏名的參數(shù),而形參是指宏定義時(shí),宏名后邊參數(shù)表中的參數(shù)。 例如, #define sQ(x)x*x 在程序中出現(xiàn)下述語(yǔ)句: A=SQ(5); 這里,在宏定義中參數(shù)x是形參,而程序中SQ(5)的S是實(shí)參,宏替換時(shí),將用5來(lái)替換x,其結(jié)果如下: a=5 * 5; 又例如, #define ADD(x,y) x十Y 在程序中出現(xiàn)下述語(yǔ)句; A=ADD(5,3); 宏替換后結(jié)果如下: a=5十3; 如果在上述宏定義下,程序中出現(xiàn)如下語(yǔ)句; b=ADD(a+1,b一1); 宏替換后結(jié)果如下: B=a+1+b-1 由

7、此可見,帶參數(shù)的宏定義是這樣替換的:按照宏定義中所指定的宏體從左至右用程序中出現(xiàn)的宏的實(shí)參來(lái)替換宏體中的形參,對(duì)非參數(shù)字符,則保留。宏中的實(shí)參可以是常量、變量或表達(dá)式。2.使用帶參數(shù)的宏定義應(yīng)該注意的事項(xiàng) (1)在宏定義時(shí),宏名與左圓括號(hào)之間不能出現(xiàn)空格符,否則空格符后將作為宏體的一部分。例如: #define ADD (x,y) x十Y 將認(rèn)為ADD是不帶參數(shù)的宏名,而字符串(x, y) x+y作為宏體。顯然,這不是原來(lái)的含意。因此,宏名后與左圓括號(hào)間一定不能加空格符。 (2)宏體中,各參數(shù)上加括號(hào)是十分重要的。例如: #define SQ(x) x*x 當(dāng)程序中出現(xiàn)下列語(yǔ)句, A=SQ(a

8、十1); 替換后,則為; a=a+1*a+1 而不能將替換的結(jié)果寫成 a=(a十1)*(a+1); 如果要將替換后結(jié)果寫成上述形式,則需要將宏定義改寫為: #define SQ(x) (x),(x) 由此可見,在宏定義中,對(duì)宏體內(nèi)的形參外向加上括號(hào)是很重要的,它可以避免在優(yōu)先級(jí)上可能出現(xiàn)的問(wèn)題。 對(duì)上述宏定義最好寫成下述形式: #define SQ(x)(.x)*(x ) 這里的圓括號(hào)是很有用的。例如,在有如下語(yǔ)句時(shí), m=50/SQ(b十1); 替換后結(jié)果如下: m= 50/(b十1)*(b+1); (3)帶參數(shù)的宏定義與函數(shù)的區(qū)別 帶參數(shù)的宏定義和函數(shù)盡管在形式上非常相似,特別是當(dāng)宏名使用

9、小寫字母時(shí),出現(xiàn)在程序中很難區(qū)別出來(lái)是帶參數(shù)的宏定義還是函數(shù)。但是,這二者是根本不同,它們之間的區(qū)別概述如下: 定義形式上不同。帶參數(shù)的宏定義的定義格式前面講過(guò)了,它是通過(guò)預(yù)處理命令ce-fine來(lái)定義的。它的作用域是在定義它的文件內(nèi),并從定義處開始。而函數(shù)的定義格式在本書函數(shù)和存儲(chǔ)類1章中描述過(guò)了。它的作用域分為程序級(jí)的和文件級(jí)的兩種。 處理時(shí)間上不同。宏定義是在編譯預(yù)處理時(shí)處理的,處理后再進(jìn)行編譯。而函數(shù)是在執(zhí)行時(shí)處理的。它們二者占用的是不同階段的時(shí)間。 處理方式_卜。不同。帶參數(shù)的宏定義在進(jìn)行宏替換時(shí),用實(shí)參來(lái)代替形參,這里只是簡(jiǎn)單替換,并不做語(yǔ)法上的檢查。而函數(shù)調(diào)用時(shí),是將實(shí)參的值賦給

10、形參,要求對(duì)應(yīng)類型一致。宏定義中在參數(shù)替換時(shí),不要求類型一致仁 時(shí)間和空間的開銷上不同。帶參數(shù)的宏定義,是在通常的編譯之前完成替換的,因此它在該程序的目標(biāo)代碼的形成上并沒(méi)有影響。函數(shù)調(diào)用是在執(zhí)行時(shí)進(jìn)行的,因此,采用函數(shù)調(diào)用的方式可以減少該程序的目標(biāo)代碼,所以,在空間的開銷上可以減少。但是,函數(shù)調(diào)用要有額外的時(shí)間上的開銷。因?yàn)檎{(diào)用前要保留現(xiàn)場(chǎng),調(diào)用后又要恢復(fù)現(xiàn)場(chǎng),因此函數(shù)調(diào)用時(shí)間開銷要比帶參數(shù)的宏定義大。帶參數(shù)宏定義在使用中比函數(shù)時(shí)間開銷小是一個(gè)重要特征。 類型的要求上不同。帶參數(shù)的宏定義對(duì)形參的類型不必說(shuō)明,它沒(méi)有類型的限制。而函數(shù)的形參在定義時(shí)必須進(jìn)行類型說(shuō)明。例如,兩個(gè)數(shù)相減的操作用帶參數(shù)

11、的宏定義和函數(shù)分別定義如下: 用帶參數(shù)的宏定義格式如下: 抹define MINU (x,y)(x)一(Y) 用函數(shù)的定義格式如下: minu(x,y) Int x,y ( return (x一y); 該函數(shù)只能進(jìn)行兩個(gè)lnl型數(shù)值相減的運(yùn)算。而。上述的宏定義可以進(jìn)行兩個(gè)。har型量的相減,也可以進(jìn)行兩個(gè)int型數(shù)的相減。還可以進(jìn)行兩float型數(shù)的相減,因?yàn)樗鼪](méi)有類型的限制通過(guò)上述對(duì)于帶參數(shù)的宏定義和函數(shù)之間區(qū)別的分析,不難看出兩者各有特點(diǎn)。對(duì)于同一個(gè)間題一可以采用兩種不同的表示形式,那么到底選擇哪一種更好些呢?一般說(shuō)來(lái),在功能比較簡(jiǎn)單的情況一下,選用帶參數(shù)的玄定義能更好些,特別是在需要反復(fù)

12、引用的情況下,用宏定義的時(shí)間開銷較少。例如,比較兩個(gè)整數(shù)的大小,并輸出最大的,可用如下的宏定義來(lái)實(shí)現(xiàn): #define fl(a,b)printf(%dn,ab?;b); 又例如,計(jì)算一個(gè)自然數(shù)的立方值,可用如下的宏定義實(shí)現(xiàn): #define f2(a)printi%dn,a*a*a); 功能比較復(fù)雜的還是選用函數(shù)來(lái)定義。6.2.3 宏定義的應(yīng)用 在C語(yǔ)言程序中,宏定義主要用于下述幾個(gè)方面。 (1)符號(hào)常聳的定義 C語(yǔ)言中的常覺一般都用符號(hào)常量表示,這樣不僅書寫簡(jiǎn)便,而且易于修改、易于移植,還可以使標(biāo)識(shí)符有更明顯的含意。例如, #define PI 3. #define E 2.71828 #

13、define EPS 1.0e一9 #define MAX 32767 #define TRUE 1 #define FALSE 0 等等。 (2)功能簡(jiǎn)單使用頻繁的情況卜,用帶參數(shù)的宏定義比用函數(shù)可以提高速度。因?yàn)楹瘮?shù)調(diào)用要花費(fèi)額外的時(shí)間開銷。 (3)在多數(shù)情況下,為了書寫簡(jiǎn)練,程序易讀而采用宏定義例6.4分析下列程序輸出結(jié)果,并說(shuō)明宏定義在該程序中所起的作用。 #define F1%dn #define F2%d,%dn #define PRl(a)print3(1,a) #define PR2t(a.b) print(F2,a,b); main) int x+y,z; x=5; y=5*

14、x; z=x*y; PR1(x); PR2(y,z); PR1(2,y); PR2(x+5,z/5) 執(zhí)行該程序輸出的結(jié)果如下: 5 25.30 50 10.6 說(shuō)明: (1)該程序前面有4條宏定義命令。前兩條是簡(jiǎn)單宏定義,后兩條是帶參數(shù)的宏定義。這4條宏定義命令都是有關(guān)標(biāo)準(zhǔn)文件的格式輸出的。 (2)程序中的最后4條語(yǔ)句是輸出顯示結(jié)果的語(yǔ)句,由于引用了宏定義命令,使得該輸出語(yǔ)句簡(jiǎn)練、清晰。由于在C語(yǔ)言程序中,輸出顯示結(jié)果語(yǔ)句用得較多,并且可選用不同的參數(shù)個(gè)數(shù),如果能使用宏定義命令使之簡(jiǎn)化,將給書寫帶來(lái)方便。特別是這里使用一次文件包含命令(下面講述)將宏定義部分寫在一個(gè)。h(頭文件)文件內(nèi),程序

15、需要時(shí)只要包含進(jìn)去就可以了,這樣將會(huì)更加簡(jiǎn)便。6.3.1 文件包含命令的格式和功能 文件包含命令是C語(yǔ)言程序常用的一條預(yù)處理命令,它的格式如下: # include(文件名) 其中,include是關(guān)鍵字,(文件名)是被包含的文件名,這里要求使用文件全名,包括路徑名和擴(kuò)展名。 文件包含的功能就是將指定的被包含文件的內(nèi)容放置在文件包含命令出現(xiàn)的地方。該命令可寫在程序的任一位置,但是一般寫在一個(gè)文件的開頭,這是一種明智的選擇。因?yàn)樵撁钤诤翁幊霈F(xiàn),所包含的文件內(nèi)容就被放置到該命令出現(xiàn)的位置,這就相當(dāng)于將被包含文件的內(nèi)容插入到該命令的地方。而被包含的。h文件中往往是一些該程序所需要的一些說(shuō)明或定義,

16、它包括符號(hào)常量的定義、類型定義、帶參數(shù)的宏定義、數(shù)組、結(jié)構(gòu)、聯(lián)合和枚舉的定義等等,它還可以包含外部變量的定義、函數(shù)的定義和說(shuō)明等等。這些內(nèi)容程序中將要用到,顯然放在程序前面比放在中間和后面要好些。 文件包含的用途在于減少程序人員的重復(fù)勞動(dòng),使得C語(yǔ)言程序更加簡(jiǎn)潔,提高程序的可讀性。但是,如果對(duì)文件包含命令使用不當(dāng),會(huì)增加程序的代碼長(zhǎng)度,包含了一些該程序所不需要的內(nèi)容。因此,選擇包含的文件時(shí)要慎重,定義被包含的文件時(shí)要短小。 6. 5 將例6. 4中的宏定義部分寫在一個(gè)print.h文件中,當(dāng)程序需要時(shí),將它包含進(jìn)去。其做法如下: 定義。h文件名為print.h,它將包含有關(guān)輸出顯示結(jié)果的宏定義

17、,其內(nèi)容如下: #define F1%dn #define F2%d,I%dn #de,ine PR1(a)printf(Fl,a) #define PR2(a,b) printf(F2,a,b) 程序內(nèi)容如下 #include print.h Main() int x,y,z; X=5; y=5*x: z =x+y; PR1(x); PR2(y,Z); PR12,Y); PR2(x+5,z/5) 執(zhí)行該程序的輸出結(jié)果與例6. 4的結(jié)果相同。 該程序中在開頭使用了文件包含命令,將文件print.h包含在該程序的開頭。從程序書寫角度來(lái)看只使用了一條文件包含命令便可代替該文件(指print. h文

18、件)中的4條宏定義命令,可見書寫簡(jiǎn)單了。print. h文件還可以用于其他程序中,如果某個(gè)程序需要該文件的內(nèi)容,只要使用一條文件包含命令就可以了。 6.3.2使用文件包含命令時(shí)應(yīng)注意事項(xiàng)、 (1)一個(gè)文件包含命令只能包含一個(gè)文件。如果某個(gè)程序需要包含多個(gè)文件,則可使用多條文件包含命令。例如,下列寫法是錯(cuò)誤的, #includ xy. h mn. h 而改寫成下列形式是正確的, #includexy. h #includemn. h 其前后順序取決于被包含文件內(nèi)容間的相互關(guān)系。如果兩個(gè)被包含文件內(nèi)容相互無(wú)關(guān),則書寫的前后順序也無(wú)關(guān)。如果一個(gè)文件中要使用另一個(gè)文件的內(nèi)容,則另一個(gè)文件要寫在前面。

19、(2)文件包含的定義是可以嵌套的。所謂文件包含定義的嵌套是指在一個(gè)被包含的文件中還可以包含有其他文件。例如, 文件filel. c的內(nèi)容如下: #include filet. h 而被包含的文件#file2.h的內(nèi)容如一下: #include file3. h 這便是文件包含的嵌套,它可以等價(jià)于: 文件filet c的內(nèi)容如下: #include,file3. h #includefile2. h 按上述順序?qū)懕容^安全。 (3) 文件包含命令中,引用的被包含文件有下面兩種方式: 方式一: # include(文件名 方式二: # include文件名, 這兩種方式中,文件名都要求是全名,方式一

20、中用一對(duì)尖括號(hào)將文件名括起,它表示所引習(xí)的被包含文件是系統(tǒng)提供的,并放在指定目錄下的。h文件。例如, #include stdio. h) #include math. h) 等等。 這種方式引用時(shí),系統(tǒng)將到指定的目錄去查找系統(tǒng)提供的。h文件。 方式二是用一對(duì)雙引號(hào)將文件名括起,它表示所引用的被包含文件可能是用戶自己定義的文件,并放在當(dāng)前目錄下或系統(tǒng)可自動(dòng)查找的目錄下。對(duì)這種引用的文件,系統(tǒng)先在當(dāng)前目錄下或用nos命令(PATH)連起來(lái)的通用目錄下查找,如果找不到再到系統(tǒng)指定的目錄下查找?guī)б虼?,要求編程人員對(duì)自己定義的被包含文件,引用時(shí)使用雙引號(hào),而系統(tǒng)提供的。h文件最好使用尖括號(hào),這樣查找可

21、能快些。 (4)被包含的文件可以是任意的源文件,不一定必須是。h文件,也可以是。c文件, 例6.6 使用文件包含命令將一個(gè)。c文件包含在另一個(gè)。c文件之中。 f1. c文件內(nèi)容如下: add(x,y int x,y; int z; z =x+y; return(z); f2.c文件內(nèi)容如下: #Include fl.c main () int a,b; a=5; b=10; printf( %dn,add (a,): 執(zhí)行f2一文件后,將獲得如h結(jié)果: 15 在f2.c文件的開頭就使用文件包含命令將f1.c一文件包含了進(jìn)去,這就相當(dāng)于將fl.c文件的內(nèi)容插入到f2. c文件中main( )的前

22、邊。 (5)為提高程序的可移植性,編程時(shí)事先將一些在不同環(huán)境或條件廠需要修改的量或需要修改的部分放在一個(gè)被包含的文件中,以后為適應(yīng)某種環(huán)境需要修改時(shí)。可以只修改包含文件中的內(nèi)容,這將為該程序的移植提供了方便。 6.4.1條件編譯的常用命令格式 條件編譯的常用命令格式有如下三種。 格式一: #ifdef #else #endif 其中,ifdef,else和endif是關(guān)鍵字。(標(biāo)識(shí)符少是指是否使用 defin命令定義過(guò)。和是由語(yǔ)句或命令組成的程序段。 該格式的功能描述如下; 當(dāng)被宏定義時(shí),中的語(yǔ)句或命令參加編譯;否則程序段2)中的語(yǔ)句或命令參加編譯,該格式中,#else是可以省略的,則變成下列

23、格式: #ifdef (程序段) #endif 格式二: #ifndef #else #endif 該格式與格式一大致相同,只是第一個(gè)關(guān)鍵字中不一樣。 該格式的功能是:如果未被宏定義時(shí),則編譯。否則編譯 格式三: #if表達(dá)式) #else #endif 該格式中,第一行與前面二種格式不同,if是關(guān)鍵字,是常量表達(dá)式。 該格式的功能是:當(dāng)是有非0值時(shí),則參加編譯;否則參加編譯。當(dāng)#else省略了,則變成如下簡(jiǎn)化格式; #if #endif 該格式中決定參加編譯的程序段取決于的值是零還是非零。 以下三種格式可根據(jù)需要講行選擇。6.4.2 條件編譯命令的應(yīng)用 (1)條件編譯可以用來(lái)提高程序的通用性

24、。由于不同的計(jì)算機(jī)存在一定差異,有的是16位機(jī),有的是32位機(jī),為使一個(gè)源程序在不同機(jī)器上運(yùn)行,可以使用以下的條件編譯(假定區(qū)別僅在機(jī)器的字長(zhǎng)上): #ifdef PC16 #define INTSIZE 16 #else #define INTSiE 32 #endif 如果PCi6在前面已被宏定義過(guò),例如以下命令: #define PC16 16 則編譯下面的命令行: #define INTSIZE 16 否則,PC16在前面沒(méi)有被宏定義過(guò),則編譯下面的命令行: #define INTIZE 32 這里,到底編譯哪些行,關(guān)鍵在于標(biāo)識(shí)符PC16是否被宏定義,而定義為多少并沒(méi)有關(guān)系。 前面介紹

25、的只是一種簡(jiǎn)單情況,其思路是將其不同用語(yǔ)句或命令表示出來(lái),根據(jù)不同的要求進(jìn)行選擇,按照這種思路來(lái)設(shè)計(jì)條件編譯。 (2)條件編譯會(huì)給程序調(diào)試帶來(lái)方便。在源程序的調(diào)試中,常常需要跟蹤程序的執(zhí)行情況,為此,在程序中加一些輸出信息的語(yǔ)句,通過(guò)這些輸出信息來(lái)跟蹤判斷程序是否有錯(cuò)誤。這是一種常用的調(diào)試手段。在調(diào)試結(jié)束后,需要把為了調(diào)試而增加的那些輸出信息的語(yǔ)句刪除掉,然而這種刪除工作常常帶來(lái)一些不方便,因?yàn)椴荒芏鄤h,也不對(duì)能少刪,必須刪對(duì),否則又將出錯(cuò)。如果使用條件編譯將會(huì)帶來(lái)一些方便即在滿足調(diào)試條件的情況下,加上一些輸入信息的語(yǔ)句行,在調(diào)試完成后,只要改變其條件使之不滿足調(diào)試條件,這時(shí)再重新編譯,原來(lái)加

26、進(jìn)去的一些輸出信息的語(yǔ)句將不再被編譯,這相當(dāng)于被刪除了,這種自動(dòng)刪除要方便得多。例如,在調(diào)試某個(gè)程序時(shí),為得出輸出信息以供判斷可在源程序中插入以下條件編譯: #if DEBUG printf(a=%d,b=%dn,a,b) #endif 在調(diào)試程序時(shí),在它們前面設(shè)置#define DEBUG 1,則printf( )語(yǔ)句行將參加編譯。于是 將輸出供判斷參考的a和b的滇。當(dāng)調(diào)試完成后,只是將前面的設(shè)置修改為:# define DE-BUG 0,則printf ( )語(yǔ)句行將不參加編譯,就相當(dāng)于該行被刪除一樣。可見,使用條件編譯通過(guò)改變其條件來(lái)刪除不需要參加編譯的程序段是很方便的。 (3)使用條件

27、編譯替代if語(yǔ)句會(huì)減少目標(biāo)代碼的長(zhǎng)度。例6.7將一個(gè)已知的十進(jìn)制數(shù),根據(jù)設(shè)置條件編譯的不同條件,使它按十六進(jìn)制輸出,或按八進(jìn)制輸出。 導(dǎo)人1s/、JL巾7相組l月它 main() . #define ;N 1; int n55; #ifdef N primF( % xn ,n); #else printf (%0n,n); #endif 由于程序中,N已被宏定義,因此執(zhí)行搞程序輸出的結(jié)果如下: 37 這是55 的十六進(jìn)制表示的值 如果刪除程序中的#definen NI這行后,執(zhí)行該程序輸出的結(jié)果為55的八進(jìn)制表示值: 67 前面己經(jīng)講述了三種常用的驪處理命令:宏定義命令、文件包含命令和條件編譯

28、命令。此外,還有一些其他不常用的預(yù)處理命令木書就不再講述了。下面以一個(gè)使用上述三種預(yù)處理命令的程序來(lái)結(jié)束本節(jié)的內(nèi)容。例6.8分析下列程序的輸出。n果,并分析各種預(yù)處理命令的用法。 該程序內(nèi)容如下: #define N I #define ARC main()printf(Hello!%sn) #include abc.h 其中,abc.H文件的內(nèi)容如下: #if N Char s=good morning ABC #endif 執(zhí)行該程序后輸出結(jié)果為: Hello!Good morning! 說(shuō)明: (1)在該程序中,有兩條宏定義命令,都是簡(jiǎn)單宏定義,有一條文件包含命令,所包含的文件是用戶定義

29、的。 (2)在被包含的文件ab. h中,只有一個(gè)條件編譯命令,該命令表明,只要是N為非0,則給出的程序段將被編譯。如果N為0,則無(wú)編譯的程序段。 (3)在該程序編譯前,進(jìn)行預(yù)處理時(shí),先將被包含文件插人到包含文件命令處,再經(jīng)過(guò)進(jìn)行條件編譯命令和宏定義命令后,該程序?qū)⒈惶鎿Q成如下待編譯的格式: Char s=good morning Main() Printf(*Hello!%sn,s); 該程序經(jīng)過(guò)編譯,執(zhí)行后將獲得上述結(jié)果,這是很自然的。6.5.1類型定義的含意和類型定義語(yǔ)1.類型定義的含意 什么是類型定義?是再定義新的類型嗎?不是口這里的類型定義指根據(jù)某種需要對(duì)已有的類型用一種新的類型名字來(lái)

30、替代,即給已有的或者已存在的類型起個(gè)新名。而不是再重新定義原來(lái)沒(méi)有的新類型。2.類型定義語(yǔ)句 類型定義是通過(guò)類型定義語(yǔ)句來(lái)實(shí)現(xiàn)的。類型定義語(yǔ)句格式如下: typedef(已有類型說(shuō)明符)新類型名表; 其中,typedef是關(guān)鍵字。(已有類型說(shuō)明符)包含C語(yǔ)言中規(guī)定的所有合法的類型說(shuō)明符和已用類型定義語(yǔ)句定義的新的類型名,(新類型名表)是用類型定義語(yǔ)句定義的新的類型說(shuō)明符,該表中可以有一個(gè)或多個(gè)新的類型說(shuō)明符,多個(gè)新的類型說(shuō)明符用逗號(hào)分隔。 該語(yǔ)句在使用時(shí)應(yīng)該往意如下事項(xiàng): (1)該語(yǔ)句只是對(duì)已有的類型定義一個(gè)新名,而絕不是產(chǎn)生一種新的類型。 (2)使用該語(yǔ)句時(shí),習(xí)慣上將新定義的類型名用大寫字母

31、,以便與系統(tǒng)原有的類型名加以區(qū)別。這里如用小寫字母也可以。 (3)類型定義可以嵌套。所謂嵌套是指用該語(yǔ)句定義的新的類型名可再用來(lái)定義新的類型。例如, typFdef int FEET; typedef FEET*()POINT; POINT p1,p2; 這里,F(xiàn)EET是用typedef語(yǔ)句定義出的新類型名,接著又用FEET來(lái)定義新類型POINT,由于FEET為int型的類型,而PONIT為指向整型類型的指針,然后又用POINT定義兩個(gè)變量p1和P2,這時(shí)p1和P2都是指向int型類型的指針。 (4)常把使用該語(yǔ)句定義的數(shù)據(jù)類型包含在某個(gè)頭文件中,這樣在不同的源文件中用到該類型時(shí),叮使用文件包含命令將所需的頭文件包含到該源文件巾。 (5)在使用中會(huì)看到typedef語(yǔ)句與#define二有相似之處,但是二者實(shí)際上是很不相同的。其中#define在編譯的預(yù)處理時(shí)完成,只是簡(jiǎn)單的替換,而typed

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論