這一小片在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;
這一小片在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;
任何人有一個想法,我做錯了什麼
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
。
strlen(str)
返回一個無符號整數。將帶符號整數與無符號整數進行比較時,編譯器將帶符號值轉換爲無符號。當轉換爲無符號時,-1
變爲2^32 - 1
(假設strlen返回一個32位整數),它大於您要比較的字符串的長度。
不要認爲'size_t'是32位長。 – Caleb
你可以告訴OP關於編譯器的警告,如果啓用,防止這種錯誤。 – chqrlie
轉換爲'size_t',而不是'int'。 'strlen'返回'size_t',現在這種情況非常普遍,超過了32位。 – juanchopanza
strlen
返回size_t
類型的值。這是一個無符號整數類型。
當將帶符號的值與對應的無符號類型的值進行比較時,C中的規則是將帶符號的值轉換爲無符號值。
如果這些值的大小不同,例如,如果您的系統有4個字節的int
和8個字節的size_t
,那麼規則是將較小類型的值轉換爲較大類型的值。
無論哪種方式,這意味着-1
轉換爲size_t
,導致SIZE_MAX
這是一個很大的正值。 (無符號類型不能包含負值)。
這個較大的正值大於字符串的長度,所以小於比較返回false。
您可以告訴OP關於編譯器警告,如果啓用,防止這種錯誤。 – chqrlie
@chqrlie取決於編譯器和設置的質量。我傾向於禁用無符號簽名警告,因爲它們往往是誤報。 –
非常感謝! –
'strlen(str)'的輸出值是什麼? – sasquatch
可能是它返回無符號值並且會破壞事物 –
在編譯器上打開最大設置的警告是很好的 –