是否可以在預處理過程中連接字符串?使用預處理器的字符串串聯
我發現這個例子
但是它並沒有爲我工作 - 打印出「你好」當我用gcc -std=c99
UPD這個例子貌似現在的工作。但是,它是c預處理器的一個正常特性嗎?
是否可以在預處理過程中連接字符串?使用預處理器的字符串串聯
我發現這個例子
但是它並沒有爲我工作 - 打印出「你好」當我用gcc -std=c99
UPD這個例子貌似現在的工作。但是,它是c預處理器的一個正常特性嗎?
級聯相鄰串litterals的不預處理器的功能,它的核心是語言(C和C++)的功能。你可以這樣寫:
printf("Hello "
" world\n");
的 '##' 的預處理操作者進行標記粘貼。當一個宏展開時,每個'##'運算符兩邊的兩個令牌被合併成一個單獨的令牌,然後替換宏擴展中的'##'和兩個原始令牌。
考慮一個解釋命名命令的C程序。有可能需要在命令表,或許聲明爲結構數組如下:
struct command { char *name; void (*function) (void); }; struct command commands[] = { { "quit", quit_command }, { "help", help_command }, ... };
這將是清潔不必須給每個命令的名字兩次,一次在字符串常量,一次在功能名稱。以命令的名稱作爲參數的宏可以使這不必要。可以使用字符串化創建字符串常量,並通過將參數與
_command
連接來創建函數名稱。下面是它是如何做:#define COMMAND(NAME) { #NAME, NAME ## _command } struct command commands[] = { COMMAND (quit), COMMAND (help), ... };
你確實可以連接預處理器中的標記,但要小心,因爲它很棘手。關鍵是##運算符。如果你在你的代碼的頂部拋出這樣的:
#define myexample(x,y,z) int example_##x##_##y##_##z## = x##y##z
話,基本上,這是什麼呢,是在預處理過程中,它會採取任何調用該宏,如下列:
myexample(1,2,3);
,它會從字面上變成
int example_1_2_3 = 123;
這可以讓你一噸的靈活性,同時編碼,如果你正確地使用它,但它並不完全適用你如何嘗試使用它。用一點按摩,你可以讓它工作。爲你的榜樣
一個可能的解決方案可能是:
#define H "Hello "
#define W "World!"
#define concat_and_print(a, b) cout << a << b << endl
,然後像做
concat_and_print(H,W);
我只是想我要補充一點,引用源,爲什麼這個問題的解答。
C99標準§5.1.1.2定義了C代碼的轉換階段。第6條規定:
- 相鄰字符串文字令牌是級聯。
類似地,在C++標準(ISO 14882)§2.1定義翻譯的相位。這裏子部分6陳述:
6將相鄰的普通字符串文字標記連接在一起。相鄰的寬字符串文字標記是連接的。
這就是爲什麼你可以將它們彼此相鄰的簡單連接字符串:
printf("string"" one\n");
>> ./a.out
>> string one
問題的預處理部分的#define
預處理指令,它不會取代簡單地使用從標識符(H
)到字符串("Hello "
)。
這是一個C++標準或只是一個gcc功能? – bibi 2016-12-09 07:38:39
在你的例子中,連接是在運行時完成的,而不是由預處理器完成。 – 2017-06-13 15:19:13