簡體   English   中英

下面的例子中預處理器是如何工作的?

[英]How does the pre-processor work in the following example?

在以下示例中:

#define PRNT(x, y) printf("X is %s and Y is %s\n", #x, #y)
int main(void)
{
    PRNT("HELLO", 4);
}

這給出了:

X 是“你好”,Y 是 4

預處理器如何在上面進行替換? 例如,它為什么不評估為:

  1. 開始: printf("X is %s and Y is %s\n", #x, #y)
  2. 添加 x="Hello", y=4: printf("X is %s and Y is %s\n", "Hello", 4)
  3. Printf 應該返回: X is Hello and Y is 4\n <-- HELLO不是"HELLO"

那么它如何/為什么在 HELLO 周圍添加額外的" ;也就是說,為什么它打印..."HELLO"...而不僅僅是...HELLO... ?將這兩個參數傳遞給printf function 時,它最終變為\" \"HELLO\""4"

這對於x, y是正確的,但不是#x, #y使用“stringizing”修飾符

如果你對一個字符串進行字符串化,你只會得到一個字符串,但它會包含周圍的引號。 如果對數字進行字符串化,則會得到一個字符串。

一般來說,對於給定的x你會得到"x" ,所以對於"x"你會得到"\"x\""

預處理器是否將字符串中的引號翻譯成\" ,因此在將這兩個 args 傳遞給 printf function 時,它最終會變成\"HELLO\""4"

是的。

如果您樂於接受 Microsoft 文檔, 請參閱此處

此外,如果參數中包含的字符在字符串文字中使用時通常需要轉義序列,例如引號 (") 或反斜杠 (\) 字符,則會在字符之前自動插入必要的轉義反斜杠。

或者,如果您更喜歡更正式的版本,以下是C11(草案)標准的內容:

6.10.3.2 # 運算符


2 語義

... 否則,參數中每個預處理標記的原始拼寫將保留在字符串文字中,但產生字符串文字和字符常量的拼寫的特殊處理除外:在每個字符的 " 和 \ 字符之前插入一個 \ 字符常量或字符串文字(包括分隔的 " 字符),...

#X給出了一個字符串文字,其內容是 X。所以帶有參數"FOO"#給出了一個字符串文字,其五個字符是" , F , O , O , " (當然還有 null 終結者)

預處理發生在代碼被標記和轉義序列處理之后,預處理的結果是一個標記 stream(不是某種需要重新標記和重新轉義處理的源文件)。

"HELLO"是您傳遞給宏的令牌。 #運算符將其轉換為字符串,因此您的字符串將為 "\"HELLO\"",就像您傳入數字4時,它變為"4" 因此,當預處理器運行時,我希望您的代碼如下所示:

int main(void)
{
    printf("X is %s and Y is %s\n", "\"HELLO\"", "4");
}

這樣做是因為宏內部變量前面的“#”。 它被稱為“字符串化”操作符,它將接受輸入變量,然后,將其字符串化。 這意味着在它周圍加上引號,以及已經在變量中的 escaping 。 這意味着,當展開時, "Hello"變成"\"Hello\""並且4變成"4"

字符串化(當您在宏中執行#x之類的操作時會發生什么)獲取項目並將其轉換為字符串。 4的情況下,你會得到"4" ,在"HELLO"的情況下,你會得到"\"HELLO\"" ,因為這兩個都是在打印項目時復制項目所需的確切字符串,因為例子。

許多編譯器可以選擇在預處理后停止以允許您檢查其效果,例如使用gcc-E標志:

pax:~> gcc --std=c17 -E prog.c
# 1 "prog.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "prog.c"

int main(void)
{
    printf("X is %s and Y is %s\n", "\"HELLO\"", "4");
}

#xx轉換為字符串。

IE

x = "Hello"

然后

#x = "\"Hello\""

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM