關於#和##c#
在C語言的宏中,#的功能是將其後面的宏參數進行字符串化操做(Stringfication),簡單說就是在對它所引用的宏變量經過替換後在其左右各加上一個雙引號。好比下面代碼中的宏:數組
1. #使用ide
#define WARN_IF(EXP) /函數
do{ if (EXP) /ui
fprintf(stderr, "Warning: " #EXP "/n"); } /spa
while(0)指針
那麼實際使用中會出現下面所示的替換過程:code
WARN_IF (divider ); 其中divider == 0對象
被替換爲blog
do { if (divider == 0) fprintf(stderr, "Warning" "divider == 0" "/n"); } while(0);
這樣每次divider(除數)爲0的時候便會在標準錯誤流上輸出一個提示信息。
2. ##使用
而## 被稱爲鏈接符(concatenator),用來將兩個Token鏈接爲一個Token。注意這裏鏈接的對象是Token就行,而不必定是宏的變量。好比你要作一個菜單項命令名和函數指針組成的結構體的數組,而且但願在函數名和菜單項命令名之間有直觀的、名字上的關係。那麼下面的代碼就很是實用:
struct command { char * name; void (*function) (void); };
#define COMMAND(NAME) { NAME, NAME ## _command } 此處的##表示後面有內容與NAME連接
// 而後你就用一些預先定義好的命令來方便的初始化一個command結構的數組了:
struct command commands[] = { COMMAND(quit), COMMAND(help), ... }
COMMAND宏在這裏充當一個代碼生成器的做用,這樣能夠在必定程度上減小代碼密度,間接地也能夠減小不留心所形成的錯誤。咱們還能夠n個##符號鏈接 n+1個Token,這個特性也是#符號所不具有的。好比:
#define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d //注意這裏的規則(a##開頭,##d結束,中間都用##x##)
typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);
// 這裏這個語句將展開爲:
// typedef struct _record_type name_company_position_salary;
我的認爲##相似 運算符+ 起到鏈接的做用。
3 再看一個#使用以下:
#define display(name) printf(""#name"") int main() { display(name); }
運行結果是name,爲何不是"#name"呢?
---------------------------------------------------------------
#在這裏是字符串化的意思 printf(""#name"") 至關於 printf("" "name" "")