譚浩強(qiáng)C程序設(shè)計(jì)第三版清華課件第9章預(yù)處理_第1頁(yè)
譚浩強(qiáng)C程序設(shè)計(jì)第三版清華課件第9章預(yù)處理_第2頁(yè)
譚浩強(qiáng)C程序設(shè)計(jì)第三版清華課件第9章預(yù)處理_第3頁(yè)
譚浩強(qiáng)C程序設(shè)計(jì)第三版清華課件第9章預(yù)處理_第4頁(yè)
譚浩強(qiáng)C程序設(shè)計(jì)第三版清華課件第9章預(yù)處理_第5頁(yè)
已閱讀5頁(yè),還剩25頁(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、本章要點(diǎn)9.1 9.1 宏定義宏定義9.29.2“文件包含文件包含”處理處理9.3 9.3 條件編譯條件編譯4基本概念基本概念 ansi c標(biāo)準(zhǔn)規(guī)定可以在源程序中加入一些“預(yù)處理命令” ,以改進(jìn)程序設(shè)計(jì)環(huán)境,提高編程效率。 這些預(yù)處理命令是由ansi c統(tǒng)一規(guī)定的,但是它不是c語(yǔ)言本身的組成部分,不能直接對(duì)它們進(jìn)行編譯(因?yàn)榫幾g程序不能識(shí)別它們)。必須在對(duì)程序進(jìn)行通常的編譯之前,先對(duì)程序中這些特殊的命令進(jìn)行“預(yù)處理”。 經(jīng)過(guò)預(yù)處理后程序可由編譯程序?qū)︻A(yù)處理后的源程序進(jìn)行通常的編譯處理,得到可供執(zhí)行的目標(biāo)代碼。 5基本概念基本概念 c語(yǔ)言與其他高級(jí)語(yǔ)言的一個(gè)重要區(qū)別是可以使用預(yù)處理命令和具有預(yù)處

2、理的功能。提供的預(yù)處理功能主要有以下三種:宏定義文件包含條件編譯 這些功能分別用宏定義命令、文件包含命令、條件編譯命令來(lái)實(shí)現(xiàn)。為了與一般語(yǔ)句相區(qū)別,這些命令以符號(hào)“”開頭。例如: #define #include 69.1.1 不帶參數(shù)的宏定義不帶參數(shù)的宏定義 宏定義一般形式為:definedefine 標(biāo)識(shí)符標(biāo)識(shí)符 字符串字符串例如:例如: define pi 3.1415926define pi 3.1415926 宏定義的作用是在本程序文件中用指定的標(biāo)識(shí)符pi來(lái)代替“3.1415926”這個(gè)字符串,在編譯預(yù)處理時(shí),將程序中在該命令以后出現(xiàn)的所有的pi都用“3.1415926”代替。這種方

3、法使用戶能以一個(gè)簡(jiǎn)單的名字代替一個(gè)長(zhǎng)的字符串。 這個(gè)標(biāo)識(shí)符(名字)稱為“宏名”。 在預(yù)編譯時(shí)將宏名替換成字符串的過(guò)程稱為“宏展開”。define是宏定義命令。7#include #define pi 3.1415926#define pi 3.1415926 void main() float l,s,r,v; printf(input radius:); scanf(%f,&r); l=2.0*pi*r; s=pi*r*r; v=4.0/3*pi*r*r*r;printf(l=%10.4fns=%10.4fnv=%10.4fn,l,s,v);例例9.1 9.1 使用不帶參數(shù)的宏定義。

4、使用不帶參數(shù)的宏定義。8input radius: 4 運(yùn)行情況如下:運(yùn)行情況如下:1=25.1328s=50.2655v=150.7966(1) 宏名一般習(xí)慣用大寫字母表示,以便與變量名相區(qū)別。但這并非規(guī)定,也可用小寫字母。(2) 使用宏名代替一個(gè)字符串,可以減少程序中重復(fù)書寫某些字符串的工作量。(3) 宏定義是用宏名代替一個(gè)字符串,只作簡(jiǎn)單置換,不作正確性檢查。只有在編譯已被宏展開后的源程序時(shí)才會(huì)發(fā)現(xiàn)語(yǔ)法錯(cuò)誤并報(bào)錯(cuò)。9(4) 宏定義不是語(yǔ)句,不必在行末加分號(hào)。如果加了分號(hào)則會(huì)連分號(hào)一起進(jìn)行置換。(5) definedefine命令出現(xiàn)在程序中函數(shù)的外面,宏名的有效范圍為定義命令之后到本源文

5、件結(jié)束。通常,definedefine命令寫在文件開頭,函數(shù)之前,作為文件一部分,在此文件范圍內(nèi)有效。(6) 可以用undefdef命令終止宏定義的作用域。例如: 10#define g 9.8 _ void main() g的有效范圍 - #undef g f1() 在在f1f1函數(shù)中,不再代表函數(shù)中,不再代表9.89.8。這樣可以靈活控制宏。這樣可以靈活控制宏定義的作用范圍。定義的作用范圍。11(7) 在進(jìn)行宏定義時(shí),可以引用已定義的宏名,可以層層置換。 #include #define r 3.0#define pi 3.1415926#define l 2*pi*r#define s

