看你的敘述,你的宏應(yīng)該是想計(jì)算某個(gè)數(shù)的平方。在C語言中,宏的展開僅僅是“字符”替換。當(dāng)宏中有運(yùn)算操作時(shí),要定義好宏的參數(shù)(用括號(hào)來括好參數(shù)),不然結(jié)果可能不是想要的。如定義一個(gè)計(jì)算某個(gè)數(shù)的平方的宏,如果如下寫法:
創(chuàng)新互聯(lián)長(zhǎng)期為數(shù)千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為桐鄉(xiāng)企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè),桐鄉(xiāng)網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
#define S(a)????a*a
這種寫法是錯(cuò)誤的。如果這么使用 S(100),它的結(jié)果正確,展開為100*100;但如果這么使用 S(50+50),它的結(jié)果就是錯(cuò)誤的,展開為 50+50*50+50。
正確的定義方式是:
#define S(a) ????((a)*(a))
下面在手機(jī)上用易歷知食軟件內(nèi)的微C程序設(shè)計(jì)來演示一下效果,直接在手機(jī)上編個(gè)小程序,手機(jī)上的代碼如下:
運(yùn)行結(jié)果如下(可見第1種定義是錯(cuò)誤的,本來想要的是(1+2)的平方,結(jié)果卻為5,即1+2*1+2):
宏定義的基礎(chǔ)知識(shí)。引用宏定義時(shí),直接代入進(jìn)行代換。
既然已經(jīng)宏定義SUB(a) (a)-(a),而程序中出現(xiàn)的對(duì)應(yīng)a的是a+b,那么就將a換為a+b代入表達(dá)式:
d=SUB(a+b)*c=(a+b)-(a+b)*c=(2+3)-(2+3)*5
直接用(a+b)-(a+b)代換SUB(a+b)。這一點(diǎn)和數(shù)學(xué)是不同的,不要強(qiáng)行往數(shù)學(xué)上靠。
宏是用于編譯器處理的,他在程序編譯時(shí),會(huì)在對(duì)應(yīng)位置展開成代碼。。,這就相當(dāng)于你在告訴編譯器,我想在這個(gè)位置加一些代碼,代碼的內(nèi)容已在宏中定義,請(qǐng)編譯器自己支找。。。,也就是說程序在運(yùn)行時(shí),早已變成了對(duì)應(yīng)位置上的代碼,此時(shí)已沒有宏的概念了。。。。
而函數(shù)則是運(yùn)行時(shí),調(diào)用。他不會(huì)在編譯時(shí),在對(duì)應(yīng)位置上加上函數(shù)代碼,只是加上一個(gè)函數(shù)入口指針。。。從這個(gè)入口去運(yùn)行一段代碼。。。運(yùn)行完了之后回到當(dāng)前位置繼續(xù)執(zhí)行。。。。
可以簡(jiǎn)單的認(rèn)為,宏是在編譯時(shí)上起作用,而函數(shù)是運(yùn)行時(shí)起作用。。。
宏是一種預(yù)處理指令,它提供了一種機(jī)制,可以用來替換源代碼中的字符串。
1、條件編譯:
C語言中,預(yù)處理過程讀入源代碼,檢查包含預(yù)處理指令的語句和宏定義,并對(duì)源代碼進(jìn)行相應(yīng)的轉(zhuǎn)換,預(yù)處理過程還會(huì)刪除程序中的注釋和多余的空白符號(hào)。
預(yù)處理指令是以#開頭的代碼行,#必須是該行除了空白字符外的第一個(gè)字符。#后是指令關(guān)鍵字,在#和指令關(guān)鍵字之間允許存在若干空白字符。
使用宏進(jìn)行條件編譯的用法與使用宏防止多重引用類似。示例如下:
使用條件編譯,方便程序員在調(diào)試程序的過程中,執(zhí)行一些在程序發(fā)布后并不需要執(zhí)行的指令。只要在需要調(diào)試的代碼前加上_DEBUG的定義,就可以在調(diào)試程序的過程中輸出調(diào)試信息。
這樣方便查看程序在運(yùn)行過程中有沒有出現(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ù)則不存在上述問題,宏函數(shù)在預(yù)編譯時(shí),同函數(shù)定義的代碼來替換函數(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)的使用。
擴(kuò)展資料:
宏的更多規(guī)則特性:
(1)宏名一般用大寫。
(2)使用宏可提高程序的通用性和易讀性,減少不一致性,減少輸入錯(cuò)誤和便于修改。例如:數(shù)組大小常用宏定義。
(3)預(yù)處理是在編譯之前的處理,而編譯工作的任務(wù)之一就是語法檢查,預(yù)處理不做語法檢查。
(4)宏定義末尾不加分號(hào)。
(5)宏定義寫在函數(shù)的花括號(hào)外邊,作用域?yàn)槠浜蟮某绦颍ǔT谖募淖铋_頭。
(6)可以用#undef命令終止宏定義的作用域。
(7)宏定義不可以嵌套。
(8)字符串" "中永遠(yuǎn)不包含宏。
(9)宏定義不分配內(nèi)存,變量定義分配內(nèi)存。
(10)宏定義不存在類型問題,它的參數(shù)也是無類型的。
參考資料:
百度百科--宏定義
可以把宏理解成拼字游戲,它功能很強(qiáng)大,但是強(qiáng)大到使用不好就會(huì)有副作用。C++有很多語言設(shè)施用來完全特定功能的宏,如const,inline,template,就是為了讓大家少用宏。給你舉個(gè)宏和函數(shù)不同的例子代碼:
#define max(x,y) ((x)(y)?(x):(y))
template class T
inline T max(T x,T y){return xy?x:y;}
看起來似乎是相同的功能,可是函數(shù)調(diào)用,畢竟會(huì)求完每一個(gè)實(shí)參的值,再傳遞給被調(diào)函數(shù),即使聲明了inline,在調(diào)用點(diǎn)展開而不發(fā)生實(shí)際的調(diào)用開銷。
但是你試試用這個(gè)調(diào)用宏,結(jié)果就會(huì)有問題:
int i=4,j=5;
int k=max(i++,j++);
如果是函數(shù)調(diào)用,i==5,j==6,k==5。如果是宏的話,結(jié)果是:
int k=((i++)(j++)?(i++):(j++));
你覺得會(huì)一樣嗎?所以,慎用宏。
MFC中有很多功能是宏完成的,它太強(qiáng)大了,很多情況下有宏很高效,但是不容易控制。
當(dāng)前文章:c語言宏函數(shù) c語言宏函數(shù)的使用方法
網(wǎng)站路徑:http://aaarwkj.com/article40/doodpho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、微信小程序、用戶體驗(yàn)、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)