2016-04-13 131 views
-2

有人可以向我解釋爲什麼下面的代碼輸出0 0。我是數學上a-b == 0a == b值相同但不相等

char* V1 = "hello, world!\n"; 

main(){ 
    F1(V1); 
} 

F1(A1){ 
    printf("%u %u\n", V1 - A1, V1 == A1); 
} 
+8

不要告訴我你真的寫了代碼..... –

+0

這是一個最小的可行的例子,從別人的錯誤代碼...他們聲稱它在Visual Studio中工作正常... – user12341234

+3

'=='比較在C中的字符串並不意味着你認爲它的意思。 – callyalater

回答

2

作爲每C11標準,章節§6.5.6,兩個指針只能任何只有當它們是從同一陣列對象中減去的印象。

當兩個指針相減,既應指向同一陣列對象, 或一個過去的數組對象的最後一個元素的元素;結果是兩個數組元素的 下標的差異。結果的大小是實現定義的, 及其類型(有符號整數類型)是<stddef.h>標頭中定義的ptrdiff_t。 如果結果在該類型的對象中不可表示,則行爲未定義。 [...]

這就是說,你應該使用%td打印ptrdiff_t類型的結果,從指針減法產生。

接下來,使用==運算符,它不能用來比較字符串(數組)的內容,它基本上比較指針本身(而不是它們指向的內容)。

+0

好吧,所以兩個值不相等的原因是因爲這是未定義的行爲? – user12341234

+1

@ user12341234首先,它是錯誤的代碼(沒有違法),其次,'=='和'strcmp()'不一樣,第三,你是對的。 –

+0

首先:沒有冒犯,我沒有寫這個,只是簡化了它。其次:我不認爲最初的意圖是比較字符串內容,但指針。第三:感謝。 – user12341234

2

As @SouravGhosh指出,這裏有一個未定義的行爲。儘管如此,理解爲什麼第二個打印值有時是0並且有時是1(取決於它運行的機器),這很有趣。

輸入F缺少顯式類型意味着A1隱含爲int。函數調用F(V1)因此將指針V1轉換爲int。在某些機器上,這可能是一個縮小的轉換,這就是爲什麼在某些機器上比較V1 == A1是正確的,而在其他機器上是錯誤的。也許在某些機器上,V1 - A1中的兩個參數都被轉換爲整數(因此值爲0),但是在比較V1 == A1(這是ub)試圖將A1轉換爲有效地址並失敗或將其轉換爲不同的地址。

+0

但是,如果值相同,並且縮小了,那麼'=='的兩個操作數都不會被降低並仍然相等? – user12341234

+0

好問題。將整數與指針比較是未定義的行爲,因此比較是未定義的。在任何情況下,'V1 == V1' *爲真,並且'A1 == V1'有時評估爲false,而從'pointer'到'int'的隱式強制轉換是唯一一個兩端之間的差異可以引入比較。也許問題不是縮小本身,而是轉換爲有符號的數字。 –

相關問題