蕪湖市網(wǎng)站建設(shè)站長(zhǎng)工具外鏈查詢
宏(Macro),是一種批量處理的稱謂。計(jì)算機(jī)科學(xué)里的宏是一種抽象(Abstraction),它根據(jù)一系列預(yù)定義的規(guī)則替換一定的文本模式。解釋器或編譯器在遇到宏時(shí)會(huì)自動(dòng)進(jìn)行這一模式替換。對(duì)于編譯語(yǔ)言,宏展開在編譯時(shí)發(fā)生,進(jìn)行宏展開的工具常被稱為宏展開器。宏這一術(shù)語(yǔ)也常常被用于許多類似的環(huán)境中,它們是源自宏展開的概念,這包括鍵盤宏和宏語(yǔ)言。絕大多數(shù)情況下,“宏”這個(gè)詞的使用暗示著將小命令或動(dòng)作轉(zhuǎn)化為一系列指令。
宏是一種預(yù)處理指令,它提供了一種機(jī)制,可以用來(lái)替換源代碼中的字符串。
1、條件編譯:
C語(yǔ)言中,預(yù)處理過(guò)程讀入源代碼,檢查包含預(yù)處理指令的語(yǔ)句和宏定義,并對(duì)源代碼進(jìn)行相應(yīng)的轉(zhuǎn)換,預(yù)處理過(guò)程還會(huì)刪除程序中的注釋和多余的空白符號(hào)。
預(yù)處理指令是以#開頭的代碼行,#必須是該行除了空白字符外的第一個(gè)字符。#后是指令關(guān)鍵字,在#和指令關(guān)鍵字之間允許存在若干空白字符。
使用宏進(jìn)行條件編譯的用法與使用宏防止多重引用類似。示例如下:
使用條件編譯,方便程序員在調(diào)試程序的過(guò)程中,執(zhí)行一些在程序發(fā)布后并不需要執(zhí)行的指令。只要在需要調(diào)試的代碼前加上_DEBUG的定義,就可以在調(diào)試程序的過(guò)程中輸出調(diào)試信息。
這樣方便查看程序在運(yùn)行過(guò)程中有沒有出現(xiàn)錯(cuò)誤,定位錯(cuò)誤出現(xiàn)的地方。而在程序發(fā)布之前,取消_DEBUG的定義就可以不再執(zhí)行調(diào)試代碼。
2、宏函數(shù):
函數(shù)的調(diào)用是需要一定的時(shí)間和空間代價(jià)的。因?yàn)橄到y(tǒng)在調(diào)用函數(shù)時(shí),需要保留"現(xiàn)場(chǎng)",即將程序要執(zhí)行的指令的下一條指令的位置壓入棧,然后轉(zhuǎn)入調(diào)用函數(shù)去執(zhí)行,調(diào)用完函數(shù)后再返回主調(diào)函數(shù),恢復(fù)"現(xiàn)場(chǎng)",返回到棧里保存的的下一條指令的位置繼續(xù)執(zhí)行。
所以函數(shù)的調(diào)用需要額外的時(shí)間和空間代價(jià)。
而宏函數(shù)則不存在上述問(wèn)題,宏函數(shù)在預(yù)編譯時(shí),同函數(shù)定義的代碼來(lái)替換函數(shù)名,將函數(shù)代碼段嵌入到當(dāng)前程序,不會(huì)產(chǎn)生函數(shù)調(diào)用。
所以會(huì)省去普通函數(shù)保留現(xiàn)場(chǎng)恢復(fù)現(xiàn)場(chǎng)的時(shí)間,但因?yàn)橐獙⒍x的函數(shù)體嵌入到當(dāng)前程序,所以不可避免的會(huì)占用額外的存儲(chǔ)空間。
在頻繁調(diào)用同一個(gè)宏的時(shí)候,該現(xiàn)象尤其明顯。宏函數(shù)的示例定義如下:
#define MAX(a,b) ((a)<(b)?(b):(a))
宏函數(shù)的優(yōu)點(diǎn)在于避免函數(shù)調(diào)用,提高程序效率。
同時(shí)需要注意的是inline標(biāo)識(shí)符。inline也將函數(shù)定義為內(nèi)聯(lián)的。但是使用內(nèi)聯(lián)函數(shù)需要注意的是:函數(shù)體必須十分簡(jiǎn)單,不能含有循環(huán)、條件、選擇等復(fù)雜結(jié)構(gòu),否則就不能作為內(nèi)聯(lián)函數(shù)了。
事實(shí)上,有時(shí)候即便你沒有將函數(shù)指定為內(nèi)聯(lián)函數(shù),編譯器也會(huì)將一些簡(jiǎn)單的函數(shù)作為內(nèi)聯(lián)函數(shù)處理,而對(duì)于一些復(fù)雜的函數(shù),即使聲明為內(nèi)聯(lián)函數(shù),編譯器也不會(huì)理會(huì)的。
inline函數(shù)的瓶頸就在于此,使用inline標(biāo)識(shí)符將函數(shù)聲明為內(nèi)聯(lián)的,但這只是一種提示,到底編譯器有沒有優(yōu)化還依賴于編譯器的實(shí)現(xiàn),而使用宏函數(shù)則完全由代碼本身控制。
但在使用宏函數(shù)的時(shí)候,需要明確的是宏函數(shù)只是簡(jiǎn)單的替換,需要注意括號(hào)的使用。
為了能夠真正理解#define的作用,讓我們來(lái)了解一下對(duì)C語(yǔ)言源程序的處理過(guò)程。當(dāng)我們?cè)谝粋€(gè)集成的開發(fā)環(huán)境如Turbo C中將編寫好的源程序進(jìn)行編譯時(shí),實(shí)際經(jīng)過(guò)了預(yù)處理、編譯、匯編和連接幾個(gè)過(guò)程。
源程序?
預(yù)處理器?
修改后的源程序?
編譯器?
匯編程序?
匯編器?
可重定位的目標(biāo)程序?
連接器?
可執(zhí)行的目標(biāo)程序?
?
宏的規(guī)則特性:
(1)宏名一般用大寫。
(2)使用宏可提高程序的通用性和易讀性,減少不一致性,減少輸入錯(cuò)誤和便于修改。例如:數(shù)組大小常用宏定義。
(3)預(yù)處理是在編譯之前的處理,而編譯工作的任務(wù)之一就是語(yǔ)法檢查,預(yù)處理不做語(yǔ)法檢查。
(4)宏定義末尾不加分號(hào)。
(5)宏定義寫在函數(shù)的花括號(hào)外邊,作用域?yàn)槠浜蟮某绦?#xff0c;通常在文件的最開頭。
(6)可以用#undef命令終止宏定義的作用域。
(7)宏定義不可以嵌套。
(8)字符串" "中永遠(yuǎn)不包含宏。
(9)宏定義不分配內(nèi)存,變量定義分配內(nèi)存。
(10)宏定義不存在類型問(wèn)題,它的參數(shù)也是無(wú)類型的。
參考文章:https://zhidao.baidu.com/question/414209784.html
參考文章:http://blog.chinaunix.net/uid-20606164-id-3280360.html