譚浩強(qiáng)C程序設(shè)計(jì)-第三版-清華課件-預(yù)處理_第1頁
譚浩強(qiáng)C程序設(shè)計(jì)-第三版-清華課件-預(yù)處理_第2頁
譚浩強(qiáng)C程序設(shè)計(jì)-第三版-清華課件-預(yù)處理_第3頁
譚浩強(qiáng)C程序設(shè)計(jì)-第三版-清華課件-預(yù)處理_第4頁
譚浩強(qiáng)C程序設(shè)計(jì)-第三版-清華課件-預(yù)處理_第5頁
已閱讀5頁,還剩25頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第九章,預(yù)處理命令,本章要點(diǎn),預(yù)處理的概念 C語言處理系統(tǒng)的預(yù)處理功能 預(yù)處理命令的使用,主要內(nèi)容,9.1 宏定義 9.2“文件包含”處理 9.3 條件編譯,基本概念,ANSI C標(biāo)準(zhǔn)規(guī)定可以在源程序中加入一些“預(yù)處理命令” ,以改進(jìn)程序設(shè)計(jì)環(huán)境,提高編程效率。 這些預(yù)處理命令是由ANSI C統(tǒng)一規(guī)定的,但是它不是C語言本身的組成部分,不能直接對它們進(jìn)行編譯(因?yàn)榫幾g程序不能識別它們)。必須在對程序進(jìn)行通常的編譯之前,先對程序中這些特殊的命令進(jìn)行“預(yù)處理”。 經(jīng)過預(yù)處理后程序可由編譯程序?qū)︻A(yù)處理后的源程序進(jìn)行通常的編譯處理,得到可供執(zhí)行的目標(biāo)代碼,基本概念,C語言與其他高級語言的一個重要區(qū)別是

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

3、長的字符串。 這個標(biāo)識符(名字)稱為“宏名”。 在預(yù)編譯時將宏名替換成字符串的過程稱為“宏展開”。define是宏定義命令,include #define PI 3.1415926 void main() float l,s,r,v; printf(input radius:); scanf(%f,例9.1 使用不帶參數(shù)的宏定義,input radius: 4,運(yùn)行情況如下,1=25.1328 s=50.2655 v=150.7966,1) 宏名一般習(xí)慣用大寫字母表示,以便與變量名相區(qū)別。但這并非規(guī)定,也可用小寫字母。 (2) 使用宏名代替一個字符串,可以減少程序中重復(fù)書寫某些字符串的工作量。

4、 (3) 宏定義是用宏名代替一個字符串,只作簡單置換,不作正確性檢查。只有在編譯已被宏展開后的源程序時才會發(fā)現(xiàn)語法錯誤并報錯,說明,4) 宏定義不是語句,不必在行末加分號。如果加了分號則會連分號一起進(jìn)行置換。 (5) define命令出現(xiàn)在程序中函數(shù)的外面,宏名的有效范圍為定義命令之后到本源文件結(jié)束。通常,define命令寫在文件開頭,函數(shù)之前,作為文件一部分,在此文件范圍內(nèi)有效。 (6) 可以用undef命令終止宏定義的作用域。 例如,說明,define G 9.8 _ void main() G的有效范圍 - #undef G f1(),在f1函數(shù)中,不再代表9.8。這樣可以靈活控制宏定義

5、的作用范圍,7) 在進(jìn)行宏定義時,可以引用已定義的宏名,可以層層置換,說明,include #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R void main() printf(L=%fnS=%fn,L,S);,運(yùn)行情況如下,L=18.849556 S=28.274333,例9.2 在宏定義中引用已定義的宏名,經(jīng)過宏展開后,printf函數(shù)中的輸出項(xiàng)被展開為: 2*3.1415926*3.0 展開為 3.1415926*3.0*3.0 printf函數(shù)調(diào)用語句展開為,printf(“L=%FNS=%fn”

