C語言深入探究程序的編譯之預(yù)處理_第1頁
C語言深入探究程序的編譯之預(yù)處理_第2頁
C語言深入探究程序的編譯之預(yù)處理_第3頁
C語言深入探究程序的編譯之預(yù)處理_第4頁
C語言深入探究程序的編譯之預(yù)處理_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第C語言深入探究程序的編譯之預(yù)處理目錄1.程序的翻譯環(huán)境和執(zhí)行環(huán)境2.詳解編譯與鏈接2.1翻譯環(huán)境2.2編譯本身也分為幾個階段2.3運(yùn)行環(huán)境3.預(yù)處理詳解3.1預(yù)處理符號3.2#define3.2.1#define定義標(biāo)識符3.2.2#define定義宏3.2.3#define的替換規(guī)則3.2.4宏和函數(shù)對比3.2.5命名約定3.3#undef3.4條件編譯

1.程序的翻譯環(huán)境和執(zhí)行環(huán)境

在ANSIC中任何一種實現(xiàn)中,存在兩個不同的環(huán)境.

第一種是翻譯環(huán)境,在這個環(huán)境中源代碼被轉(zhuǎn)換為可執(zhí)行的機(jī)器指令

第二種執(zhí)行環(huán)境,它用于實際執(zhí)行代碼。

2.詳解編譯與鏈接

2.1翻譯環(huán)境

1.組成一個程序的每個源文件通過編譯過程分別轉(zhuǎn)換成目標(biāo)代碼(objectcode)。

2.每個目標(biāo)文件由鏈接器(linker)捆綁在一起,形成一個單一而完整的可執(zhí)行程序。

3.鏈接器同時也會引入標(biāo)準(zhǔn)C函數(shù)庫中任何被該程序所用到的函數(shù),而且它可以搜索程序員個人的程序庫,將其需要的函數(shù)也鏈接到程序中。

2.2編譯本身也分為幾個階段

2.3運(yùn)行環(huán)境

程序執(zhí)行的過程:

1.程序必須載入內(nèi)存中。在有操作系統(tǒng)的環(huán)境中:一般這個由操作系統(tǒng)完成。在獨(dú)立的環(huán)境中,程序的載入必須由手工安排,也可能是通過可執(zhí)行代碼置入只讀內(nèi)存來完成。

2.程序的執(zhí)行便開始。接著便調(diào)用main函數(shù)

3.開始執(zhí)行程序代碼。這個時候程序?qū)⑹褂靡粋€運(yùn)行時堆棧(stack),存儲函數(shù)的局部變量和返回地址。程序同時也可以使用靜態(tài)(static)內(nèi)存,存儲于靜態(tài)內(nèi)存中的變量在程序的整個執(zhí)行過程一直保留他們的值。

4.終止程序。正常終止main函數(shù);也有可能是意外終止

3.預(yù)處理詳解

3.1預(yù)處理符號

__FILE__//進(jìn)行編譯的源文件__LINE__//文件當(dāng)前的行號__DATE__//文件被編譯的日期__TIME__//文件被編譯的時間__STDC__//如果編譯器遵循ANSIC,其值為1,否則未定義

3.2#define

3.2.1#define定義標(biāo)識符

//語法

#definenamestuff

#defineMAX1000

#defineregregister//為register這個關(guān)鍵字,創(chuàng)建一個簡短的名字

#definedo_foreverfor(;;)//用更形象的符號來替換一種實現(xiàn)

#defineCASEbreak;case//在寫case語句的時候自動把break寫上。

//如果定義的stuff過長,可以分成幾行寫,除了最后一行外,每行的后面都加一個反斜杠(續(xù)行符)。

#defineDEBUG_PRINTprintf("file:%s\tline:%d\t\

date:%s\ttime:%s\n",\

__FILE__,__LINE__,\

__DATE__,__TIME__)

3.2.2#define定義宏

宏(definemacro)。

聲明方式:

#definename(parament-list)stuff

舉例:

#defineADD(x)x+x

inta=5;

ADD(a)

//等價于

//ADD(a)=5+5

3.2.3#define的替換規(guī)則

在程序中擴(kuò)展#define定義符號和宏時,需要涉及幾個步驟。

1.在調(diào)用宏時,首先對參數(shù)進(jìn)行檢查,看看是否包含任何由#define定義的符號。如果是,它們首先被替換。

