c語言允許巨集帶有引數。在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數。
對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代換形參。
帶參巨集定義的一般形式為:帶參巨集呼叫的一般形式為:巨集名(實參表);#define 巨集名(形參表) 字串
例如:
#define m(y) y*y+3*y /*巨集定義*/……k=m(5); /*巨集呼叫*/
……
在巨集呼叫時,用實參5去代替形參y,經預處理巨集展開後的語句為:k=5*5+3*5
#include #define max(a,b) (a>b)?a:b
void main()
1. 帶參巨集定義中,巨集名和形參表之間不能有空格出現。
例如把:自己試試看~#define max(a,b) (a>b)?a:b
寫為:#define max (a,b) (a>b)?a:b
2. 在帶參巨集定義中,形式引數不分配記憶體單元,因此不必作型別定義。而巨集呼叫中的實參有具體的值。要用它們去代換形參,因此必須作型別說明。
這是與函式中的情況不同的。在函式中,形參和實參是兩個不同的量,各有自己的作用域,呼叫時要把實參值賦予形參,進行「值傳遞」。而在帶參巨集中,只是符號代換,不存在值傳遞的問題。
3. 在巨集定義中的形參是識別符號,而巨集呼叫中的實參可以是表示式。
#include #define say(y) (y)
void main()
; while (say[i])
printf("\n\t%s\n\n", say);
}
4. 在巨集定義中,
字串內的形參通常要用括號括起來以避免出錯。在上例中的巨集定義中(y)*(y)表示式的y都用括號括起來,因此結果是正確的。如果去掉括號,把程式改為以下形式:
#include #define sq(y) (y)*(y) // y*y試試
void main()
如果我們不加括號,即#define sq(y) y*y
得到的結果就會事與願違:即sq=a+1*a+1
將例子3題目進行**:我們現在要160 ÷ sq(y)
#include #define sq(y) ((y)*(y))
void main()
5. 帶參的巨集和帶參函式很相似,但有本質上的不同,除上面已談到的各點外,把同一表示式用函式處理與用巨集處理兩者的結果有可能是不同的。
比較一下下面兩個程式的結果為何不一樣:
//用函式處理
#include void main()
}int sq(int y)
//用巨集處理
#include #define sq(y) ( (y)*(y) )
void main()
}
6. 巨集定義也可用來定義多個語句,在巨集呼叫時,把這些語句又代換到源程式內。看下面的例子。
#include #include // strcat是乙個字串函式
#define str(s1, s2, s3, sum) strcat( strcat( strcat(sum, s1), s2 ), s3)
void main()
零基礎入門學習C語言010講 預處理(1)
在前面各章中,已多次使用過以 號開頭的預處理命令。如包含命令 include 巨集定義命令 define pi 3.1415926等。在源程式中這些命令都放在函式之外,而且一般都放在原始檔的前面,它們稱為預處理部分。無參巨集的巨集名後不帶引數。其定義的一般形式為 define 識別符號 字串 其中的...
零基礎入門學習C語言010講 預處理(3)
儘管我們很熟悉,但對檔案包含命令還要說明以下幾點 1.乙個include命令只能指定乙個被包含檔案,若有多個檔案要包含,則需用多個include命令。2.檔案包含允許巢狀,即在乙個被包含的檔案中又可以包含另乙個檔案。3.包含命令中的檔名可以用雙引號括起來,也可以用尖括號括起來。例如以下寫法都是允許的...
零基礎入門學習C語言004講 順序程式設計(2)
scanf函式稱為格式輸入函式,即按使用者指定的格式從鍵盤上把資料輸入到指定的變數之中。1.scanf函式的一般形式 scanf函式是乙個標準庫函式,它的函式原型在標頭檔案 stdio.h 中,與printf函式相同,語言也允許在使用scanf函式之前不必包含stdio.件。scanf函式的一般形式...