C語(yǔ)言程序設(shè)計(jì)課件:編譯預(yù)處理_第1頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件:編譯預(yù)處理_第2頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件:編譯預(yù)處理_第3頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件:編譯預(yù)處理_第4頁(yè)
C語(yǔ)言程序設(shè)計(jì)課件:編譯預(yù)處理_第5頁(yè)
已閱讀5頁(yè),還剩37頁(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)介

預(yù)

理9.1宏定義9.2文件包含單元小結(jié) 9.1宏

9.1.1不帶參數(shù)的宏定義

不帶參數(shù)的宏定義的一般形式如下:

#define標(biāo)識(shí)符字符串

其作用是用一個(gè)指定的標(biāo)識(shí)符來(lái)代表一個(gè)字符串。

說(shuō)明:其中的“#”表示這是一條預(yù)處理命令;“define”為宏定義命令;“標(biāo)識(shí)符”為所定義的宏名;“字符串”可以是常數(shù)、表達(dá)式、字符串等。例如:

#definePI3.14159

上述命令的作用是用標(biāo)識(shí)符PI代替常量3.14159。在編譯預(yù)處理時(shí),將程序中該定義以后的所有標(biāo)識(shí)符PI都用3.14159代替。

【例9-1】

輸入圓的半徑,求圓的周長(zhǎng)、面積和球的體積,并輸出結(jié)果。要求使用不帶參數(shù)的宏定義圓周率。#include<stdio.h>#definePI3.14159main(){ floatr,l,s,v; printf("請(qǐng)輸入圓的半徑:");

scanf("%f",&r); l=2*PI*r; s=PI*r*r; v=PI*r*r*r*4/3; printf("周長(zhǎng)=%.2f,面積=%.2f,球體積=%.2f\n",l,s,v);}圖9-1例9-1程序運(yùn)行結(jié)果

下面是關(guān)于宏定義的幾點(diǎn)說(shuō)明:

(1)宏名一般習(xí)慣用大寫字母表示,以便與變量名相區(qū)別。但這并非規(guī)定,也可用小寫字母。

(2)宏定義是用宏名來(lái)代表一個(gè)字符串,在宏展開(kāi)時(shí)又以該字符串取代宏名,這只是一種簡(jiǎn)單的替代。字符串可以包含任何字符,可以是常數(shù),也可以是表達(dá)式。預(yù)處理程序?qū)λ蛔鋈魏螜z查。如果有錯(cuò)誤,只能在已被宏展開(kāi)后的源程序編譯時(shí)被發(fā)現(xiàn),例如:

#defineN100

inta[N];

上面的例子先用N來(lái)代表常數(shù)100,然后定義一個(gè)一維數(shù)組a,令其數(shù)組元素為100個(gè)。再例如:

#defineM3+4

s=5*M;

其中,計(jì)算之后s的值為19,即在實(shí)際的編譯運(yùn)行時(shí)執(zhí)行的是s=5*3+4=19。這和下面的例子并不等價(jià)。

#defineM(3+4)

s=5*M;

此時(shí),在程序運(yùn)行時(shí)執(zhí)行的是s=5*(3+4)=35。

(3)宏定義不是說(shuō)明或語(yǔ)句,在行末不必加分號(hào)。如果加上分號(hào),則連分號(hào)也一起置換。例如:

#defineN100;

inta[N];

經(jīng)宏展開(kāi)后,該語(yǔ)句如下:

#defineN100;

inta[100;];

顯然出現(xiàn)了語(yǔ)法錯(cuò)誤。

(4)宏名在源程序中若用引號(hào)括起來(lái),則預(yù)處理程序不對(duì)其作宏置換。

#defineOK200

main()

{

printf(“OK”);

printf(“\n”);

}

上面定義宏名OK表示200,但在printf函數(shù)調(diào)用語(yǔ)句中OK被引號(hào)括起來(lái),因此,不作宏置換。

(5)宏定義必須寫在函數(shù)之外,其作用域?yàn)閺暮甓x命令起到源程序結(jié)束。如果要終止其作用域,可使用命令#undef撤銷已定義的宏。例如:

#definePI3.14

#undefPI

在#undef命令行之后的范圍,PI不再代表3.14。

