mysql巨集引數 C語言帶引數的巨集定義

2021-10-18 06:54:01 字數 3064 閱讀 6734

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(){

int x , y, max;

printf("input two numbers: ");

scanf("%d %d", &x, &y);

max = max(x, y);

printf("max=%d\n", max);

return 0;

執行結果:

input two numbers: 10 20

max=20

程式第 2 行定義了乙個帶引數的巨集,用巨集名max表示條件表示式(a>b) ? a : b,形參 a、b 均出現在條件表示式中。程式第 7 行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(){

int a, sq;

printf("input a number: ");

scanf("%d", &a);

sq = sq(a+1);

printf("sq=%d\n", sq);

return 0;

執行結果:

input a number: 9

sq=100

第 2 行為巨集定義,形參為 y。第 7 行巨集呼叫中實參為 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(){

int a, sq;

printf("input a number: ");

scanf("%d", &a);

sq = sq(a+1);

printf("sq=%d\n", sq);

return 0;

執行結果為:

input a number: 9

sq=19

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

sq=a+1*a+1;

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

#include

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

int main(){

int a,sq;

printf("input a number: ");

scanf("%d", &a);

sq = 200 / sq(a+1);

printf("sq=%d\n", sq);

return 0;

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

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(){

int a,sq;

printf("input a number: ");

scanf("%d", &a);

sq = 200 / sq(a+1);

printf("sq=%d\n", sq);

return 0;

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

C語言的巨集之帶引數巨集

c語言允許巨集帶有引數。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數,這種巨集外形和作用與函式類似,即類函式巨集。但是它的行為和函式呼叫完全不同。對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代換形參。類函式巨集定義的圓括號中可以有乙個或多個引數,隨後這些引數出現在替換體...

C語言中的帶引數巨集

c語言中的帶引數巨集 一.帶引數的巨集 1.帶引數的巨集定義不是簡單的字串替換,還要進行引數替換 定義格式為 define 巨集名 參數列 字串 1 字串包含括號中所有指定的引數 eg define s a,b a b area s 3,2 2 編譯系統處理帶引數的巨集名時,按程式行中指定的字串,括...

C語言基礎之帶引數的巨集

像函式的巨集 define cube x x x x 巨集可以帶引數 例 include define cube x x x x int main int argc,char const ar 在這個巨集中,編譯預處理時,會將所有的cube x 替換成 x x x 其中x是引數 錯誤定義的巨集 de...