版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第8章編譯預(yù)處理本章學(xué)習(xí)目標(biāo)熟練掌握宏定義。掌握文件包含處理。了解條件編譯。[Return]
所謂編譯預(yù)處理是指,在對源程序進(jìn)行編譯之前,先對源程序中的編譯預(yù)處理命令進(jìn)行處理;然后再將處理的結(jié)果,和源程序一起進(jìn)行編譯,以得到目標(biāo)代碼。10.1宏定義10.2文件包含10.3條件編譯10.1宏定義在C語言中,“宏”分為無參數(shù)的宏(簡稱無參宏)和有參數(shù)的宏(簡稱有參宏)兩種。10.1.1無參宏定義1.無參宏定義的一般格式
#define標(biāo)識符語言符號字符串其中:“define”為宏定義命令;“標(biāo)識符”為所定義的宏名,通常用大寫字母表示,以便于與變量區(qū)別;“語言符號字符串”可以是常數(shù)、表達(dá)式、格式串等。2.使用宏定義的優(yōu)點(diǎn)(1)可提高源程序的可維護(hù)性(2)可提高源程序的可移植性(3)減少源程序中重復(fù)書寫字符串的工作量【例10-1】輸入圓的半徑,求圓的周長、面積和球的體積。要求使用無參宏定義圓周率。/*exam10_1,輸入半徑,求圓的周長、面積和球的體積。*/#include"stdio.h"#definePI3.1415926main(void){doubleradius,length,area,volume;printf("Inputaradius:");scanf("%lf",&radius);length=2*PI*radius;/*引用無參宏求周長*/area=PI*radius*radius;/*引用無參宏求面積*/volume=PI*radius*radius*radius*3/4;/*引用無參宏求體積*/printf("length=%.2f,area=%.2f,volume=%.2f\n",length,area,volume);} 3.說明(1)宏名一般用大寫字母表示,以示與變量區(qū)別。但這并非是規(guī)定。(2)宏定義不是C語句,所以不能在行尾加分號。否則,宏展開時(shí),會將分號作為字符串的1個(gè)字符,用于替換宏名。(3)在宏展開時(shí),預(yù)處理程序僅以按宏定義簡單替換宏名,而不作任何檢查。如果有錯(cuò)誤,只能由編譯程序在編譯宏展開后的源程序時(shí)發(fā)現(xiàn)。(4)宏定義命令#define出現(xiàn)在函數(shù)的外部,宏名的有效范圍是:從定義命令之后,到本文件結(jié)束。通常,宏定義命令放在文件開頭處。(5)在進(jìn)行宏定義時(shí),可以引用已定義的宏名。例如:
#defineONE1 #defineTWOONE+ONE #define
THREE
ONE+TWO(6)對雙引號括起來的字符串內(nèi)的字符,即使與宏名同名,也不進(jìn)行宏展開。
例如: #defineXYZthisisatest
…
… printf("XYZ");該語句不是打印輸出:
thisisatest而是打印輸出:
XYZ[演示]1.帶參宏定義的一般格式#define宏名(形參表)語言符號字符串2.帶參宏的調(diào)用和宏展開(1)調(diào)用格式:宏名(實(shí)參表)(2)宏展開:用宏調(diào)用提供的實(shí)參字符串,直接置換宏定義命令行中、相應(yīng)形參字符串,非形參字符保持不變。例如:#defineMIN(a,b)(a<b)?a:bmain(void){intx,y;
x=10;y=20;
printf("theminimumis:%d",MIN(x,y));}10.1.2有參宏定義
當(dāng)編譯該程序時(shí),由MIN(a,b)定義的表達(dá)式被替換,x和y用作操作數(shù),即printf()語句被代換后取如下形式:
printf("theminimumis:%d",(x<y)?x:y);用宏定義代替實(shí)在的函數(shù)的一大好處是宏定義增加了代碼的速度,因?yàn)椴淮嬖诤瘮?shù)調(diào)用的開銷。但增加速度也有代價(jià):由于重復(fù)編碼而增加了程序長度。3.說明:(1)在帶參宏定義中,形式參數(shù)不分配內(nèi)存單元,不做類型定義。宏調(diào)用時(shí)的實(shí)參代換形參不做類型檢查。這是與函數(shù)不同的。利用宏不做類型檢查的特性,在宏調(diào)用時(shí)避開數(shù)據(jù)類型的限制,來實(shí)現(xiàn)某些函數(shù)無法實(shí)現(xiàn)的功能。如上例中的宏定義同樣也可以用求兩個(gè)實(shí)型數(shù)中的最小值,而如果改用函數(shù)實(shí)現(xiàn)則需要定義兩個(gè)不同類型的函數(shù)。(2)在帶參宏定義中,宏名和形參表之間不能有空格出現(xiàn)。例如:把
#defineMIN(a,b)(a<b)?a:b寫為:
#defineMIN
(a,b)(a<b)?a:b將被認(rèn)為是無參宏定義,宏名MIN代表字符串(a,b)(a<b)?a:b
(3)在宏定義中形參是標(biāo)識符,而宏調(diào)用中的實(shí)參可以是表達(dá)式。在宏調(diào)用中的實(shí)參是表達(dá)式時(shí),可能引起意想不到的錯(cuò)誤。[演示]例如,定義宏:
#defineAREA(r)3.1416*r*r在宏調(diào)用時(shí)按如下方式調(diào)用:
k=AREA(3+5);則宏展開后形式為:
k=3.1416*3+5*3+5;計(jì)算結(jié)果與本來意圖相差很遠(yuǎn),所以在宏定義中,建議字符串內(nèi)形參和整個(gè)字符串都用括號括起來以避免出錯(cuò)。如上述宏可以寫為:
#defineAREA(r)(3.1416*(r)*(r))這樣定義后,實(shí)參是數(shù)據(jù)表達(dá)式也不會出錯(cuò)。[演示](4)有參宏與有參函數(shù)的比較不同之處,主要有以下幾個(gè)方面:1)調(diào)用有參函數(shù)時(shí),是先求出實(shí)參的值,然后再復(fù)制一份給形參。而展開有參宏時(shí),只是將實(shí)參簡單地置換形參。2)在有參函數(shù)中,形參是有類型的,所以要求實(shí)參的類型與其一致;而在有參宏中,形參是沒有類型信息的,因此用于置換的實(shí)參,什么類型都可以。有時(shí),可利用有參宏的這一特性,實(shí)現(xiàn)通用函數(shù)功能。3)使用有參函數(shù),無論調(diào)用多少次,都不會使目標(biāo)程序變長,但每次調(diào)用都要占用系統(tǒng)時(shí)間進(jìn)行調(diào)用現(xiàn)場保護(hù)和現(xiàn)場恢復(fù);而使用有參宏,由于宏展開是在編譯時(shí)進(jìn)行的,所以不占運(yùn)行時(shí)間,但是每引用1次,都會使目標(biāo)程序增大1次。10.2文件包含1.文件包含的概念文件包含是指,一個(gè)源文件可以將另一個(gè)源文件的全部內(nèi)容包含進(jìn)來。2.文件包含處理命令的格式#include“包含文件名”或#include<包含文件名>兩種格式的區(qū)別僅在于:(1)使用雙引號:系統(tǒng)首先到當(dāng)前目錄下查找被包含文件,如果沒找到,再到系統(tǒng)指定的“包含文件目錄”(由用戶在配置環(huán)境時(shí)設(shè)置)去查找。(2)使用尖括號:直接到系統(tǒng)指定的“包含文件目錄”去查找。一般地說,使用雙引號比較保險(xiǎn)。一個(gè)大程序,通常分為多個(gè)模塊,并由多個(gè)程序員分別編程。有了文件包含處理功能,就可以將多個(gè)模塊共用的數(shù)據(jù)(如符號常量和數(shù)據(jù)結(jié)構(gòu))或函數(shù),集中到一個(gè)單獨(dú)的文件中。這樣,凡是要使用其中數(shù)據(jù)或調(diào)用其中函數(shù)的程序員,只要使用文件包含處理功能,將所需文件包含進(jìn)來即可,不必再重復(fù)定義它們,從而減少重復(fù)勞動(dòng)。3.文件包含的優(yōu)點(diǎn)4.說明(1)編譯預(yù)處理時(shí),預(yù)處理程序?qū)⒉檎抑付ǖ谋话募?,并將其?fù)制到#include命令出現(xiàn)的位置上。(2)常用在文件頭部的被包含文件,稱為“標(biāo)題文件”或“頭部文件”,常以“h”(head)作為后綴,簡稱頭文件。在頭文件中,除可包含宏定義外,還可包含外部變量定義、結(jié)構(gòu)類型定義等。(3)一條包含命令,只能指定一個(gè)被包含文件。如果要包含n個(gè)文件,則要用n條包含命令。(4)文件包含可以嵌套,即被包含文件中又包含另一個(gè)文件。/*exam10_2,演示時(shí)要分別存為3個(gè)相應(yīng)的文件*//*minfile.c*/intmin(inta,intb){returna<b?a:b;}注意:在minfile.c文件中沒有main()函數(shù)。/*maxfile.c*/intmax(inta,intb){returna>b?a:b;}注意:在maxfile.c文件中也沒有main()函數(shù)?!纠?0-2】文件包含處理應(yīng)用舉例。以下程序是由3個(gè)文件組成的:minfile.c,maxfile.c和mainfile.c。/*mainfile.c*/#include“stdio.h”/*包含標(biāo)準(zhǔn)輸入輸出庫函數(shù)*/#include“maxfile.c”
/*包含maxfile.c文件,以便調(diào)用max函數(shù)*/#include“minfile.c”
/*包含minfile.c文件,以便調(diào)用min函數(shù)*/intmain(void){inta=18,b=9,c,d;c=max(a,b);d=min(a,b);printf(“max=%d,min=%d\n”,c,d);return0;}[演示]注意:編譯時(shí)使用“changedir”命令修改工作目錄為3個(gè)文件的保存目錄。
說明:雖然在mainfile.c文件中沒有定義max函數(shù)和min函數(shù),但由于在mainfile.c文件中使用了#include“maxfile.c”和#include“minfile.c”包含命令,將這兩個(gè)文件的內(nèi)容包含到了mainfile.c源文件中,所以可以調(diào)用這兩個(gè)函數(shù)。10.3條件編譯
一般情況下,源程序中所有的行都參加編譯。但有時(shí)希望對其中一部分內(nèi)容只在滿足一定條件才進(jìn)行編譯,這就是條件編譯。商業(yè)軟件公司廣泛應(yīng)用條件編譯來提供和維護(hù)某一程序的許多顧客版本。條件編譯有以下幾種形式:(1)#ifdef標(biāo)識符程序段1;#else
程序段2;#endif功能:當(dāng)“標(biāo)識符”已經(jīng)被#define命令定義過,則編譯程序段1,否則編譯程序段2。(1)在不同的系統(tǒng)中,一個(gè)int型數(shù)據(jù)占用的內(nèi)存字節(jié)數(shù)可能是不同的。這樣往往需要對源程序作出修改,這就降低了程序的通用性。使用以下條件編譯處理,則可以輕松解決此類問題。如:如果在這組條件編譯命令之前曾出現(xiàn)以下命令行:
#defineCOMPUTER_A0或?qū)OMPUTER_A定義為任何字符串,甚至是
#defineCOMPUTER_A則編譯后程序中的INTEGER_SIZE都用16代替,否則用32來代替。這樣源程序可以不必作任何修改就可以用于不同類型的計(jì)算機(jī)系統(tǒng)。#ifdefCOMPUTER_A#defineINTEGER_SIZE16#else#defineINTEGER_SIZE32#endif如果COMPUTER_A在前面已經(jīng)被定義過,則編譯下面的命令行:
#defineINTEGER_SIZE16否則,編譯下面的命令行:
#defineINTEGER_SIZE32(3)#if常量表達(dá)式程序段1;#else
程序段2;#endif
功能:如果常量表達(dá)式的值為真(非0),則對程序段1進(jìn)行編譯,否則對程序段2進(jìn)行編譯。(2)#ifndef標(biāo)識符程序段1;#else
程序段2;#endif功能:當(dāng)“標(biāo)識符”沒有被#define命令定義過,則編譯程序段1,否則編譯程序段2。與第一種形式的作用剛好
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 貴州大學(xué)《影視音樂欣賞》2023-2024學(xué)年第一學(xué)期期末試卷
- 貴陽幼兒師范高等專科學(xué)?!段枧_語言基礎(chǔ)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025江蘇省建筑安全員A證考試題庫及答案
- 貴陽學(xué)院《復(fù)合材料學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025重慶建筑安全員-B證考試題庫附答案
- 2025年-浙江省安全員C證考試(專職安全員)題庫附答案
- 2025貴州省建筑安全員-C證考試(專職安全員)題庫及答案
- 廣州醫(yī)科大學(xué)《材料創(chuàng)新導(dǎo)論》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025四川省建筑安全員知識題庫附答案
- 2025遼寧建筑安全員B證(項(xiàng)目經(jīng)理)考試題庫
- 醫(yī)美整形退款協(xié)議書范本下載
- 國培培訓(xùn)成果匯報(bào)
- 廣東省廣州市2023-2024學(xué)年高一上學(xué)期期末物理試卷(含答案)
- 北師大版(三起)(2024)三年級上冊英語全冊教案(按課設(shè)計(jì)共23課)
- 博物館多功能廳功能改造方案
- 2024年四川省公務(wù)員錄用考試《行測》真題及答案解析
- 銀行內(nèi)部管理檔案制度
- 外墻真石漆施工后期維護(hù)方案
- 電氣自動(dòng)化年終總結(jié)
- 工會上墻制度
- 與信仰對話 課件-2024年入團(tuán)積極分子培訓(xùn)
評論
0/150
提交評論