(6)宏定義允許嵌套,在宏定義的字符串中可以使用已經(jīng)定義的宏名。在宏展開(kāi)時(shí),由預(yù)處理程序?qū)訉又脫Q。例如:

#definePI3.14

#defineSPI*Y*Y

printf(“%f”,S);

在宏展開(kāi)后表示如下:

printf("%f",3.14*Y*Y);

(7)宏定義是專門用于預(yù)處理命令的一個(gè)專用名詞,它與定義變量的含義不同,只進(jìn)行字符替換,不分配內(nèi)存空間。

在程序中使用宏定義,有以下幾個(gè)優(yōu)點(diǎn):

(1)能提高源程序的可讀性。例如,對(duì)于以下語(yǔ)句:

return(2.0*3.1415926*3.0);和return(3.1415926*3.0*3.0);

編程人員能否很快地看出其意義呢?顯然不能。但如果寫成下面的形式:

return(2.0*PI*RADIUS);和return(PI*RADIUS*RADIUS);

編程人員就能一眼看出,這是在計(jì)算圓周長(zhǎng)和圓面積。

(2)能提高源程序的可移植性。如要將RADIUS的值由3.0修改為4.0,只要在#define命令中修改一處便可。而在不使用宏定義的文件中,則要將多處的3.0修改為4.0。9.1.2帶參數(shù)的宏定義

C語(yǔ)言中允許宏帶有參數(shù)。在宏定義中參數(shù)稱為形式參數(shù),在宏調(diào)用中的參數(shù)稱為實(shí)際參數(shù)。對(duì)于帶參數(shù)的宏,在調(diào)用時(shí)不僅要進(jìn)行宏展開(kāi),而且還要進(jìn)行參數(shù)替換。

帶參宏定義的一般形式如下:

#define宏名(形參表)字符串

在字符串中含有各個(gè)形參,帶參宏調(diào)用的一般形式如下:

宏名(實(shí)參表)

【例9-2】

用帶參數(shù)的宏定義編程,輸入圓的半徑,計(jì)算圓的面積。

#include<stdio.h>

#definePI3.1415926

#defineS(r)PI*r*r

main()

{ floata,radius;

printf(“請(qǐng)輸入圓半徑:”);

scanf(“%f”,&radius);

a=S(radius);

printf(“圓的面積為:%.2f\n”,a);

}

圖9-2例9-2程序運(yùn)行結(jié)果

帶參數(shù)的宏定義的幾點(diǎn)說(shuō)明:

(1)宏名和形參列表之間不能有空格出現(xiàn)。例如,把“#defineS(r)PI*r*r”寫為“#defineS(r)PI*r*r”將被認(rèn)為是無(wú)參數(shù)的宏定義,宏名S將代表字符串“(r)PI*r*r”。

(2)形式參數(shù)不分配內(nèi)存單元,因此不必進(jìn)行類型定義。而宏調(diào)用中的實(shí)參有具體的值,要用它們?nèi)ブ脫Q形參,因此需要進(jìn)行類型說(shuō)明。

(3)在宏定義中,字符串內(nèi)的形參通常用括號(hào)括起來(lái)以避免出錯(cuò)。

【例9-3】如果長(zhǎng)方形的長(zhǎng)原本是4,寬原本是3,現(xiàn)長(zhǎng)增加2,寬增加1,編程計(jì)算長(zhǎng)方形的面積。

#include<stdio.h>

#defineS(a,b)a*b

main()

{ intlen,wid,area;

printf("請(qǐng)輸入增加的長(zhǎng)和寬值:");

scanf("%d%d",&len,&wid);

area=S(4+len,3+wid);

printf("area=%d\n",area);

}圖9-3例9-3程序運(yùn)行結(jié)果

該程序在進(jìn)行宏展開(kāi)時(shí),用4+len置換a,用3+wid置換b,再用a*b置換S(a,b),得到如下語(yǔ)句:

area=4+len*3+wid;

即area=4+2*3+1=11。

該結(jié)果顯然不是預(yù)期的結(jié)果。在C語(yǔ)言中,帶參數(shù)的宏定義在調(diào)用時(shí),實(shí)參不會(huì)把值傳遞給形參,而只是做簡(jiǎn)單的替換。如果把宏定義中的參數(shù)加上括號(hào),那結(jié)果就不一樣了,即改寫成如下形式:

