函式式巨集(巨集函式)和函式模擬會更加靈活,我們通過兩個例子來看一下。
函式
#include
intsqr_int
(int x)
double
sqr_double
(double x)
intmain
(int argc ,
char
*ar**)
函式式巨集
#include
#define sqr(x) ((x)*(x))
intmain
(int argc,
char
*ar**)
函式式巨集是在編譯時展開並填入程式的
而函式定義則需要為每個形參都定義各自的資料型別,返回值型別也只能為一種。函式更為嚴格。
函式默默的為我們進行一些複雜的操作,比如:
引數傳遞(將實參值賦值給形參)
函式呼叫和函式返回操作
返回值的傳遞
而函式式巨集只是做巨集展開,並不做上述處理。
函式式巨集能是程式的執行速度稍微提高一點兒,但是當函式中有大量的巨集替換的時候,又會是的程式變得臃腫。
巨集在使用的時候必須小心謹慎,避免出現問題。這一點是有巨集的本身特性決定,即只做替換不做計算。舉例來說明:
巨集的***
情況一:
#define sqr(a) ((a)*(a))
若呼叫該函式式巨集計算sqr(a++),展開後就變為:((a++) * (a++)),可以發現a執行了兩次自增操作。這就會造成**的錯誤,比如我只是想將a自增1後在求其平方,但是結果卻並非我們所想。
情況二:
巨集定義與巨集函式
假如我們在sqr 和』('之間多敲了乙個空格,如下
#define sqr (a) ((a)*(a))
那麼此時函式式巨集就變成了,巨集定義了,也成物件式巨集。即sqr會被編譯器替換成(x) (x)*(x)
在定義巨集函式的時候注意巨集函式名和』('之間不能有空格。
情況三:
#define sum(x,y) x + y //注意:不規範的函式式巨集的定義
//呼叫
z = sum(a,b) * sum(c,d);
//編譯器將其展開後就變為:
z = a + b * c + d; //這樣是不是偏離了我們的本意
因此,我們在定義函式式巨集的時候與一定要每個引數以及整個表示式都用()括起來,就不會出錯了。上面的就可以改為
#define sum(x,y) ((x) + (y))
//正確的定義方法
//呼叫
z =sum
(a,b)
*sum
(c,d)
;/編譯器將其展開後就變為:
z =(
(a)+
(b))*(
(c)+
(d))
;
總結,在定義和使用函式式巨集的時候要注意避免其產生***
#include
#define puts_alert(str)
intmain
(int argc,
char
*ar**)
#include
#define puts_alert(str)
//當然了,如果一行定義不下,有時候為了美觀我們也這樣寫,'\'表示下一行還有內容
#define puts_alert(str)
intmain
(int argc,
char
*ar**)
;else
;return0;
}
#include
#define puts_alert(str) (putchar('\a'),puts(str))
intmain
(int argc,
char
*ar**)
//在if處展開
if(n)
(putchar
('\a'),
puts
(str));
else
(putchar
('\a'),
puts
(str)
);
c語言基礎 巨集
在 c 語言中,可以採用命令 define 來定義巨集。在定義了巨集之後,無論巨集名稱出現在源 的何處,預處理器都會把它用定義時指定的文字替換掉。define 巨集名稱 替換文字 define print printf hello world define 巨集名稱 形參列表 替換文字 define...
C語言基礎 11 巨集
巨集也可以用來給計算公式起名字 計算公式裡包含未知數字,需要使用巨集的引數表示這些未知數字 帶引數的巨集採用二次替換方式進行處理 巨集的引數不一定代表數字,所以沒有型別名稱 如果巨集有多個引數應該用逗號把相鄰的引數名稱分隔開 巨集不可以使用自己的儲存區和函式進行資料傳遞 巨集沒有形式引數也沒有用來存...
C 語言 巨集定義和巨集函式
在軟體開發過程中,經常有一些常用或者通用的功能或者 段,這些功能既可以寫成函式,也可以封裝成為巨集定義。那麼究竟是用函式好,還是巨集定義好?這就要求我們對二者進行合理的取捨。我們來看乙個例子,比較兩個數或者表示式大小,首先我們把它寫成巨集定義 define max a,b a b a b 其次,把它...