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