2015-05-18 60 views
5

這一小片在VS2013代碼工作,但由於某種原因,它不print.it似乎-1>的strlen(STR)爲什麼在C中爲-1> strlen(t)爲真?

任何人有一個想法,我做錯了什麼

char *str="abcd"; 
if(-1<strlen(str)) 
printf("The size of the string is %d", strlen(str));  
return 0; 
+1

'strlen(str)'的輸出值是什麼? – sasquatch

+1

可能是它返回無符號值並且會破壞事物 –

+2

在編譯器上打開最大設置的警告是很好的 –

回答

10

任何人有一個想法,我做錯了什麼

strlen()返回size_t,這是一個無符號整數類型。被解釋爲無符號整數的-1是一個很大的值,因此它最終大於字符串的長度。您可以使用-Wsign-compare標誌gcc和其他一些編譯器在嘗試比較簽名值和無符號值時發出警告。

另外,將字符串的長度與-1進行比較沒有多大意義。長度永遠不會是負面的;它的總是將是0或更大。所以你可能想要重寫你的代碼來測試0,或者正確地實現你想要測試的任何條件。

if(-1<strlen(str)) printf("The size of the string is %d", strlen(str));

在這段代碼中,你可能會合理預期的測試總是成功而printf()執行,因爲長度總是0以上。但是您發現測試實際上失敗並且printf()從未發生,因爲-1被升級爲無符號,因此它可以與size_t進行比較。簡單的解決方案是徹底刪除條件:您知道測試總是會成功,所以不需要它。只是刪除if*

printf("The size of the string is %zu", strlen(str)); 

*此外,改變從%d打印格式說明%zu以來,馬特麥克納布在評論中指出,你想打印size_t

+1

你可以告訴OP有關編譯器的警告,如果啓用,防止這種錯誤。 – chqrlie

+0

@chqrlie好的建議;完成。 – Caleb

+1

非常感謝! –

4

strlen(str)返回一個無符號整數。將帶符號整數與無符號整數進行比較時,編譯器將帶符號值轉換爲無符號。當轉換爲無符號時,-1變爲2^32 - 1(假設strlen返回一個32位整數),它大於您要比較的字符串的長度。

+1

不要認爲'size_t'是32位長。 – Caleb

+0

你可以告訴OP關於編譯器的警告,如果啓用,防止這種錯誤。 – chqrlie

+0

轉換爲'size_t',而不是'int'。 'strlen'返回'size_t',現在這種情況非常普遍,超過了32位。 – juanchopanza

4

strlen返回size_t類型的值。這是一個無符號整數類型。

當將帶符號的值與對應的無符號類型的值進行比較時,C中的規則是將帶符號的值轉換爲無符號值。

如果這些值的大小不同,例如,如果您的系統有4個字節的int和8個字節的size_t,那麼規則是將較小類型的值轉換爲較大類型的值。

無論哪種方式,這意味着-1轉換爲size_t,導致SIZE_MAX這是一個很大的正值。 (無符號類型不能包含負值)。

這個較大的正值大於字符串的長度,所以小於比較返回false。

+0

您可以告訴OP關於編譯器警告,如果啓用,防止這種錯誤。 – chqrlie

+0

@chqrlie取決於編譯器和設置的質量。我傾向於禁用無符號簽名警告,因爲它們往往是誤報。 –

+0

非常感謝! –