C(和C++)中的巨集(Macro)屬於編譯器預處理的範疇。
下面對常遇到的巨集的使用問題做了簡單總結。
單井號(#)和雙井號(##)
(#)的功能是將其後面的巨集引數進行字串化操作(Stringfication):
#define WARN_IF(EXP) /
do{ if (EXP) /
fprintf(stderr, "Warning: " #EXP "/n"); } /
while(0)
實際使用會出現下面的替換過程:
WARN_IF (divider == 0);
被替換為
do {
if (divider == 0)
fprintf(stderr, "Warning" "divider == 0" "/n");
} while(0);
定義單行巨集:主要有以下三種用法。
1) 前加##或後加##,將標記作為一個合法的識別字的一部分,例如:
#define A(x) T_##x // int A(1) = 10; 等效於 int T_1 = 10;
#define A(x) Tx##__ // int A(1) = 10; 等效於 int T1__ = 10;
2) 前加#@,將標記轉換為相應的字元,注意:僅對單一標記轉換有效:
#define B(x) #@x // B(a) 等效 'a',B(1) 等效 '1',但B(abc)卻不甚有效。
3) 前加#,將標記轉換為字串。
#define C(x) #x // C(1+1) 等效於 "1+1"
(##)連接子(concatenator),
其功能是在帶參數的巨集定義中將兩個Token聯接起來,從而形成一個新的Token。
但它不可以是第一個或者最後一個子串。
譬如做一個功能表項目命令名稱和函數指標組成的結構陣列,並在函數名和功能表項目命令名之間有直接名字上的關係:
struct command
{
char * name;
void (*function) (void);
};
#define COMMAND(NAME) { NAME, 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
typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);
// 這裡這個語句將展開為:
// typedef struct _record_type name_company_position_salary;
MSDN上的一個例子:
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;
// Main中調用 paster( 9 ); 這個語句將展開為:
// printf( "token" "9" " = %d", token9 );
注意到在這個例子中,paster(9); 中的這個”9”被原封不動的當成了一個字串,
與”token”連接在了一起,從而成為了token9。
而 #n 也被”9”所替代。可想而知,上面程式運行的結果就是在螢幕上列印出token9=9
2016年8月9日 星期二
訂閱:
張貼留言 (Atom)
Uninstalling HEVC Video Extensions from Windows
Microsoft store packages are usually APPX format installations (HEVC Video Extensions is installed as APPX package) You will need to use Pow...
-
C(和C++)中的巨集(Macro)屬於編譯器預處理的範疇。 下面對常遇到的巨集的使用問題做了簡單總結。 單井號(#)和雙井號(##) (#)的功能是將其後面的巨集引數進行字串化操作(Stringfication): #define WARN_IF(EXP) / ...
-
$ dmesg | grep tty [ 0.000000] console [tty0] enabled [ 12.903931] 00:05: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550...
-
dmesg是用來讀取開機時Kernel顯示的硬體資訊,紀錄一下常用的使用方式。 (開機訊息亦保存在/var/log目錄中,名稱為dmesg的文件) # dmesg | more 分頁顯示所有資訊 # dmesg -c 清除 dmesg buffer # dmes...
沒有留言:
張貼留言