**
"#" 代表和乙個字串相連線
"##" 代表和乙個符號連線,符號可以是變數,或另乙個巨集符號。
舉例如下:
巨集定義如下
(1)#define dev_file_name "/dev/test_kft"
#define open_file(fd, n) \ \}
如此呼叫:
open_file(fd1, 1);
open_file(fd2, 2);
open_file(fd3, 3);
open_file(fd4, 4);
open_file(fd5, 5);
open_file(fd6, 6);
用gcc -e展開後,如下
2299: };
2300: };
2301: };
2302: };
2303: };
2304: };
如果沒有定義dev_file_name ,就是
2299: };
2300: };
2301: };
2302: };
2303: };
2304: };
所以可以很清楚的看出#n 解析出來的是"n" , 用於連線乙個已有的字串。
(2) 再來看 ## 是什麼意思, 巨集定義如下:
#define open_file(fd, n) \ \}
呼叫方式相同。
看巨集展開:
2299: };
2300: };
2301: };
2302: };
2303: };
2304: };
現在看清楚了, ##n 的作用是把n直接連線在了乙個符號的末尾. 好, 現在我們定義乙個符號看看效果。
#define dev_file_name1 "/dev/test_kft1"
再展開:
2299: };
2300: };
2301: };
2302: };
2303: };
2304: };
很顯然第乙個符號被替換了, 因為是符號是巨集的緣故。 這樣我們也能把這一擴充套件特性應用在變數上。
from:
之二:一,一般用法
我們使用#把巨集引數變為乙個字串,用##把兩個巨集引數貼合在一起.
用法:#include
#include
using namespace std;
#define str(s) #s
#define cons(a,b) int(a##e##b)
int main()
二,當巨集引數是另乙個巨集的時候
但雖要注意的是凡巨集定義裡有用'#'或'##'的地方巨集引數是不會再展開.
1, 非'#'和'##'的情況
#define tow (2)
#define mul(a,b) (a*b)
printf("%d*%d=%d\n", tow, tow, mul(tow,tow));
這行的巨集會被展開為 printf("%d*%d=%d\n", (2), (2), ((2)*(2)));
mul裡的引數tow會被展開為(2).
2, 當有'#'或'##'的時候
#define a 2
#define str(s) #s
#define cons(a,b) int(a##e##b)
printf("int max: %s\n", str(int_max)); // int_max #include
這行會被展開為printf("int max: %s\n", "int_max");
printf("%s\n", cons(a, a)); // compile error
這一行則是printf("%s\n", int(aea));
int_max和a都不會再被展開,
然而解決這個問題的方法很簡單. 加多一層中間轉換巨集.
#define a 2
#define _str(s) #s
#define str(s) _str(s) // 轉換巨集
#define _cons(a,b) int(a##e##b)
#define cons(a,b) _cons(a,b) // 轉換巨集
printf("int max: %s\n", str(int_max)); // int_max #include
printf("%s\n", cons(a, a));
加這層巨集的用意是把所有巨集的引數在這層裡全部展開, 那麼在轉換巨集裡的那乙個巨集(_str)就能得到正確的巨集引數.
三,'#'和'##'的一些應用特例
1, 合併匿名變數名
#define ___anonymous1(type, var, line) type var##line
#define __anonymous0(type,line) ___anonymous1(type, _anonymous, line)
#define anonymous(type) __anonymous0(type,__line__)
2,填充結構
#define fill(a)
typedef struct msgmsg;
enum;
msg _msg=;
3,記錄檔名
#define _get_file_name(f) #f
#define get_file_name(f) _get_file_name(f)
static char file_name=get_file_name(__file__);
4,得到乙個數值型別所對應的字串緩衝大小
#define _type_buf_size(type) sizeof #type
#define type_buf_size(type) _type_buf_size(type)
char buf[type_buf_size(int_max)];
itoa(2006, buf, 10);
from:
補充:1, "##"用於定義結構體型別.
若結構體成員相同, 但是為了有所區別, 需要定義成不同的型別名, 此時用"##"就非常方便了. 比如, 定義乙個用於除錯的結構體型別:
struct operationresult_struct
;但是我們想為http的除錯和檔案操作的除錯定義不同的型別名, 可以用如下方法.
用gcc -e 檢視預編譯結果.
include
#define xname(n) x ## n
#define print_xn(n) printf("x" #n " = %d\n", x ## n);
int main(void)
here's the output:
x1 = 14
x2 = 20
巨集定義中的 和 的區別
代表和乙個字串相連線 代表和乙個符號連線,符號可以是變數,或另乙個巨集符號。舉例如下 巨集定義如下 1 define dev file name dev test kft define open file fd,n 如此呼叫 open file fd1,1 open file fd2,2 open ...
巨集定義中的 和 的區別
剛才測試了巨集定義中的 和 的區別,希望能對大家有點幫助。結果如下 代表和乙個字串相連線 代表和乙個符號連線,符號可以是變數,或另乙個巨集符號。舉例如下 巨集定義如下 1 如此呼叫 用gcc e展開後,如下 如果沒有定義dev file name 就是 所以可以很清楚的看出 n 解析出來的是 n 用...
c C C 巨集定義中 的區別
表示 對應變數字串化 表示 把巨集引數名與巨集定義 序列中的識別符號連線在一起,形成乙個新的識別符號 連線符 它將單字元標記符變換為 單字元,即加單引號。例如 define b x x 則b a 即 a b 1 即 1 但b abc 卻不甚有效。cpp view plain copy include...