Summary
1)'#'用於在預處理期
將巨集引數轉換為字串
;只在巨集定義中有效
,編譯器不知道'#'
的存在
2)可以使用#+函式名
,在呼叫時列印函式名
3)'##'用於在預處理期 拼接兩個識別符號
;只在巨集定義中有效
,編譯器不知道'##'
的存在
4)可以使用'##'快速定義結構體
、使用結構體,快速定義類
等。
·#和##運算子分析
1、'#'
- '#'運算子用於在
預處理期
將巨集引數轉換為字串
(給引數加上雙引號
); - '#'的轉換是在預處理期完成的,所以
只在巨集定義中有效
;編譯器不知道'#'
的轉換作用 用法:
#define STRING(s) #s printf("%s\n", STRING(hello world)); 單步編譯:gcc -E test.c -o test.i 中間結果:printf("%s\n", "hello world");
可以使用#+函式名
,在呼叫時把函式名列印出來
:
#define CALL(f, p) (printf("call function: %s\n", #f), f(p))
void func()
{
printf("function output");
}
int main()
{
CALL(f, 1); // C語言中如果不寫引數列表,則接受任意多引數
return 0;
}
2、'##'
- '##'運算子用於在
預處理期
粘連兩個字元(拼接字元
) - '##'的拼接作用是在預處理期完成的,因此
只在巨集定義中有效
、編譯器不知道'##'
的拼接作用 用法:
#define CONNECT(a, b) a##b int CONNECR(a, 1); // int a1; a1 = 2;
工程中可以用'##'快速定義結構體
(定義不同的類
等)
// 在C語言中使用結構體必須帶上struct關鍵字,就可以用下面的巨集封裝下typedef,
// 然後就可以把struct當成一個型別來用
#define STRUCT(type) typedef strtuct __tag_##type type; \
struct __tag_##type
STRTUCT(Student)
{
char* name;
int id;
};
int main()
{
Student s;
s.name = "ss";
s.id = 1;
printf("name: %s, id: %d\n"), s.name, s.id);
retrun 0;
}
本文總結自“狄泰軟體學院”唐佐林老師《C語言進階課程》。
如有錯漏之處,懇請指正。