#defineS(a,b)(a)*(b)

而其他不變,那么宏展開(kāi)之后將變成如下形式:

area=(4+len)*(3+wid);

即area=(4+2)*(3+1)=24。

初學(xué)者容易把帶參數(shù)的宏與函數(shù)混淆。確實(shí)它們之間有一些類似之處,在調(diào)用函數(shù)時(shí)也是在函數(shù)名后的括號(hào)中寫出實(shí)參,也要求實(shí)參與形參的數(shù)目相等。但是,帶參的宏定義與函數(shù)是不同的,其不同之處主要有以下幾點(diǎn):

(1)函數(shù)在調(diào)用時(shí),先求出實(shí)參表達(dá)式的值,然后再代入形參。而使用帶參的宏只是進(jìn)行簡(jiǎn)單的字符替換。

(2)函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,為形參分配臨時(shí)的內(nèi)存單元。而宏展開(kāi)則是在編譯前進(jìn)行的,在展開(kāi)時(shí)并不分配內(nèi)存單元,并且不進(jìn)行值的傳遞處理,也沒(méi)有“返回值”的概念。

(3)函數(shù)中的實(shí)參和形參都要定義類型,二者的類型要求一致,如果不一致,則應(yīng)進(jìn)行類型轉(zhuǎn)換。而宏不存在類型問(wèn)題,宏名無(wú)類型,它的形參也無(wú)類型,只是一個(gè)符號(hào)代碼,展開(kāi)時(shí)代入指定的字符串即可。宏定義時(shí),字符串可以是任何類型的數(shù)據(jù)。例如:

#defineCLC_LANGUAGE (字符)

#defineX4.3

(數(shù)值)

其中,CL和X不需要定義類型,它們不是變量,在程序中凡遇CL均以C_LANGUAGE代之,凡遇X均以4.3代之,顯然不需定義類型。對(duì)帶參數(shù)的宏同樣如此,例如:

#defineS(r)PI*r*r

其中,r也不是變量,如果在語(yǔ)句中有S(3.6),則展開(kāi)后為PI*3.6*3.6,語(yǔ)句中并不出現(xiàn)r,當(dāng)然也不必定義r。

(4)調(diào)用函數(shù)只能得到一個(gè)返回值,而用宏可以得到幾個(gè)結(jié)果。

【例9-4】計(jì)算圓的周長(zhǎng)、面積和圓球的體積。

#include<stdio.h>

#definePI3.1415926

#defineCIRCLE(R,L,S,V)L=2*PI*R;S=PI*R*R;V=4.0/3.0*PI*R*R*R

main()

{ floatr,l,s,v;

scanf("%f",&r);

CIRCLE(r,l,s,v);

printf("r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2f\n",r,l,s,v);

}

經(jīng)預(yù)編譯宏展開(kāi)后源程序變成如下形式:

#include<stdio.h>

main()

{ floatr,l,s,v;

scanf("%f",&r);

l=2*3.1415926*r;s=3.1415926*r*r;v=4.0/3.0*3.1415926*r*r*r;

printf("r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2f\n",r,l,s,v);

}

圖9-4例9-4程序運(yùn)行結(jié)果

實(shí)參r的值已知,可以從宏返回三個(gè)值:l、s、v。其實(shí),這只不過(guò)是字符置換而己,即將字符r置換R,l置換L,s置換S,v置換V,而并未在宏展開(kāi)時(shí)求出l、s、v的值。

(5)使用宏次數(shù)多時(shí),宏展開(kāi)后源程序變長(zhǎng),因?yàn)槊空归_(kāi)一次都使程序變長(zhǎng),而函數(shù)調(diào)用則不使源程序變長(zhǎng)。

(6)宏替換不占用運(yùn)行時(shí)間,只占用編譯時(shí)間,而函數(shù)調(diào)用則占用運(yùn)行時(shí)間(分配單元、保留現(xiàn)場(chǎng)、值傳遞、返回)。

一般用宏來(lái)代表簡(jiǎn)短的表達(dá)式比較合適。有些問(wèn)題,使用宏和函數(shù)都可以解決。例如:

