前言
本人學生黨,辣雞一個,還望包涵
正文
一、宏定義的基本使用方法
宏定義對于學過c語言的人來說應該并不陌生,其實說白了就是#define
,但是對于初學者來說,用法一般只有這樣
// 定義一個常量
#define CONST "value"
但是實際上這個宏定義還可以定義一些“函數”,比如說下面的
// 定義一個加法的宏
#define add(num1, num2) (num1 + num2)
這句話的意思其實是當你在寫add(5, 6)
的時候,5被當作num1,6被當作num2,然后對宏展開的內容進行替換,也就是替換成(5+6)
。編譯器會在進行預處理的時候完成這個替換。
二、使用代碼塊完成宏定義
但是如果說在這個定義中要使用多個語句或者說其他的變量怎么辦呢?我們可以使用代碼塊來完成這些操作。
// 代碼塊是{}
// 定義一個交換兩個變量值的宏
#define exchange(num1, num2) {int c; c=num1; num1=num2; num2=c;}
在代碼塊中定義的變量會在程序離開該塊的時候失效,這樣的話這個變量c就不會影響到宏定義以外的代碼內容。
三、行連接符''
我們可以看到,上面的宏定義因為把所有的語句都寫在了同一行,看起來十分臃腫,那我們有沒有什么辦法把它分成幾行呢?肯定是有的,我們用''連接符可以鏈接兩行之間的內容
// 還是上面的那個交換
#define exchange(num1, num2) \
{ \
int c; \
c=num1; \
num1=num2; \
num2=c; \
}
但是要注意的是。''符號同一行的后面不能再有任何的字符。最經常的錯誤就是''后面加多了空格或者是制表符,這樣也會導致編譯錯誤。
四、連接符'##'和字符串化操作符'#'
有的時候,我們想要連接兩個字符串,這個時候我們可以使用符號##,它會幫我們把左右宏參數連接起來。而#號會給后面的內容的左右加上雙引號,也就是變成字符串
我們先舉一個關于##符號的例子
// 指數宏
#define _POWER(_BASE_, _EXPONENT_) (int)(_BASE_##e##_EXPONENT_)
#define POWER(_BASE_, _EXPONENT_) _POWER(_BASE_, _EXPONENT_)
我們可以用宏實現把兩個數字轉換成一個指數。但是我們注意到,我這里好像畫蛇添足的加多了一個宏,這個是為什么呢?因為凡是加了#或者##的宏是不會進行二次解析的。比如說下面的:
#define A 1
#define B 2
_POWER(A, B); // 這里會被替換成 (int)(AeB);
POWER(A, B); // 這里先會被替換成 _POWER(1, 2); 然后變成 (int)(1e2);
所以說我們在使用的時候需要進行多一步轉換。
最后再舉一個#符號使用的例子,其實這個我使用的不是很多,所以只能是給一個最簡單的例子:
// 將一個數字轉換稱為字符串
#define a 90 // 在這里a是(int)90
#define _STR(_STRING_) #_STRING_
#define STR(_STRING_) _STR(_STRING_)
printf("The number is %s.\n", STR(a)); // 這里會把a先轉換成90再轉換成“90”
這些宏有時候可以幫助我們完成重要的操作,所以還是很有用的。