C語言知識彙總 43 C語言帶引數的巨集定義

2021-10-09 16:04:58 字數 2828 閱讀 2272

c語言允許巨集帶有引數。在巨集定義中的引數稱為「形式引數」,在巨集呼叫中的引數稱為「實際引數」,這點和函式有些類似。

對帶引數的巨集,在展開過程中不僅要進行字串替換,還要用實參去替換形參。

帶參巨集定義的一般形式為:

#define 巨集名(形參列表) 字串
在字串中可以含有各個形參。

帶參巨集呼叫的一般形式為:

巨集名(實參列表);
例如:

#define m(y) y*y+3*y  //巨集定義

// todo:

k=m(5); //巨集呼叫

在巨集展開時,用實參 5 去代替形參 y,經預處理程式展開後的語句為k=5*5+3*5

【示例】輸出兩個數中較大的數。

#include #define max(a,b) (a>b) ? a : b

int main()

執行結果:

input two numbers: 10 20

max=20

程式第 3 行定義了乙個帶引數的巨集,用巨集名max表示條件表示式(a>b) ? a : b,形參 a、b 均出現在條件表示式中。程式第 11 行max = max(x, y)為巨集呼叫,實參 x、y 將用來代替形參 a、b。巨集展開後該語句為:

max=(x>y) ? x : y;

(1)帶參巨集定義中,形參之間可以出現空格,但是巨集名和形參列表之間不能有空格出現。例如把:

#define max(a,b) (a>b)?a:b
寫為:

#define max  (a,b)  (a>b)?a:b
將被認為是無參巨集定義,巨集名 max 代表字串(a,b) (a>b)?a:b。巨集展開時,巨集呼叫語句:

max = max(x,y);
將變為:

max = (a,b)  (a>b)?a:b(x,y);
這顯然是錯誤的。

(2)在帶參巨集定義中,不會為形式引數分配記憶體,因此不必指明資料型別。而在巨集呼叫中,實參包含了具體的資料,要用它們去替換形參,因此實參必須要指明資料型別。

這一點和函式是不同的:在函式中,形參和實參是兩個不同的變數,都有自己的作用域,呼叫時要把實參的值傳遞給形參;而在帶引數的巨集中,只是符號的替換,不存在值傳遞的問題。

【示例】輸入 n,輸出 (n+1)^2 的值。

#include #define sq(y) (y)*(y)

int main()

執行結果:

input a number: 9

sq=100

第 2 行為巨集定義,形參為 y。第 11 行巨集呼叫中實參為 a+1,是乙個表示式,在巨集展開時,用 a+1 代換 y,再用 (y)*(y) 代換 sq,得到如下語句:

sq = (a+1)*(a+1);
這與函式的呼叫是不同的,函式呼叫時要把實參表示式的值求出來再傳遞給形參,而巨集展開中對實參表示式不作計算,直接按照原樣替換。

(3)在巨集定義中,字串內的形參通常要用括號括起來以避免出錯。例如上面的巨集定義中 (y)*(y) 表示式的 y 都用括號括起來,因此結果是正確的。如果去掉括號,把程式改為以下形式:

#include #define sq(y) y*y

int main()

執行結果為:

input a number: 9

sq=19

同樣輸入 9,但結果卻是不一樣的。問題在**呢?這是由於巨集展開只是簡單的符號替換的過程,沒有任何其它的處理。巨集替換後將得到以下語句:

sq = a+1*a+1;
由於 a 為 9,故 sq 的值為 19。這顯然與題意相違,因此引數兩邊的括號是不能少的。即使在引數兩邊加括號還是不夠的,請看下面程式:

#include #define sq(y) (y)*(y)

int main()

與前面的**相比,只是把巨集呼叫語句改為:

sq = 200/sq(a+1);
執行程式後,如果仍然輸入 9,那麼我們希望的結果為 2。但實際情況並非如此:

input a number: 9

sq=200

為什麼會得這樣的結果呢?分析巨集呼叫語句,在巨集展開之後變為:

sq = 200/(a+1)*(a+1);
a 為 9 時,由於「/」和「*」運算子優先順序和結合性相同,所以先計算 200/(9+1),結果為 20,再計算 20*(9+1),最後得到 200。

為了得到正確答案,應該在巨集定義中的整個字串外加括號:

#include #define sq(y) ((y)*(y))

int main()

由此可見,對於帶參巨集定義不僅要在引數兩側加括號,還應該在整個字串外加括號

4 3 C語言基本運算子

我們小學數學學過加 減 乘 除等運算符號以及四則混合運算,而這些運算符號在 c語言中也有,但是有些表達方法不一樣,並且還有額外的運算符號。在 c 語言程式設計中,加 減 乘 除和取餘數的符號分別是 此外,c 語言中還有額外的兩個運算子 和 他們的用法是一樣的,乙個是自加 1,乙個是自減 1,我們選 ...

輸入字元 4 3 C語言字元資料的輸入輸出

01putchar函式 想從計算機向顯示器輸出乙個字元,可以呼叫系統函式庫中的putchar函式。1 一般形式 putchar c putchar是put character 給字元 的縮寫,其作用是輸出字元變數c的值,顯然它是乙個字元。2 putchar c 中的c可以是字元常量 整型常量 字元變...

C語言 main 函式帶引數

想必我們都知道函式是帶有從引數的。但是似乎,很少考慮過主函式 main 帶引數。不帶引數的main函式格式為 main 它實際上是 main void 的簡寫 c語言中如果主函式需要帶引數,帶引數的main函式格式為 main int argc,char ar 也可寫成 main int argc,...