2.替換文本隨后被插入到程序中原來文本的位置。對于宏,參數(shù)名被他們的值所替換。

3.最后,再次對結(jié)果文件進(jìn)行掃描,看看它是否包含任何由#define定義的符號。如果是,就重復(fù)上述處理過程。

注意:

1.宏參數(shù)和#define定義中可以出現(xiàn)其他#define定義的符號。但是對于宏,不能出現(xiàn)遞歸。

2.當(dāng)預(yù)處理器搜索#define定義的符號的時候,字符串常量的內(nèi)容并不被搜索。

3.2.4宏和函數(shù)對比

宏通常被應(yīng)用于執(zhí)行簡單的運(yùn)算。

比如在兩個數(shù)中找出較大的一個。

#defineMAX(a,b)((a)(b)(a):(b))

那為什么不用函數(shù)來完成這個任務(wù)?

原因有二:

1.用于調(diào)用函數(shù)和從函數(shù)返回的代碼可能比實際執(zhí)行這個小型計算工作所需要的時間更多。所以宏比函數(shù)在程序的規(guī)模和速度方面更勝一籌。

2.更為重要的是函數(shù)的參數(shù)必須聲明為特定的類型。所以函數(shù)只能在類型合適的表達(dá)式上使用。反之這個宏怎可以適用于整形、長整型、浮點(diǎn)型等可以用來比較的類型。

宏是類型無關(guān)的。

宏的缺點(diǎn):當(dāng)然和函數(shù)相比宏也有劣勢的地方:

1.每次使用宏的時候,一份宏定義的代碼將插入到程序中。除非宏比較短,否則可能大幅度增加程序的長度。

2.宏是沒法調(diào)試的。

3.宏由于類型無關(guān),也就不夠嚴(yán)謹(jǐn)。

4.宏可能會帶來運(yùn)算符優(yōu)先級的問題,導(dǎo)致程容易出現(xiàn)錯

宏和函數(shù)的一個對比:

屬性#define定義宏函數(shù)代碼長度每次使用時,宏代碼都會被插入到程序中。除了非常小的宏之外,程序的長度會大幅度增長函數(shù)代碼只出現(xiàn)于一個地方;每次使用這個函數(shù)時,都調(diào)用那個地方的同一份代碼執(zhí)行速度更快存在函數(shù)的調(diào)用和返回的額外開銷,所以相對慢一些操作符優(yōu)先級宏參數(shù)的求值是在所有周圍表達(dá)式的上下文環(huán)境里,除非加上括號,否則鄰近操作符的優(yōu)先級可能會產(chǎn)生不可預(yù)料的后果,所以建議宏在書寫的時候多些括號。函數(shù)參數(shù)只在函數(shù)調(diào)用的時候求值一次,它的結(jié)果值傳遞給函數(shù)。表達(dá)式的求值結(jié)果更容易預(yù)測。帶有副作用的參數(shù)參數(shù)可能被替換到宏體中的多個位置,所以帶有副作用的參數(shù)求值可能會產(chǎn)生不可預(yù)料的結(jié)果。函數(shù)參數(shù)只在傳參的時候求值一次,結(jié)果更容易控制。參數(shù)類型宏的參數(shù)與類型無關(guān),只要對參數(shù)的操作是合法的,它就可以使用于任何參數(shù)類型。函數(shù)的參數(shù)是與類型有關(guān)的,如果參數(shù)的類型不同,就需要不同的函數(shù),即使他們執(zhí)行的任務(wù)是相同的。調(diào)試宏是不方便調(diào)試的函數(shù)是可以逐語句調(diào)試的遞歸宏是不能遞歸的函數(shù)是可以遞歸的

3.2.5命名約定

一般來講函數(shù)的宏的使用語法很相似。所以語言本身沒法幫我們區(qū)分二者。

那我們平時的一個習(xí)慣是:

把宏名全部大寫

函數(shù)名不要全部大寫

3.3#undef

這條指令用于移除一條宏定義

#undefNAME//如果現(xiàn)存的一個名字需要被重新定義,那么它的舊名字首先要被移除。

3.4條件編譯

在編譯一個程序的時候我們?nèi)绻獙⒁粭l語句(一組語句)編譯或者放棄是很方便的。因為我們有條件編譯指令。

1.

//...

//常量表達(dá)式由預(yù)處理器求值。

如:

//..

溫馨提示

  • 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

提交評論