2012-09-26 26 views
0

也許一個奇怪的問題..C字符串比較 - 等同於真正的

我目前正在努力理解爲什麼以下等同於真正的即的「Hello World」打印到控制檯?我一直認爲在C中的字符串比較必須使用strcmp或類似的。

char *a = "Hello"; 
char *b = "Hello"; 

if(a == b) 
{ 
    printf("Hello World\n"); 
} 

我還認爲,如果地址相等,這隻會等同於真?它是文字的事實嗎?

PS。是的,這與任務幾乎沒有關係,但我只是想到了上面的問題。 - 這不會以任何方式回答任務。

+0

這取決於你的編譯器是否存儲「Hello」一次或兩次。 – chris

+1

字符串比較**可以**,應該用'strcmp'完成。正如蘇格拉底所說的,並非所有的貓都是魚。 –

+0

到目前爲止,所有五個答案都是正確的。如果你想親眼看看發生了什麼,你可以嘗試以下方法:(1)使用字符串文字初始化'a',用'strcpy'初始化'b',並且(2)打印指針'a的值將''和'b'轉換爲'int'以查看比較中使用的值'a == b'。 –

回答

3

您直接放入代碼的相同文字實際上會指向相同的內存位置以達到優化目的。

在這種情況下,編譯器在固定內存中放下「Hello」一次,然後在內存中指向ab

爲了更詳細地瞭解發生了什麼,我建議你編譯這個程序(首先添加一串字符串),然後使用gdb或valgrind或任何其他內存檢查器並手動查看指向字符串文字 - 你會發現在標準情況下,gcc將所有字符串文字放在內存中,並重新使用相同的字符串文字。

+0

順便說一下,這個答案是_gcc_如何做的事情; Kerrek SB是正確的,沒有語言保證會發生。 –

4

該語言沒有要求在何處以及如何存儲字符串文字。你所知道的是他們有靜態的存儲時間,你不能試圖改變數據。標準中沒有任何內容要求兩個不同的字符串文字具有不同的地址,並且實現會重複刪除字符串文字數據是完全合理的。

另一方面,沒有什麼要求將兩個相同的字符串文字存儲在相同的地址,所以比較地址沒有多大意義。總是使用strcmp來比較字符串的內容

2

a和b是指向字符的指針。

一個指針基本上存儲一個內存地址。你的a和b變量不保存單詞「hello」,但它們保存單詞「hello」所保存的內存地址。

在程序中打印a和b以查看其值。 它看起來像:632176或類似的東西,他們將是平等的。

所以代碼a == b基本上說:「做a和b指向相同的內存地址?」。他們這樣做,因爲「你好」是一個常量字符串,它只會被寫入一次內存。

1

這裏發生的事情是,你有兩個指針,分別叫做*a*b。接下來,如您所知,指針指向特定內存位置。現在,當*a*b被設置爲等同於完全相同的句子時,由此ab指向存儲器地址。然而,編譯器注意到這些指針是相同的句子,所以它將它們設置爲以指向完全相同的存儲器地址用於優化目的。

正因爲如此,什麼情況是這樣的:

a = 0xFFFFFFFF; 
b = 0xFFFFFFFF; 
if(0xFFFFFFFF == 0xFFFFFFFF){ 
    // Code 
} 

現在,當你對它們進行比較,編譯器將其視爲(0xFFFFFFFF == 0xFFFFFFFF)編譯器看到,他們是平等的,導致if statement變得真實,顯示Hello, World

但是,這可能不會發生在不同的編譯器上,因此您可能會在編譯器中得到不同的結果。儘管如此,這種行爲也適用於gcc。所以在這種情況下,您應該始終使用strcmp進行比較以避免像這樣的隨機行爲。

1

我相信如果你有兩個指針指向一個相同的值,那麼編譯器只會將兩個指針指向同一塊內存。它更高效。但是在C中,即使在這種情況下也總是使用strcmp。

+0

這是編譯器特定的,你不能指望它。總是像你所建議的那樣使用strcmp。 – CrazyCasta