我碰到一個斷言的這個例子來格式化,並想知道的#
是什麼時:什麼是#用%s
#define ASSERT(x) if (!(x)) { \
int *p = NULL; \
DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
*p=1; \
}
我碰到一個斷言的這個例子來格式化,並想知道的#
是什麼時:什麼是#用%s
#define ASSERT(x) if (!(x)) { \
int *p = NULL; \
DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
*p=1; \
}
#x
是字符串化指令
#define Stringify(x) #x
表示Stringify(abc)
將被替換爲
如
#define initVarWithItsOwnName(x) const char* p = #x
int main()
{
initVarWithItsOwnName(Var);
std::cout << Var; //will print Var
}
這是「stringize」預處理運算符。
它將令牌作爲參數傳遞給宏參數x
並將它們轉換爲字符串文字。
#
是預處理器的"stringizing" operator。它將宏參數轉換爲字符串文字。如果您調用ASSERT(foo >= 32)
,則在評估宏時,#x
將擴展爲"foo >= 32"
。
這是一個稱爲stringification的預處理器功能。它
用實際參數的文本文本替換[宏參數],轉換爲字符串常量。
你看到什麼叫字串。它允許您將宏的參數轉換爲字符串文字。你可以在這裏閱讀更多關於http://gcc.gnu.org/onlinedocs/cpp/Stringification.html。
#
是在第6.10.3.2節(C99)和第16.3.2節中定義的串化運算符。 (C++ 03)
它將宏參數轉換爲字符串文字而不擴展參數定義。
如果產生的更換是不是一個有效的字符串文字中, 行爲是不確定。 #運算符的評估順序是未指定。
例如,在語法上,字符串文字中反斜線字符的出現被限制爲轉義序列。
在下面的例子:
1 #define mkstr(x) # x
2 char *p = mkstr(a \ b);
/* "a \ b" violates the syntax of string literals */
#
的運算符的結果不必是"a \ b"
。
是否有任何情況下「替換結果不是有效的字符串文字」?我想不出任何。 – 2011-03-18 16:16:02
@James McNellis:在「新C標準」中找到一個例子,查看我的帖子。 – 2011-03-18 16:29:32
有趣。我對「預處理令牌序列的拼寫」(來自C++)的理解是編譯器需要執行任何必要的轉義,所以'mkstr(「a」)'會產生一個「」而不是「 「」 一 「」'。也許這不適用於無關的非空白標記? – 2011-03-18 16:36:34
哇...有時你可以在一分鐘內得到如此多的答案:) – 2011-03-18 16:05:06