6、pi*r*rvoid main() printf(l=%fns=%fn,l,s);運(yùn)行情況如下:運(yùn)行情況如下:l=18.849556s=28.274333例例9.2 9.2 在宏定義中引用已定義的宏名。在宏定義中引用已定義的宏名。12經(jīng)過(guò)宏展開后,printf函數(shù)中的輸出項(xiàng)被展開為: 2*3.1415926*3.0展開為 3.1415926*3.0*3.0printf函數(shù)調(diào)用語(yǔ)句展開為:printf(“l(fā)=%fns=%fn”,2*3.1415926*3.0,3.1415926*3.0*3.0);13(8) 對(duì)程序中用雙撇號(hào)括起來(lái)的字符串內(nèi)的字符,即使與宏名相同,也不進(jìn)行置換。 (9) 宏定義是

7、專門用于預(yù)處理命令的一個(gè)專用名詞,它與定義變量的含義不同,只作字符替換,不分配內(nèi)存空間。149.1.2 帶參數(shù)的宏定義 作用:不是進(jìn)行簡(jiǎn)單的字符串替換,還要進(jìn)行參數(shù)替換。 帶參數(shù)的宏定義一般形式為:definedefine 宏名(參數(shù)表)宏名(參數(shù)表) 字符串字符串 字符串中包含在括弧中所指定的參數(shù)#define s(a,b) a*b area=s(3,2); 程序中用和分別代替宏定義中的形式參數(shù)和b,用*代替s(3,2) 。因此賦值語(yǔ)句展開為:area=3area=3* *2 2例:15 對(duì)帶實(shí)參的宏(如s(3,2),則按define命令行中指定的字符串從左到右進(jìn)行置換。若串中包含宏中的形參

8、(如a、b),則將程序中相應(yīng)的實(shí)參(可以是常量、變量或表達(dá)式)代替形參。如果宏定義中的字符串中的字符不是參數(shù)字符(如*中的*號(hào)),則保留。這樣就形成了置換的字符串。16#include #define pi 3.1415926 #define s(r) pi*r*r void main() float a,area; a=3.6; area=s(a); printf(r=%fnarea=%fn,a,area);運(yùn)行情況如下:運(yùn)行情況如下:=3.600000 area=40.715038例例9.3 9.3 使用帶參的宏使用帶參的宏賦值語(yǔ)句“area=s(a); ” 經(jīng)宏展開后為:area=3.1

9、415926area=3.1415926* * *; 17(1)對(duì)帶參數(shù)的宏展開只是將語(yǔ)句中的宏名后面括號(hào)內(nèi)的實(shí)參字符串代替definedefine 命令行中的形參。(2) 在宏定義時(shí),在宏名與帶參數(shù)的括弧之間不應(yīng)加空格,否則將空格以后的字符都作為替代字符串的一部分。 18(1) 函數(shù)調(diào)用時(shí),先求出實(shí)參表達(dá)式的值,然后代入形參。而使用帶參的宏只是進(jìn)行簡(jiǎn)單的字符替換。(2) 函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,為形參分配臨時(shí)的內(nèi)存單元。而宏展開則是在編譯前進(jìn)行的,在展開時(shí)并不分配內(nèi)存單元,不進(jìn)行值的傳遞處理,也沒有“返回值”的概念。(3) 對(duì)函數(shù)中的實(shí)參和形參類型要求一致。而宏名無(wú)類型,它的參數(shù)也無(wú)類

10、型,只是一個(gè)符號(hào)代表,展開時(shí)代入指定的字符串即可。宏定義時(shí),字符串可以是任何類型的數(shù)據(jù)。(4) 調(diào)用函數(shù)只可得到一個(gè)返回值,而用宏可以設(shè)法得到幾個(gè)結(jié)果。 19#include #include #define pi 3.1415926#define pi 3.1415926#define circle(r,l,s,v)#define circle(r,l,s,v) l=2l=2* *pipi* *r;s=pir;s=pi* *r r* *r;v=4.0/3.0r;v=4.0/3.0* *pipi* *r r* *r r* *r r void main() void main() float r

11、,l,s,v; float r,l,s,v; scanf(%f,&r); scanf(%f,&r); circle(r,l,s,v); circle(r,l,s,v); printf(r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2fnprintf(r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2fn,r,l,s,v);,r,l,s,v); 例例9.4 9.4 通過(guò)宏展開得到若干個(gè)結(jié)果。通過(guò)宏展開得到若干個(gè)結(jié)果。20void mainvoid main()() float r,l,s,v; float r,l,s,v; scanf(%f,&r);

