2016-06-13 48 views
0

考慮以下兩個代碼字符串:
比較使用memcmp在C

char str1[] = "Hello"; 
char str2[] = "Hello\0\0\0l\0o"; 
int x; 
x=memcmp(str1,str2,sizeof(str2)); 
printf("%d",x); 

當我運行它,它顯示了O/P爲:

1 

你能解釋的理由這個。我瞭解到兩個字符串中的每個字節都會進行比較並相應返回。但我不清楚最後會發生什麼。

+0

你確定'str1 []'和'str2 []'沒有任何大小? –

+0

您是否考慮在您的初學者C書中閱讀關於memcmp的內容?除了你的代碼中的錯誤之外,你的問題的答案可以在那裏找到。 – Lundin

回答

6

您的程序調用未定義的行爲。

sizeof(str2)大於sizeof(str1)。通過使用它作爲memcmp的最後一個參數,您正在訪問您不應該訪問的內存。這是未定義行爲的原因。

因此,輸出可以是任何東西。試圖理解它毫無意義。

3

當你做字符串比較時,一旦它達到'\ 0'就會停止比較。在這裏你已經完成了一個memcmp,它不會停止,直到讀取所有請求的字符。

在這種情況下,你要比較sizeof(str2)字節,在str1的情況下,在末尾隱含的'\ 0'後會產生垃圾。

要在比較得到一個0:

  • 只比較的sizeof(STR1)或的sizeof(STR1)+1個字節
  • 做一個字符串比較
1

請記住,這是不安全有時危險在這裏調用memcmp因爲str1長度比str2少。

考慮下面的代碼:

int main() 
{ 
    char str1[] = "Hello"; 
    char str2[] = "AAAAA\0\0\0l\0o"; 
    for(int i=0; i<sizeof(str2); i++) 
     printf("%02X %02X\n", str1[i], str2[i]); 
    printf("\n%X %X", (int)str1, (int)str2); 
    return 0; 
} 

輸出是

48 41 
65 41 
6C 41 
6C 41 
6F 41 
00 00 
41 00 
41 00 
41 6C 
41 00 
41 6F 
00 00 

28FEEE 28FEF4 

我們可以看到[6] - [11]個字節的str1實際上是str2第一個字節,它可以通過str1str2的地址確認。在這種情況下,GCC/MSVC(我對Clang不太確定)將兩個字符串const initalizer存儲在一行中。因此,當您撥打memcmp時,在空終止符\0後,該函數實際上將str2的第一個字節與\0進行比較。但請記住,編譯器存儲常量的方式在任何情況下都可能會改變。你應該不是依靠這種行爲。