6、, 2*3.1415926*3.0,3.1415926*3.0*3.0,8) 對程序中用雙撇號括起來的字符串內(nèi)的字符,即使與宏名相同,也不進(jìn)行置換。 (9) 宏定義是專門用于預(yù)處理命令的一個專用名詞,它與定義變量的含義不同,只作字符替換,不分配內(nèi)存空間,說明,9.1.2 帶參數(shù)的宏定義,作用:不是進(jìn)行簡單的字符串替換,還要進(jìn)行參數(shù)替換,帶參數(shù)的宏定義一般形式為,define 宏名(參數(shù)表) 字符串 字符串中包含在括弧中所指定的參數(shù),define S(a,b) a*b area=S(3,2,程序中用和分別代替宏定義中的形式參數(shù)和b,用*代替S(3,2) 。因此賦值語句展開為: area=3*2,

7、例,對帶實(shí)參的宏(如S(3,2),則按define命令行中指定的字符串從左到右進(jìn)行置換。若串中包含宏中的形參(如a、b),則將程序中相應(yīng)的實(shí)參(可以是常量、變量或表達(dá)式)代替形參。如果宏定義中的字符串中的字符不是參數(shù)字符(如*中的*號),則保留。這樣就形成了置換的字符串,對帶參的宏定義是這樣展開置換的,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)行情況如下,3.600000 area=40.7

8、15038,例9.3 使用帶參的宏,賦值語句“area=S(a); ” 經(jīng)宏展開后為: area=3.1415926,1)對帶參數(shù)的宏展開只是將語句中的宏名后面括號內(nèi)的實(shí)參字符串代替define 命令行中的形參。 (2) 在宏定義時,在宏名與帶參數(shù)的括弧之間不應(yīng)加空格,否則將空格以后的字符都作為替代字符串的一部分,說明,1) 函數(shù)調(diào)用時,先求出實(shí)參表達(dá)式的值,然后代入形參。而使用帶參的宏只是進(jìn)行簡單的字符替換。 (2) 函數(shù)調(diào)用是在程序運(yùn)行時處理的,為形參分配臨時的內(nèi)存單元。而宏展開則是在編譯前進(jìn)行的,在展開時并不分配內(nèi)存單元,不進(jìn)行值的傳遞處理,也沒有“返回值”的概念。 (3) 對函數(shù)中的實(shí)

9、參和形參類型要求一致。而宏名無類型,它的參數(shù)也無類型,只是一個符號代表,展開時代入指定的字符串即可。宏定義時,字符串可以是任何類型的數(shù)據(jù)。 (4) 調(diào)用函數(shù)只可得到一個返回值,而用宏可以設(shè)法得到幾個結(jié)果,帶參數(shù)的宏和函數(shù)的區(qū)別,include #define PI 3.1415926 #define CIRCLE(R,L,S,V) L=2*PI*R;S=PI*R*R;V=4.0/3.0*PI*R*R*R void main() float r,l,s,v; scanf(%f,例9.4 通過宏展開得到若干個結(jié)果,void main() float r,l,s,v; scanf(%f,對宏進(jìn)行預(yù)編

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

11、%d #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %s,void main() int a,b,c,d; char string=CHINA; a=1;b=2;c=3;d=4; PR(D1,a); PR(D2,a,b); PR(D3,a,b,c); PR(D4,a,b,c,d); PR(S,string);,運(yùn)行時輸出結(jié)果,所謂“文件包含”處理是指一個源文件可以將另外一個源文件的全部內(nèi)容包含進(jìn)來。語言提供了#include命令用來實(shí)現(xiàn)“文件包含”的操作,其一般形式為:

12、 #include 文件名 或 #include,9.2 “文件包含”處理,例9.6 將例95時格式宏做成頭文件,把它包含在用戶程序中,1)將格式宏做成頭文件format.h #include #define PR printf #define NL n #define D %d #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %s,2)主文件file1.c #include include format.h void main() int a,b,c,d; char s

13、tring=CHINA; a=1;b=2;c=3;d=4; PR(D1,a); PR(D2,a,b); PR(D3,a,b,c); PR(D4,a,b,c,d); PR(S,string);,注意: 在編譯時并不是分別對兩個文件分別進(jìn)行編譯,然后再將它們的目標(biāo)程序連接的,而是在經(jīng)過編譯預(yù)處理后將頭文件format.h包含到主文件中,得到一個新的源程序,然后對這個文件進(jìn)行編譯,得到一個目標(biāo)(.obj)文件。被包含的文件成為新的源文件的一部分,而單獨(dú)生成目標(biāo)文件,1) 一個#include命令只能指定一個被包含文件,如果要包含個文件,要用個#include命令。 (2) 如果文件包含文件,而在文件

14、中要用到文件的內(nèi)容,則可在文件中用兩個include命令分別包含文件和文件,而且文件應(yīng)出現(xiàn)在文件之前,即在file1.c中定義。 (3) 在一個被包含文件中又可以包含另一個被包含文件,即文件包含是可以嵌套的,說明,4) 在#include命令中,文件名可以用雙撇號或尖括號括起來。 (5) 被包含文件(file2.h)與其所在的文件(即用#include命令的源文件file2.c),在預(yù)編譯后已成為同一個文件(而不是兩個文件)。因此,如果file2.h中有全局靜態(tài)變量,它也在file1.h文件中有效,不必用extern聲明,說明,9. 條件編譯,概念:所謂“條件編譯”,是對部分內(nèi)容指定編譯的條件,使其只在滿足一定條件才進(jìn)行編譯,條件編譯命令的幾種形式,1)ifdef 標(biāo)識符 程序段 else 程序段 endif,2)ifndef 標(biāo)識符 程序

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論