2014-07-11 47 views
8

我在做宏的基礎知識。我定義一個宏如下:
整數到字符串轉換器(使用宏)

#define INTTOSTR(int) #int 

將整數轉換爲字符串。

這個宏是否完美地將整數轉換爲字符串?我的意思是有些情況下這個宏可能會失敗?

我可以用這個宏來代替itoa()這樣的標準庫函數嗎?

例如:

int main() 
{ 
    int a=56; 
    char ch[]=INTTOSTR(56); 
    char ch1[10]; 
    itoa(56,ch1,10); 
    printf("%s %s",ch,ch1); 
    return 0; 
} 

上述程序按預期方式工作。

有趣的是,這個宏甚至可以將float的值轉換爲字符串。

例如:

INTTOSTR(53.5); 

很好地工作。

到目前爲止,我在使用itoa函數將int轉換爲我所有項目中的字符串。我可以自信地在所有項目中更換itoa。因爲我知道使用宏比函數調用的開銷少。在

+0

你試過'INTTOSTR(a)'嗎? –

+3

'INTTOSTR(SOME_CONSTANT)' - 哎呀。這基本上是一個普通的字符串化宏,除了只用於整數,這不是太有用,特別是考慮到它接受其他的東西。 – chris

+0

C++ 11具有此['to_string'](http://www.cplusplus.com/reference/string/to_string/)的功能。關於宏有幾個問題。 – 101010

回答

2

在C語言中,你可以使用itoa或者如果你是絕望,想避免它,使用的snprintf例如:

snprintf(my_str, sizeof(int), "%i", my_int); 

與宏的問題是,你的心思常量,但當然,當你需要使用一個持有整數的變量時,你的宏將被破壞。您的宏將嘗試將宏名稱串起來,而不是它將保存的值。

如果你對常量沒有問題,那麼你的宏是「好」的,否則它就會出現。

+0

是的,我得到了點, 我在想,我已經開發了一些真正有用的東西,甚至沒有嘗試變量。 –

5

宏執行(之前是精確的)編譯的時候,這樣你就可以在你的源代碼轉換成文字數爲字符串而不是存儲在一個變量

在你的榜樣一些,INTTOSTR(56)使用字符串化操作預處理器的最終結果爲"56"。如果你在一個變量上調用它,你會得到變量名稱而不是它的內容。

+0

是的,先生我注意到了,它不是轉換變量:( –

1

您的宏不會將整數轉換爲字符串,它將文字轉換爲字符串文字,這是非常不同的東西。

文字是代碼中任何普通數字或值的定義。當你做int x = 10;數字10整數字面,而x是一個變量和int是類型。 const char* ten = "10";還定義了一個文字,在這種情況下,一個字符串文字,其值"10"和一個名爲ten的變量,它指向定義此文字的地址。你的宏實際上做的是在任何實際編譯進行之前,改變文字表示的方式,從一個整數字面量轉換爲一個字符串文字。

因此,實際的改變是在任何編譯之前完成的,只是在源代碼級。宏不是函數,不能檢查內存,並且你的轉換不能用於變量。如果你嘗試:

int x = 10; 
const char* ten = INTTOSTR(x); 

你會很疑惑地發現,你的變量ten將實際持有的「x」值。這是因爲x被視爲文字,而不是變量。

如果你想看看發生了什麼,我建議要求你的編譯器停止預處理,並在你的代碼被實際編譯之前看到輸出。如果您傳遞-E標誌,您可以在GCC中執行此操作。

PS。關於浮點值轉換的明顯「成功」,它只是表明宏的危險:它們不是類型安全的。它不會將53.5看作一個浮點數,而是作爲由字符5,3,...表示的一個記號。和5個源代碼。