簡單分析帶引數巨集定義

2021-10-03 07:39:50 字數 2368 閱讀 1308

相信學過c語言的同學都對c語言中的巨集定義有一定的了解,而在實際編寫程式時往往程式設計師都會加入帶引數的巨集,那麼究竟什麼是帶引數的巨集定義呢?下面課課家筆者就為大家介紹c語言中帶引數的巨集定義。

簡單分析帶引數巨集定義_程式語言_c語言_帶引數巨集定義_課課家教育

在c語言中,通常允許巨集帶有引數。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數,這方面和函式有些類似。對帶引數的巨集,我們在呼叫中的時候不僅要巨集展開,而且要用實參去代換形參。帶參巨集定義的一般形式為:#define巨集名(形參列表)字串。從字串中我們可以看到含有各個形參。帶參巨集呼叫的一般形式為:巨集名(實參列表);。具體**例子如下:

#definem(y)yy+3y//巨集定義

//code

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

在我們進行巨集呼叫時,用實參5去代替形參y,經預處理巨集展開後的語句為k=55+35。下面筆者以輸出兩個數中較大的數的**例子為例給大家講解。

#include

#definemax(a,b)(a>b)?a:b

intmain()

輸出結果:

inputtwonumbers:1020

max=20

從上面的**例子中我們可以觀察到,程式第2行進行了帶參巨集定義,用巨集名max表示條件表示式(a>b)?a:b,形參a、b均出現在條件表示式中。程式第7行max=max(x,y)為巨集呼叫,實參x、y將代換形參a、b。巨集展開後該語句為:

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

下面是筆者對帶參巨集定義的簡單總結:

①在帶參巨集定義中,形參之間可以出現空格,但是巨集名和形參列表之間不能有空格出現。比如把:#definemax(a,b)(a>b)?a:b寫為:#definemax(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);,這很明顯是錯誤的。

②在帶參巨集定義中,不會為形式引數分配記憶體,因此不必指明資料型別。相反在巨集呼叫中,實參包含了具體的資料,要用它們去代換形參,因此必須指明資料型別。在函式中,形參和實參是兩個不同的變數,都有自己的作用域,呼叫時要把實參的值傳遞給形參;而在帶引數的巨集中,只是符號的替換,不存在值傳遞的問題。下面筆者以輸入n,輸出(n+1)^2的值作為**例子來給大家說明:

#include

#definesq(y)(y)*(y)

intmain()

輸出結果:

inputanumber:9

sq=100

從上面的**例子中我們可以觀察到,第2行為巨集定義,形參為y。第7行巨集呼叫中實參為a+1,是乙個表示式,在巨集展開時,用a+1代換y,再用(y)(y)代換sq,最後會得到語句:sq=(a+1)(a+1);。這與函式的呼叫是不同的,函式呼叫時要把實參表示式的值求出來再傳遞給形參,而巨集展開中對實參表示式不作計算,直接按照原樣替換。

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

#include

#definesq(y)y*y

intmain()

輸出結果為:

inputanumber:9

sq=19

同樣我們是輸入9,但得到的結果卻是不一樣的。原因在於替換只作符號替換而不作其它處理而造成的。巨集替換後將得到以下語句:sq=a+1*a+1;。由於a為9故sq的值為19。這顯然與原本的目標相違背,因此引數兩邊的括號是不能少的。另外即便在引數兩邊加括號還是不夠的,其結果也是和原本輸出的結果也不一樣。具體大家可以觀察下面的**例子:

#include

#definesq(y)(y)*(y)

intmain()

相比於前面的**,這裡只是把巨集呼叫語句改為:sq=200/sq(a+1);。在我們執行程式後,正常情況下在輸入9的結果為2。但實際上根據以上**例子輸入後所得到結果並非如此,其結果最終會如下所示:

inputanumber:9

sq=200

我們不妨來分析巨集呼叫語句,在巨集展開之後變為:sq=200/(a+1)(a+1);。a為9時,由於「/」和「」運算子優先順序和結合性相同,所以先計算200/(9+1),結果為20,再計算20*(9+1),最後得到200。所以我們為了得到正確答案,應該在巨集定義中的整個字串外加括號:

#include

#definesq(y)((y)*(y))

intmain()

綜上所述,對於帶參巨集定義不僅要在引數兩側加括號,我們還應該在整個字串外加括號,這點是值得大家要去注意的地方!

巨集定義及帶引數的巨集定義

include 巨集定義,通常用於定義常量,在 轉換成二進位制檔案時會將 中的巨集名稱替換成值 define 巨集名稱 值 define a 1 帶引數的巨集 fun a,b 為巨集的名稱 a b為巨集的值 帶引數的巨集比函式效率高 define fun a,b a b 為了保證替換結果,最好加入 ...

帶引數的巨集定義

不是進行簡單的字串替換,還要進行引數替換。其定義的一般形式為 define 巨集名 參數列 字串 字串中包含在括弧中所指定的引數。如 define s a,b a b area s 3,2 定義矩形面積s,a 和 b 是邊長。在程式中用了s 3,2 把3 2分別代替巨集定義中的形式引數a b,即用 ...

不帶引數的巨集定義與帶引數的巨集定義

巨集定義是c提供的三種預處理功能的其中一種,這三種預處理包括 巨集定義 檔案包含 條件編譯 1.不帶引數的巨集定義 巨集定義又稱為巨集代換 巨集替換,簡稱 巨集 格式 define 識別符號 字串其中的識別符號就是所謂的符號常量,也稱為 巨集名 預處理 預編譯 工作也叫做巨集展開 將巨集名替換為字串...