C語言無引數巨集定義

2021-06-28 04:50:04 字數 2682 閱讀 9648

在c語言源程式中允許用乙個識別符號來表示乙個字串,稱為「巨集」。

被定義為「巨集」的識別符號稱為「巨集名」。在編譯預處理時,對程式中所有出現的「巨集名」,都用巨集定義中的字串去代換,這稱為「巨集代換」或「巨集展開」。

巨集定義是由源程式中的巨集定義命令完成的。巨集代換是由預處理程式自動完成的。

在c語言中,「巨集」分為有引數和無引數兩種。

本節討論無引數巨集。

無參巨集的巨集名後不帶引數。其定義的一般形式為:

#define  識別符號  字串

其中的「#」表示這是一條預處理命令。凡是以「#」開頭的均為預處理命令。「define」為巨集定義命令。「識別符號」為所定義的巨集名。「字串」可以是常數、表示式、格式串等。

在前面介紹過的符號常量的定義就是一種無參巨集定義。此外,常對程式中反覆使用的表示式進行巨集定義。例如:

#define

m (y*y+3*y)

它的作用是指定識別符號m來代替表示式(y*y+3*y)。在編寫源程式時,所有的(y*y+3*y)都可由m代替,而對源程式作編譯時,將先由預處理程式進行巨集代換,即用(y*y+3*y)表示式去置換所有的巨集名m,然後再進行編譯。

【例9-1】

#include

#define

m (y*y+3*y)

int main

(void)

上例程式中首先進行巨集定義,定義m來替代表示式(y*y+3*y),在s=3*m+4*m+5* m中作了巨集呼叫。在預處理時經巨集展開後該語句變為:

s=3*(y*y+3*y)+4*(y*y+3*y)+5*(y*y+3*y);
但要注意的是,在巨集定義中表示式(y*y+3*y)兩邊的括號不能少。否則會發生錯誤。

如當作以下定義後:

#difine m y*y+3*y
在巨集展開時將得到下述語句:
s=3*y*y+3*y+4*y*y+3*y+5*y*y+3*y;
這相當於:

3y2+3y+4y

2+3y+5y

2+3y

顯然與原題意要求不符。計算結果當然是錯誤的。因此在作巨集定義時必須十分注意。應保證在巨集代換之後不發生錯誤。

對於巨集定義還要說明以下幾點:

1) 巨集定義是用巨集名來表示乙個字串,在巨集展開時又以該字串取代巨集名,

這只是一種簡單的代換,

字串中可以含任何字元,可以是常數,也可以是表示式,預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集展開後的源程式時發現。

2) 巨集定義不是說明或語句,

在行末不必加分號,

如加上分號則連分號也一起置換。

3) 巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。如要終止其作用域可使用

#undef命令

。例如:

#define pi 3.14159

int main(void)

#undef pi

f1()

表示pi只在main函式中有效,在f1中無效。

4) 巨集名在源程式中若用引號括起來,則預處理程式不對其作巨集代換。如下所示【例92】:

#include 

#define ok 100

int main(void)

上例中定義巨集名ok表示100,但在printf語句中ok被引號括起來,因此不作巨集代換。程式的執行結果為:ok這表示把「ok」當字串處理。

5) 巨集定義允許巢狀,在巨集定義的字串中可以使用已經定義的巨集名。在巨集展開時由預處理程式層層代換。例如:

#define pi 3.1415926

#define s pi*y*y

對語句:
printf("%f",s);
在巨集代換後變為:
printf("%f",3.1415926*y*y);

6) 習慣上巨集名用大寫字母表示,以便於與變數區別。但也允許用小寫字母。

7) 可用巨集定義表示資料型別,使書寫方便。例如:

#define stu struct stu
在程式中可用stu作變數說明:
stu body[5],*p;

#define integer int

在程式中即可用integer作整型變數說明:
integer a,b;

應注意用巨集定義表示資料型別和用typedef定義資料說明符的區別。

巨集定義只是簡單的字串代換,是在預處理完成的,而typedef是在編譯時處理的,它不是作簡單的代換,而是對型別說明符重新命名。被命名的識別符號具有型別定義說明的功能。

請看下面的例子:

#define pin1 int *

typedef (int *) pin2;

從形式上看這兩者相似, 但在實際使用中卻不相同。

下面用pin1,pin2說明變數時就可以看出它們的區別:

pin1 a,b;
在巨集代換後變成:
int *a,b;
表示a是指向整型的指標變數,而b是整型變數。然而:
pin2 a,b;
表示a、b都是指向整型的指標變數。因為pin2是乙個型別說明符。

由這個例子可見,巨集定義雖然也可表示資料型別, 但畢竟是作字元代換。在使用時要分外小心,以避出錯。

8) 對「輸出格式」作巨集定義,可以減少書寫麻煩。

【例9-3】中就採用了這種方法。

#include 

#define p printf

#define d "%d\n"

#define f "%f\n"

int main(void)

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

c語言允許巨集帶有引數。在巨集定義中的引數稱為 形式引數 在巨集呼叫中的引數稱為 實際引數 這點和函式有些類似。對帶引數的巨集,在展開過程中不僅要進行字串替換,還要用實參去替換形參。帶參巨集定義的一般形式為 define 巨集名 形參列表 字串 在字串中可以含有各個形參。帶參巨集呼叫的一般形式為 巨...

無參巨集定義二 c語言(3 12)

定義無參巨集定義 的時候要注意幾點 1.巨集定義是用巨集名來表示乙個字串,在巨集展開中又以該字元取代巨集名,這只是 一種簡單的代換,字元中可以代替任何字元,可以是常數,也可以是表示式。2.巨集定義千萬不要在行末加分號,如果加了分號,它會自動連你新增的分號一起轉換。3.引號引起來的,預處理程式不會對其...

C語言可變引數巨集定義方法

在gnu c中,巨集可以接受可變數目的引數,就象函式一樣,例如 1 2 define pr debug fmt,arg.printk kern debug fmt,arg 用可變引數巨集 variadic macros 傳遞可變參數列 你可能很熟悉在函式中使用可變參數列,如 1 voidprintf...