#defineMAX(x,y)(x)>(y)?(x):(y)

main()

{ inta,b,c,d,t;

t=MAX(a+b,c+d);

}

賦值語(yǔ)句展開(kāi)后如下:

t=(a+b)>(c+d)?(a+b):(c+d);

MAX不是函數(shù),程序中只有一個(gè)main函數(shù),在main函數(shù)中就能求出t的值。這個(gè)問(wèn)題也可用函數(shù)的形式表示:

intmax(intx,inty)

{return(x>y?x:y);}

main()

{ inta,b,c,d,t;

t=max(a+b,c+d);

}

max是函數(shù),在main函數(shù)中調(diào)用max函數(shù)求出t的值。

如果善于利用宏定義,可以實(shí)現(xiàn)程序的簡(jiǎn)單化。例如,事先將程序中的“輸出格式”定義好,可以減少在輸出語(yǔ)句中每次都要寫出具體輸出格式的麻煩。 9.2文件包含

文件包含是C編譯預(yù)處理的另一個(gè)重要功能。文件包含是指一個(gè)源文件可以將另一個(gè)源文件的全部?jī)?nèi)容包含進(jìn)來(lái),即將另外的文件包含到本文件之中。

文件包含命令的一般形式如下:

#include“包含文件名”

#include<包含文件名>

以上兩種格式的區(qū)別如下:

(1)使用雙引號(hào):系統(tǒng)首先到當(dāng)前目錄下查找被包含文件,如果沒(méi)找到,再到系統(tǒng)指定的包含文件目錄(由用戶在配置環(huán)境時(shí)設(shè)置)中查找。

(2)使用尖括號(hào):直接到系統(tǒng)指定的包含文件目錄中查找(該方式為標(biāo)準(zhǔn)方式)。

一般來(lái)說(shuō),如果要包含庫(kù)函數(shù),宜用尖括號(hào);如果要包含用戶自己編寫的文件,宜用雙引號(hào)。大多數(shù)情況下,使用雙引號(hào)比較保險(xiǎn)。

【例9-5】編寫程序,比較兩個(gè)整數(shù)的值,求出其中較大的值,保存為文件“max.cpp”。

/*求兩個(gè)整數(shù)中較大數(shù)的程序max.cpp*/

max(intx,inty)

{ intm;

m=x;

if(y>x)

m=y;

return(m);

}

【例9-6】利用例9-5中的文件,編寫程序計(jì)算三個(gè)整數(shù)中最大的數(shù),并輸出該數(shù)。

#include<stdio.h>

#include“max.cpp”

main()

{ inta,b,c,z;

printf("請(qǐng)輸入三個(gè)整數(shù):");

scanf("%d,%d,%d",&a,&b,&c);

z=max(a,b);

if(z<c)

z=c;

printf("最大數(shù)為:%d\n",z);

}

圖9-5例9-6程序運(yùn)行結(jié)果

文件包含命令的功能是把指定的文件插入到該命令行位置取代該命令行,從而把指定的文件和當(dāng)前的源程序文件連成一個(gè)源文件。在程序設(shè)計(jì)中,文件包含是很有用的。一個(gè)大的程序可以分為多個(gè)模塊,由多個(gè)程序員分別編程。有些公用的符號(hào)常量或宏定義等可單獨(dú)組成一個(gè)文件,在其他文件的開(kāi)頭用包含命令包含該文件即可使用。這樣,可避免在每個(gè)文件開(kāi)頭都要書(shū)寫那些公用部分,從而避免重復(fù)編寫,并減少出錯(cuò)。

下面是關(guān)于文件包含命令的幾點(diǎn)說(shuō)明。

(1)編譯預(yù)處理時(shí),預(yù)處理程序?qū)⒉檎抑付ǖ谋话募?,并將其?fù)制到#include命令出現(xiàn)的位置上,如圖9-6所示。圖9-6文件包含編譯預(yù)處理

在進(jìn)行編譯預(yù)處理時(shí),要對(duì)#include命令進(jìn)行文件包含處理,即將file2.cpp的全部?jī)?nèi)容復(fù)制插入到“#include“f

溫馨提示

  • 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)論