![C語言的預(yù)處理器課件_第1頁](http://file4.renrendoc.com/view15/M00/2A/0C/wKhkGWeQ21uAfb-vAAEpwPFY7ic556.jpg)
![C語言的預(yù)處理器課件_第2頁](http://file4.renrendoc.com/view15/M00/2A/0C/wKhkGWeQ21uAfb-vAAEpwPFY7ic5562.jpg)
![C語言的預(yù)處理器課件_第3頁](http://file4.renrendoc.com/view15/M00/2A/0C/wKhkGWeQ21uAfb-vAAEpwPFY7ic5563.jpg)
![C語言的預(yù)處理器課件_第4頁](http://file4.renrendoc.com/view15/M00/2A/0C/wKhkGWeQ21uAfb-vAAEpwPFY7ic5564.jpg)
![C語言的預(yù)處理器課件_第5頁](http://file4.renrendoc.com/view15/M00/2A/0C/wKhkGWeQ21uAfb-vAAEpwPFY7ic5565.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
C語言的預(yù)處理器
編譯預(yù)處理命令不是C語言的語句,它的作用只是告訴(命令)編譯系統(tǒng),在編譯根源程式之前對根源程式進(jìn)行某種預(yù)加工,而後再進(jìn)行編譯。所有的編譯預(yù)處理命令都是以符號“#”開頭,末尾不加分號。預(yù)處理命令可以用在程式的任何地方。本章主要介紹以下的C語言的編譯預(yù)處理命令:宏定義的命令:#define,#undef;檔包含命令:#include;條件編譯命令:#if_#else_#endif;
#if_#elif_#endif;
#ifdef_#else_#endif;
#ifndef_#else_#endif。
12.1宏定義和宏替換12.1.1不帶參數(shù)的宏定義和引用
不帶參數(shù)的宏定義的一般形式為:
#define宏名字元序列 宏定義的作用是,在對根源程式編譯之前,將程式中出現(xiàn)的所有的宏名用對應(yīng)的字元序列來代替。這種替換稱宏替換或宏引用。不帶參數(shù)宏替換,通常的用途是,用宏名定義程式中的常量,如:
#defineFALSE0#defineWORDS"TurboC++"
通常把宏定義寫在檔的開始部分,函數(shù)的外面,或?qū)懺诎瑱n(#include)中。
例12.1.1宏定義與宏替換應(yīng)用。程式定義了一個(gè)宏名:SIZE,用來定義數(shù)組str的容量。程式中還使用了系統(tǒng)定義的一個(gè)宏名NULL(空字元),用於檢查字元型數(shù)組中字串的結(jié)束符。程式的功能是,將用戶輸入的字串存入數(shù)組str,然後,變成大寫字母將其輸出。
程式如下:
#include"stdio.h"#defineSIZE80 /*宏定義SIZE*/main(){
inti;charstr[SIZE];/*宏SIZE的引用*/
printf("Enterastring:");gets(str);
for(i=0;str[i]!=NULL;i++) /*宏NULL的引用*/
printf("%c",toupper(str[i]));
printf("\n");return;}宏替換的另一個(gè)常見的應(yīng)用,是語句串的替換。也就是用一個(gè)宏名代表一組C語句。編譯時(shí),凡是程式中遇到這個(gè)宏名,就用這些語句代替。這相當(dāng)於調(diào)用無參數(shù)的函數(shù)。例12.1.2求1~num之間的質(zhì)數(shù)的程式。程式中使用了如下的C語句宏定義:
#definePRIMEfor(i=2;i<n;i++)\if(n%i==0)prime=0;
程式如下:
#include"stdio.h"#definePRIMEfor(i=2;i<n;i++)\if(n%i==0)prime=0; /*宏定義*/
main(){
intn,i,prime,num,k=0;
printf("Enteranumber:");
scanf("%d",&num);
for(n=2;n<num;n++){prime=1;PRIME; /*宏替換*/
if(prime){
printf("%4d",n);if(!(++k%5))printf("\n");}}
printf("\n");return0;}
宏定義可以嵌套進(jìn)行。也就是說,在定義宏時(shí),可以引用已有定義的宏名,實(shí)現(xiàn)層層替換。例如:#definePI3.14159#defineSPI*r*r#defineL2*S/r
其中定義S時(shí),使用了已定義的PI;定義L時(shí),使用了已定義的S。例12.1.3應(yīng)用上面嵌套結(jié)構(gòu)的宏定義,計(jì)算圓的面積和周長。
程式如下:
#include"stdio.h"#definePI3.14159#defineSPI*r*r#defineL2*S/rmain(){
floatr;
printf("Enterr:");
scanf("%f",&r);
printf("r=%f\tS=%f\tL=%f\n",r,S,L);
return;}程式輸出舉例(帶下劃線的數(shù)據(jù)是用戶輸入的):
Enterr:1r=1.000000S=3.141590L=6.283180
需要注意的是,這個(gè)程式的語句
printf("r=%f\tS=%f\tL=%f\n",r,S,L);中,兩次出現(xiàn)S和L:在格式字串中出現(xiàn)了S和L,在輸出項(xiàng)列表中也出現(xiàn)了S和L。C語言規(guī)定,宏名出現(xiàn)在字串中時(shí),將不看作是宏名,因而也不做宏替換。所以才有如上所示的輸出。例12.1.4將宏用於輸出語句中的例子。
#include"stdio.h"#definePRNprintf/*定義宏*/#defineD"%d\n"#defineF"%f\n"#defineS"%s\n"main(){
inti=10;floatf=20.0;charch[]="string.";
PRN(D,i);PRN(F,f);PRN(S,ch);
return;}程式的運(yùn)行結(jié)果為:
1020.000000
string.12.1.2帶參數(shù)的宏定義和引用帶參數(shù)的宏定義的一般形式為:
#define宏名(形參表)字元序列
程式中引用宏名時(shí),寫入實(shí)參,就像函數(shù)調(diào)用那樣。定義了宏名後,編譯系統(tǒng)在開始編譯根源程式前,把程式中引用的宏替換成相應(yīng)的一串符號,然後進(jìn)行編譯。在替換過程中用實(shí)參代替形參。
下麵是一個(gè)帶參數(shù)的宏定義的例子:
#defineMAX(a,b)((a)>(b))?(a):(b)
例12.1.5利用上面的帶參數(shù)的宏定義,編寫求兩個(gè)數(shù)中的較大者的程式。程式如下:#include"stdio.h"#defineMAX(a,b)((a)>(b))?(a):(b) /*宏定義*/
main(){
inta,b,max;
printf("Enter2numbers:");
scanf("%d%d",&a,&b);
max=MAX(a,b); /*宏替換*/
printf("Themanximumnum=%d\n",max);
return0;}
也可以將程式中的兩個(gè)語句:
max=MAX(a,b);
printf("Themanximumnum=%d",max);寫成如下的一個(gè)語句:
printf("Themanximumnum=%d",MAX(a,b));
其效果是一樣的。我們看到,這種宏替換很象調(diào)用函數(shù)。例如:
max=MAX(a,b);MAX(a,b);但它們的工作的機(jī)理是完全不同的,在概念更上不要混淆。它們之間的不同,體現(xiàn)在以下四個(gè)方面。(1)函數(shù)調(diào)用時(shí),要計(jì)算實(shí)參並向形參傳送。而宏中的參數(shù),只是進(jìn)行簡單的替換。既沒有向形參拷貝數(shù)據(jù),也沒有傳送參數(shù)地址。(2)函數(shù)中的實(shí)參和形參有確定數(shù)據(jù)類型,並且兩者是一一對應(yīng)的。宏名沒有數(shù)據(jù)類型。它只是個(gè)符號。其參數(shù)也只是個(gè)符號而已。引用時(shí),代入指定的字元。宏定義的字串可以是任何數(shù)據(jù)類型。(3)宏是在編譯時(shí)進(jìn)行替換的,不分配記憶體空間。而函數(shù)調(diào)用是在程式運(yùn)行時(shí)處理的,並分配相應(yīng)的臨時(shí)的記憶體空間。
(4)宏替換是不占程式的運(yùn)行時(shí)間的,只占編譯時(shí)間。但宏替換增加程式代碼長度。宏替換的次數(shù)越多,程式代碼長度越長。函數(shù)調(diào)用要消耗程式的運(yùn)行時(shí)間,但不使程式變長。靈活恰當(dāng)?shù)剡\(yùn)用宏替換,可以使根源程式顯得簡潔,增加根源程式的可讀性。例12.1.6編寫程式,將例12.1.3中無參數(shù)宏定義改為帶參數(shù)r的宏定義:
#defineS(r)PI*(r)*(r)#defineL(r)2*S(r)/(r)
程式如下:
#include"stdio.h"#definePI3.14159 /*定義不帶參數(shù)的宏*/#defineS(r)PI*(r)*(r) /*定義帶參數(shù)r的宏*/#defineL(r)2*S(r)/(r) /*定義帶參數(shù)r的宏*/
main(){
floatr;
printf("Enterr:");
scanf("%f",&r);
printf("r=%f\tS=%f\tL=%f\n",r,S(r),L(r)); /*宏的引用*/
return;}在以上兩個(gè)例子中,宏的形參都用圓括號括起來了。這不是絕對必要的。例如,例12.1.5中宏定義也可以寫成下麵的形式:
#definePI3.14159#defineS(r)PI*r*r#defineL(r)2*S(r)/r但是,對於實(shí)參為運(yùn)算式的情況,上面參數(shù)不帶括弧宏定義,可能會給出錯誤的計(jì)算結(jié)果。設(shè)有r=3.0.a=1.0.b=2.0
根據(jù)上面的宏定義,則有:
S(r)=s(3)=28.27431,L(r)=l(3)18.84954
而參數(shù)為運(yùn)算式時(shí),
S(a+b)=S(3)=7.14159,L(a+b)=12.28318顯然結(jié)果是錯的。後者因?yàn)閷?shí)參沒有括弧,所以計(jì)算過程是:
S(a+b)=3.14159×1+2×1+2=3.14159+2+2=7.14159
如果在宏定義裏給參數(shù)r加上括弧,則計(jì)算過程是:
S(a+b)=3.14159×(1+2)×(1+2)=3.14159×3×3=28.27431
結(jié)果是正確的。為了避免出現(xiàn)上述可能出現(xiàn)的錯誤,在定義帶參數(shù)的宏時(shí),最好給參數(shù)加上圓括號。
12.1.3取消宏定義#undef命令用於取消先前已定義的宏名。其一般形式為:
#undef
宏名
12.2文件包含所謂檔包含,是指一個(gè)原始檔案將另一個(gè)原始檔案包含到自己的檔之中。
檔包含命令有如下兩種形式:
#include<檔案名>#include"檔案名"
包含命令的功能是,在編譯預(yù)處理時(shí),用命令指定的檔案名的文本內(nèi)容來替代該命令,使包含檔的內(nèi)容成為本程式的一部分。
如果檔案名用了雙引號,則首先查找當(dāng)前目錄,若找不到該檔,則查找命令行定義的其他目錄。如果仍找不到該檔,則查找系統(tǒng)定義的標(biāo)準(zhǔn)目錄。如果檔案名使用了尖括弧,則編譯器首先查找命令行指定的目錄;如果找不到該檔,則查找標(biāo)準(zhǔn)目錄,不查找當(dāng)前工作目錄。例12.2.1給定半徑,計(jì)算圓的周長和圓面積。為了展示利用檔包含命令處理多檔程式的設(shè)計(jì)方法,我們設(shè)計(jì)三個(gè)如下的包含檔,或稱頭檔:頭檔1名為myin1.h。檔內(nèi)容包含如下兩條:#include<stdio.h>#definePI3.14159 /*宏定義PI*/頭檔2名為myin2.h。其內(nèi)容是函數(shù)lr的定義:
floatlr(floatr) /*計(jì)算圓周長的函數(shù)*/{
return2*sr(r)/r;}
頭檔3名為myin3.h。檔內(nèi)容是函數(shù)sr的定義。
floatsr(floatr) /*計(jì)算圓面積的函數(shù)*/{
returnPI*r*r;}
設(shè)計(jì)一個(gè)含有上述三個(gè)頭檔和主函數(shù)程式如下:#include"myin1.h"#include"myin3.h"#include"myin2.h"main(){floatx=3.0;
printf("L=%f\n",lr(x));
printf("S=%f\n",sr(x));}這裏在檔myin3.h和文件myin2.h中定義的兩個(gè)函數(shù)是嵌套的。即函數(shù)lr()的定義中引用著函數(shù)sr()。函數(shù)sr()定義中還引用著頭檔myin1.h中的宏定義PI。因此,在主函數(shù)檔中,三個(gè)包含命令的檔書寫順序,必須是先myin1.h,然後myin3.h,最後是myin2.h。使用包含檔的結(jié)果,本例的根源程式由四個(gè)檔組成:三個(gè)頭檔和一個(gè)主程序檔。經(jīng)過編譯預(yù)處理後,三個(gè)頭檔被“包含”到主程序檔中,成為程式的組成部分。圖12.1給出本例包含檔處理的情形。
圖12.1例12.2.1包含檔處理示意圖12.3條件編譯C語言的條件編譯預(yù)處理命令就是用於有選擇的編譯根源程式中某些部分的。條件編譯主要用於調(diào)試程式。條件編譯的另一個(gè)用途是,可以用根源程式產(chǎn)生不同版本。
12.3.1#if_#endif類型的條件編譯命令這是根據(jù)運(yùn)算式的值進(jìn)行條件編譯的命令。該條件編譯命令有以下三種不同形式。1.#if_#endif
此命令的一般形式為:
#if常數(shù)運(yùn)算式程式段#endif其作用是,如果常數(shù)運(yùn)算式為真,則編譯從#if到#endif之間的程式段(活語句塊);否則就不編譯,跳過這段程式。2.#if_#else_#endif此命令的一般形式為:
#if常量運(yùn)算式程式段1#else
程式段2#endif其作用是,如果常量運(yùn)算式為真,編譯程序段1的代碼段;否則,編譯程序段2的代碼段。例12.3.1用戶給定一整數(shù)MAX。當(dāng)MAX大於或等於100時(shí),編譯語句:
printf("MAX>=100");
否則,編譯語句:
printf("MAX<100");程式如下:
#include<stdio.h>#defineMAX120main(){#ifMAX>=100
printf("MAX>=100\n");#else
printf("MAX<100\n");
#endif
printf("MAX=%d\n",MAX);return0;}3.#if_#elif_#endif
這是用於多路選擇的編譯命令。它的一般形式為:
#if常量運(yùn)算式1程式段1#elif
常量運(yùn)算式2程式段2
……
……#elif
常量運(yùn)算式n
程式段n
#endif
其作用是,如果常量運(yùn)算式1為真,則編譯程序段1;否則,如果常量運(yùn)算式2為真,則編譯程序段2;否則,如果常量運(yùn)算式3為真,則編譯程序段3;直到最後,如果常量運(yùn)算式n為真,則編譯程序段n。12.3.2#ifdef和#ifndef類型的條件編譯命令這是根據(jù)識別字的定義與否進(jìn)行條件編譯的命令。識別字是用宏定義命令實(shí)現(xiàn)的。因此,也可以說,這種條件編譯是根據(jù)宏名是否被定義決定某程式段是否進(jìn)行編譯。這種條件編譯預(yù)處理命令有兩種格式。1.#ifdef_#endif類型條件編譯命令這種類型的命令有以下兩種格式:第一種格式為:
#ifdef
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 教科版道德與法治七年級上冊7.2《消除煩惱體驗(yàn)美好》聽課評課記錄
- 湘教版地理八年級上冊《第一節(jié) 中國的地形》聽課評課記錄3
- 人教版地理八年級上冊第三節(jié)《河流》聽課評課記錄1
- 部編版道德與法治七年級上冊第三單元第六課《師生之間第二框師生交往》聽課評課記錄
- 人教版地理七年級上冊第三章第四節(jié)《世界的氣候》聽課評課記錄
- 商務(wù)星球版地理七年級下冊第八章《不同發(fā)展類型的國家》復(fù)習(xí)聽課評課記錄1
- 四年級上冊健康體檢與評估計(jì)劃
- 2024-2025學(xué)年人教部編版一年級美術(shù)上冊教學(xué)計(jì)劃
- 中學(xué)2025年法制教育家校合作計(jì)劃
- 2025學(xué)年春季學(xué)期科技創(chuàng)新教育計(jì)劃
- 施工現(xiàn)場人力資源施工機(jī)具材料設(shè)備等管理計(jì)劃
- 第八章《運(yùn)動和力》達(dá)標(biāo)測試卷(含答案)2024-2025學(xué)年度人教版物理八年級下冊
- 民辦幼兒園務(wù)工作計(jì)劃
- 2025年華僑港澳臺生聯(lián)招考試高考地理試卷試題(含答案詳解)
- 2025年市場拓展工作計(jì)劃
- 中國革命戰(zhàn)爭的戰(zhàn)略問題(全文)
- 《數(shù)學(xué)歸納法在中學(xué)解題中的應(yīng)用研究》9000字(論文)
- (房屋建筑部分)工程建設(shè)標(biāo)準(zhǔn)強(qiáng)制性條文版
- 《大學(xué)英語四級詞匯大全》
- 第六章-1八綱辨證
- 《中國古典建筑》課件
評論
0/150
提交評論