12、 scanf(%f,&r); l=2l=2* *3.14159263.1415926* *r; r; s=3.1515926 s=3.1515926* *r r* *r;r; v=4.0/3/0 v=4.0/3/0* *3.14159263.1415926* *r r* *r r* *r;r; printf(r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2fn printf(r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2fn ,r,l,s,v);,r,l,s,v); 對(duì)宏進(jìn)行預(yù)編譯,展開后的對(duì)宏進(jìn)行預(yù)編譯,展開后的mainmain函數(shù)如下:函數(shù)如下:運(yùn)行情況如

13、下:運(yùn)行情況如下:3.5 r=3.50,l=21.99,s=38.48,v=179.5921(5) 使用宏次數(shù)多時(shí),宏展開后源程序長(zhǎng),因?yàn)槊空归_一次都使程序增長(zhǎng),而函數(shù)調(diào)用不會(huì)使源程序變長(zhǎng)。(6) 宏替換不占運(yùn)行時(shí)間,只占編譯時(shí)間。而函數(shù)調(diào)用則占運(yùn)行時(shí)間(分配單元、保留現(xiàn)場(chǎng)、值傳遞、返回)。 如果善于利用宏定義,可以實(shí)現(xiàn)程序的簡(jiǎn)化,如事先將程序中的“輸出格式”定義好,以減少在輸出語(yǔ)句中每次都要寫出具體的輸出格式的麻煩。22例例9.5 9.5 通過(guò)宏展開得到若干個(gè)結(jié)果。通過(guò)宏展開得到若干個(gè)結(jié)果。#include #include #define pr printf#define pr print

14、f#define nl n#define nl n#define d %d#define d %d#define d1 d nl#define d1 d nl#define d2 d d nl#define d2 d d nl#define d3 d d d nl#define d3 d d d nl#define d4 d d d d nl#define d4 d d d d nl#define s %s#define s %svoid main()void main() int a,b,c,d; int a,b,c,d; char string=china; char string=chi

15、na; a=1;b=2;c=3;d=4; a=1;b=2;c=3;d=4; pr(d1,a); pr(d1,a); pr(d2,a,b); pr(d2,a,b); pr(d3,a,b,c); pr(d3,a,b,c); pr(d4,a,b,c,d); pr(d4,a,b,c,d); pr(s,string); pr(s,string); 運(yùn)行時(shí)輸出結(jié)果:23 所謂“文件包含”處理是指一個(gè)源文件可以將另外一個(gè)源文件的全部?jī)?nèi)容包含進(jìn)來(lái)。語(yǔ)言提供了#include命令用來(lái)實(shí)現(xiàn)“文件包含”的操作。其一般形式為: #include #include 文件名文件名 或 #include #include

16、24例例9.6 9.6 將例將例9 95 5時(shí)格式宏做成頭文件,把它時(shí)格式宏做成頭文件,把它包含在用戶程序中。包含在用戶程序中。(1)(1)將格式宏做成頭文件將格式宏做成頭文件format.hformat.h #include #include #define pr printf#define pr printf#define nl n#define nl n#define d %d#define d %d#define d1 d nl#define d1 d nl#define d2 d d nl#define d2 d d nl#define d3 d d d nl#define d3 d

17、 d d nl#define d4 d d d d nl#define d4 d d d d nl#define s %s#define s %s(2)(2)主文件主文件file1.cfile1.c#include #include include format.hinclude format.hvoid main()void main() int a,b,c,d; int a,b,c,d; char string=china; char string=china; a=1;b=2;c=3;d=4; a=1;b=2;c=3;d=4; pr(d1,a); pr(d1,a); pr(d2,a,b)

18、; pr(d2,a,b); pr(d3,a,b,c); pr(d3,a,b,c); pr(d4,a,b,c,d); pr(d4,a,b,c,d); pr(s,string); pr(s,string); 25注意:注意: 在編譯時(shí)并不是分別對(duì)兩個(gè)文件分別進(jìn)行編譯,然后再將它們的目標(biāo)程序連接的,而是在經(jīng)過(guò)編譯預(yù)處理后將頭文件format.h包含到主文件中,得到一個(gè)新的源程序,然后對(duì)這個(gè)文件進(jìn)行編譯,得到一個(gè)目標(biāo)(.obj)文件。被包含的文件成為新的源文件的一部分,而單獨(dú)生成目標(biāo)文件。26(1) 一個(gè)#include命令只能指定一個(gè)被包含文件,如果要包含個(gè)文件,要用個(gè)#include命令。(2) 如果文件包含文件,而在文件中要用到文件的內(nèi)容,則可在文件中用兩個(gè)include命令分別包含文件和文件,而且文件應(yīng)出現(xiàn)在文件之前,即在file1.c中定義。(3) 在一個(gè)被包含文件中又可以包含另一個(gè)被包含文件,即文件包含是可以嵌套的。 2728(4) 在#include命令中,文件名可以用雙撇號(hào)或尖括號(hào)括起來(lái)。(5) 被包含文件(file2.h)與其所在的文件(即用#include命令的源文件file2.c),在預(yù)編譯后已成為同一個(gè)文件(而不是兩個(gè)文件)。因此,

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論