版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第十一部分 編譯預(yù)處理 preprocessing 一、編譯預(yù)處理簡介 在編譯之前,對高級語言程序的源 代碼進(jìn)行的加工,生成編譯器能處 理的代碼的過程。 C語言 源程序 編譯 目標(biāo) 模塊 連接 可執(zhí)行 程序 函數(shù)庫 C程序加工過程 編譯之前還有 一個(gè)源代碼預(yù) 加工的過程 有預(yù)處 理命令 的C源 程序 編譯 目標(biāo) 模塊 連接 可執(zhí)行 程序 函數(shù)庫 C程序加工過程包含有編譯前的預(yù)處理的功能 預(yù)處理 沒有預(yù) 處理命 令的C 源程序 最先做的步驟,預(yù) 處理程序負(fù)責(zé)處理 源程序里的所有預(yù) 處理命令,生成不 含預(yù)處理命令的源 程序。 預(yù)處理命令加在程序中 指示IDE的預(yù)處理程序進(jìn) 行代碼處理工作的指令。
2、預(yù)處理命令作用:簡化編 程工作 5 C預(yù)處理命令 nC源程序中以字符源程序中以字符#開始的命令即為預(yù)處理命令開始的命令即為預(yù)處理命令 n常見的預(yù)處理命令有常見的預(yù)處理命令有 #include#if #else #elif #endif #ifdef #ifndef #define #undef 問題:為什么叫命令?命令誰做事情? 二、C的文件包含 #include 7 把指定文件內(nèi)容包含到當(dāng)前源文件把指定文件內(nèi)容包含到當(dāng)前源文件 #include #include 形式形式1 1 #include #include 文件名文件名 形式形式2 2 形式形式1 1:用于包含系統(tǒng)頭文件,預(yù)處理程序到
3、指定目錄找文件(用于包含系統(tǒng)頭文件,預(yù)處理程序到指定目錄找文件( 通常指定幾個(gè)系統(tǒng)文件目錄)。通常指定幾個(gè)系統(tǒng)文件目錄)。 Tools-Options-Directories- C:Program FilesMicrosoft Visual StudioVC98INCLUDE C:Program FilesMicrosoft Visual StudioVC98MFCINCLUDE C:Program FilesMicrosoft Visual StudioVC98ATLINCLUDE 1. 文件包含命令語法文件包含命令語法 形式形式2 2:用于包含自己的文件。預(yù)處理程序先在源文件所在的目用于包
4、含自己的文件。預(yù)處理程序先在源文件所在的目 錄里找,找不到時(shí)再到系統(tǒng)指定目錄中去找。錄里找,找不到時(shí)再到系統(tǒng)指定目錄中去找。 8 在文件系統(tǒng)中查找指定的文件在文件系統(tǒng)中查找指定的文件 如果找到,就用找到的文件的內(nèi)容如果找到,就用找到的文件的內(nèi)容 取代整個(gè)文件包含命令行。取代整個(gè)文件包含命令行。 被包含文件里如果也有預(yù)處理行也被包含文件里如果也有預(yù)處理行也 會嵌套處理。會嵌套處理。 2. 預(yù)處理過程預(yù)處理過程 #include “abc.h” double area(double r) return PI * r * r; abc.cpp 在操作系統(tǒng)文件 系統(tǒng)中尋找頭文 件 如果找到,用相應(yīng) 的
5、頭文件里的內(nèi)容 替代包含命令。 double area(double r); int func2(); void func3(); enum YES, NO; #define PI 3.14159 繼續(xù)處理 abc.h 文件包含處理過程及示例 double area(double r); int func2(); void func3(); enum YES, NO; #define PI 3.14159 double area(double r) return PI * r * r; 處理后的abc.cpp 10 stdio.hstdio.h或或math.h math.h 為標(biāo)準(zhǔn)頭文件(為標(biāo)
6、準(zhǔn)頭文件(.h .h 擴(kuò)展名),它們在系統(tǒng)子擴(kuò)展名),它們在系統(tǒng)子 目錄里(目錄名為目錄里(目錄名為 includeinclude或或h h),這些文件中的內(nèi)容一般包),這些文件中的內(nèi)容一般包 括括 l標(biāo)準(zhǔn)函數(shù)原型標(biāo)準(zhǔn)函數(shù)原型 l系統(tǒng)使用的符號常量定義等。系統(tǒng)使用的符號常量定義等。 預(yù)處理時(shí),文件內(nèi)容插入到預(yù)處理命令行處。相當(dāng)于在源文預(yù)處理時(shí),文件內(nèi)容插入到預(yù)處理命令行處。相當(dāng)于在源文 件中寫這些函數(shù)原型,使編譯程序能正確完成對標(biāo)準(zhǔn)庫函數(shù)件中寫這些函數(shù)原型,使編譯程序能正確完成對標(biāo)準(zhǔn)庫函數(shù) 調(diào)用的處理。調(diào)用的處理。 #include #include 注意:注意:寫程序時(shí)一定要包含必要的系統(tǒng)頭
7、文件寫程序時(shí)一定要包含必要的系統(tǒng)頭文件。 說明說明 三、宏定義與宏替換 #define #undef 12 簡單宏定義簡單宏定義,形式:,形式: #define #define 宏名字宏名字 替代正文替代正文 替代正文替代正文可以是任意正文序列,到換行為止。可以是任意正文序列,到換行為止。 如最后是如最后是“”,下一行還作為宏定義的繼續(xù)。,下一行還作為宏定義的繼續(xù)。 作用作用:為:為宏名字宏名字定義替代,由整個(gè)定義替代,由整個(gè)替代正文替代正文構(gòu)成構(gòu)成。 預(yù)處理程序記錄宏名字及其替代。在源程序中遇到預(yù)處理程序記錄宏名字及其替代。在源程序中遇到宏名字宏名字標(biāo)識標(biāo)識 符時(shí),就用符時(shí),就用替代正文替代
8、正文替換,替換,這種操作稱為宏展開或宏替換這種操作稱為宏展開或宏替換。 1. 常見宏定義與宏替換常見宏定義與宏替換 13 注意 n替代正文里也允許出現(xiàn)宏名字,替代正 文里宏名字會被展開。 n程序中的字符串如果有與宏名相同的串, 將不會做替換。 n人們常用這種方式定義符號常量。 #define NUM 30 14 #define NUM 30 #define SLD static long double #define NOSTOP while(1) 程序中的:程序中的: SLD x=2.4, y=9.16; 替換后變成:替換后變成: static long double x=2.4, y=9.
9、16; 后無后無 ; 預(yù)處理程序做正文預(yù)處理程序做正文替換替換,替代正文替代正文可以是任何內(nèi)容??梢允侨魏蝺?nèi)容。 例,可以寫如下形式的定義例,可以寫如下形式的定義 #define NOSTOP while(1) #include “abc.h” double area(double r) return PI * r * r; abc.cpp double area(double r); int func2(); void func3(); enum YES, NO; #define PI 3.14159 abc.h 宏定義及宏替換 double area(double r); int func
10、2(); void func3(); enum YES, NO; #define PI 3.14159 double area(double r) return PI * r * r; 包含后的abc.cpp double area(double r); int func2(); void func3(); enum YES, NO; double area(double r) return 3.14159 * r * r; 宏替換后的abc.cpp 16 2. 帶參數(shù)宏定義(慎用) n#define 宏名字(參數(shù)列表) 替代正文 n注意 n宏名字與括號間不能有空格 n用逗號分隔的標(biāo)識符看作參
11、數(shù)。 n替換正文為任意正文序列。 n例 n#define MIN(A,B) (A)(B)?(A):(B) n也被人稱為Pseudo-functions,假函數(shù),偽 函數(shù) 17 帶參宏的使用 n使用形式 n與函數(shù)調(diào)用類似,以類似參數(shù)的形式給出宏參 數(shù)的替代片段,用逗號分隔多個(gè)數(shù),稱為宏調(diào) 用。 n例 nx = MIN(y, z); n預(yù)處理器對源代碼中的宏調(diào)用的宏替換(宏展開) 過程分兩步展開 n先用各實(shí)參替代宏定義替代正文里的參數(shù); n再將代換的結(jié)果放在宏調(diào)用位置(因此并非函數(shù)調(diào)用) 18 帶參宏與函數(shù)調(diào)用不同 n帶參宏只是在程序預(yù)加工階段對用戶寫的源 代碼進(jìn)行處理,按帶參宏的展開規(guī)劃處理程
12、序源代碼,與函數(shù)調(diào)用完全不同。 n不會在程序執(zhí)行階段產(chǎn)生與函數(shù)一樣的調(diào)用動 作。 n因?yàn)橹蛔鲎址鎿Q,宏定義和調(diào)用中不涉及 類型問題。 n一個(gè)宏能否使用、使用中發(fā)生什么、能否得 到預(yù)期效果,完全看展開后的情況。 19 帶參宏的效率與限制 nPreprocessor functions, which are usually called macros or pseudo-functions, are considerably more efficient that standard C functions but also more restrictive. nEfficient:不是函數(shù)調(diào)用
13、,省去函數(shù)調(diào)用與返回 所需的時(shí)間與空間開銷 nRestrictive:不是函數(shù)調(diào)用,僅是替換,不具有 函數(shù)的靈活性,只適合非常簡單的小功能。不 小心會帶來許多注意不到問題 20 例,帶參宏定義與展開 n#define MIN(A,B) (A)(B)?(A):(B) 為什么加 括號? z = MIN(x + y, x * y); z = (x + y)(x * y)?(x + y):(x * y); 宏替換 預(yù)處理前的源代碼 預(yù)處理后的程序代碼 看上去像是函 數(shù)調(diào)用,是嗎? 根本不是函數(shù)調(diào)用 21 使用括號避免出錯(cuò) n替代正文各參數(shù)和整段應(yīng)括起,避免出錯(cuò)。 例如 n#define SQUARE(
14、x) x * x n在特定環(huán)境下可能出問題, n例如 nz = SQUARE(a + b); n展開后變成 nz = a + b * a + b; 明顯錯(cuò)了 22 慎重使用宏展開 n注意,宏展開可能會引起多次計(jì)算帶來意外的很 難發(fā)現(xiàn)的錯(cuò)誤,要慎重使用 n#define MIN(A,B) (A)(B)?(A):(B) z = (n+) (m+)?(n+):(m+); 宏替換 預(yù)處理前的源代碼 預(yù)處理后的程序代碼 z = MIN(n+, m+); 23 3. 宏名字定義 n#define 標(biāo)識符 n定義一個(gè)標(biāo)識符,告訴預(yù)編譯器定義了這樣的名 字。通過判定是否存在某宏名,配合#if, #ifdef,
15、 #ifndef等實(shí)現(xiàn)一些特定編譯預(yù)處理目的 n如設(shè)LabFunctions.h中有如下代碼 n#ifndef LABFUNCTIONS_H_ n#define LABFUNCTIONS_H_ n n#endif 判定是否曾定義過 LABFUNCTIONS_H_ 如果沒有定義過, 則定義一個(gè)這樣的 標(biāo)識符 目的:避免頭文件的重復(fù)包含以免產(chǎn)生問題 24 4. #undef與defined n宏定義可以取消,語法 n#undef 宏名字 n功能:取消已有宏名字定義 n特殊謂詞defined,使用形式 ndefined 標(biāo)識符 ndefined(標(biāo)識符) n當(dāng)標(biāo)識符是有定義的宏名字時(shí),defined
16、(標(biāo) 識符) 得到1,否則得0 25 5. 說明 n帶參宏的展開可避免函數(shù)調(diào)用開銷,但將使最終 的源程序變長。 n復(fù)雜宏定義展開后出錯(cuò)很難定位。 n應(yīng)謹(jǐn)慎使用(盡量少使用)宏。 n寫宏定義的常見錯(cuò)誤是在定義行最后寫分號。該 分號將被代入程序,有可能引起語法錯(cuò)誤。 n宏定義從定義處起作用直到文件結(jié)束。 n一個(gè)文件里不允許對同一宏名字重復(fù)定義。 26 1. 1.宏名一般都用大寫字母表示,以區(qū)別于變量宏名一般都用大寫字母表示,以區(qū)別于變量; ; 2.2.宏定義只是替代宏定義只是替代, ,減少了在程序中書寫的工作量減少了在程序中書寫的工作量, ,只是一個(gè)簡只是一個(gè)簡 單的代替單的代替, ,不作語法檢查
17、不作語法檢查; ; 3.3.宏定義不是語句宏定義不是語句, ,不必再其后加上不必再其后加上“;”;”; 4.4.在宏定義中可以進(jìn)行多層的替代在宏定義中可以進(jìn)行多層的替代. . #definre R3.0 #define PI3.1415 #define L2*PI*R #define SPI*R*R main() printf(“L=%fnS=%fn”, L, S); 27 例例 #include #define PI 3.1415 #define S(r) PI*r*r int main() double a, area; a = 3.6; area = S(a); printf(“r=%f
18、narea=%fn”, a, area); return 0; 28 例例 #include #define M3 #define NM+2 #define S(N) N*N*N int main() printf(%dn,S(N); return 0; 運(yùn)行結(jié)果為:運(yùn)行結(jié)果為:17 四、條件編譯命令 30 條件編譯條件編譯 一、引入條件編譯的原因:一、引入條件編譯的原因: 只對源程序中滿足條件的部分內(nèi)容進(jìn)行編譯。只對源程序中滿足條件的部分內(nèi)容進(jìn)行編譯。 可以減少被編譯的語句,從而減少目標(biāo)程序的長度??梢詼p少被編譯的語句,從而減少目標(biāo)程序的長度。 二、定義形式:二、定義形式: 31 程序段可以
19、是語句串,也可以是命令行程序段可以是語句串,也可以是命令行 方式方式3 3為嵌套定義為嵌套定義 方式方式2 2: #if #if 整型表達(dá)式整型表達(dá)式 程序段程序段1 1 #else#else 程序段程序段2 2 #endif#endif 方式方式1 1: #if #if 整型表達(dá)式整型表達(dá)式 程序段程序段1 1 #endif#endif 方式方式3 3: #if 整型表達(dá)式整型表達(dá)式 程序段程序段1 #elif 整型表達(dá)式整型表達(dá)式 程序段程序段2 #elif 整型表達(dá)式整型表達(dá)式 程序段程序段3 #else 程序段程序段n #endif 32 #ifdef 標(biāo)識符標(biāo)識符相當(dāng)于相當(dāng)于 #if
20、 defined(標(biāo)識符標(biāo)識符) #ifndef 標(biāo)識符標(biāo)識符 相當(dāng)于相當(dāng)于 #if !defined(標(biāo)識符標(biāo)識符) 方式方式4 4: #ifdef #ifdef 標(biāo)識符標(biāo)識符 程序段程序段1 1 #else#else 程序段程序段2 2 #endif#endif 方式方式5 5: #ifndef #ifndef 標(biāo)識符標(biāo)識符 程序段程序段1 1 #else#else 程序段程序段2 2 #endif#endif 33 #define COMPUTER_A 1 #ifdef COMPUTER_A #define INTEGER_SIZE 16 #else #define INTEGER_SIZE 20 #endif #define DEBUG 1 #ifdef DEBUG printf(“x=%d,y=%d,z=%dn”, x, y, z); #endif 預(yù)處理后只剩下預(yù)處理后只剩下#define INTEGER_SIZE 16參與編譯參與編譯 預(yù)處理后預(yù)處理后printf參與編譯參與編譯,若不在希望編譯若不在希望編譯printf得到得到 輸出,則刪除輸出,則刪除#define DEBUG 1命令行。命令行。 34 例例 #define LETTER 1 int main() char c; int i = 0; while(
溫馨提示
- 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é)《影像診斷學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《數(shù)據(jù)庫管理》2021-2022學(xué)年期末試卷
- 石河子大學(xué)《景觀生態(tài)學(xué)原理》2022-2023學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《數(shù)據(jù)庫原理》2023-2024學(xué)年期末試卷
- 沈陽理工大學(xué)《化工原理A》2021-2022學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《電路實(shí)驗(yàn)》2021-2022學(xué)年期末試卷
- 沈陽理工大學(xué)《產(chǎn)品語義學(xué)應(yīng)用設(shè)計(jì)》2021-2022學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《nux系統(tǒng)程序設(shè)計(jì)》2023-2024學(xué)年期末試卷
- 合伙承包高鈣粉合同
- 同步新課堂高中歷史專題二近代中國維護(hù)國家主權(quán)的斗爭課時(shí)訓(xùn)練7偉大的抗日戰(zhàn)爭含解析人民版必修1
- 膽管癌的CT診斷與鑒別診斷知識ppt
- SJG 77-2020 房屋建筑工程造價(jià)文件分部分項(xiàng)和措施項(xiàng)目劃分標(biāo)準(zhǔn)-高清現(xiàn)行
- 水平四(九年級)體育《耐力跑》教學(xué)設(shè)計(jì)及教案
- 有限空間作業(yè)流程圖
- 《化學(xué)反應(yīng)工程》課件第二章 氣-固相催化反應(yīng)本征及宏觀動力學(xué)(簡明)
- 第13課__生活與科幻
- 新《行政處罰法》修訂對比解讀PPT課件
- 交互分配法教案
- 材料力學(xué)內(nèi)部習(xí)習(xí)題集及問題詳解
- 《電磁屏蔽技術(shù)》PPT課件
- 正常胃鏡圖片及常見病變
評論
0/150
提交評論