在無符號數和有符號數比較時,編譯器會將有符號數轉換為無符號數,一定要注意這一點,否則會非非非非非常坑!!!!
比如說
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 int x=-1; 5 unsigned int y=2; 6 if(x>y) 7 cout<<"yes"; 8 else 9 cout<<"no"; 10 return 0; 11 }
x是有符號的-1,y是無符號的2,正常人都知道-1小於2啊,所以運行這段代碼后,一定會輸出no啊,可是結果卻是yes,為什么呢?因為無符號數和有符號數作比較的時候,編譯系統會自動將有符號數轉換為無符號數,這就是關鍵了,當有符號數-1和無符號數2比較的時候,系統會把有符號的-1轉換為無符號數,-1轉換有無符號數就是4294967295,這個數當然比2大,所以就輸出yes了。
上面說的這種情況是比較明顯得,因為代碼中出現了無符號數類型,可是有時候,這種錯誤及其不容易發現,比如:
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 int x=-1; 5 string str="JOHN WALKER"; 6 if(x>str.size()) 7 cout<<"yes"; 8 else 9 cout<<"no"; 10 return 0; 11 }
這段代碼中還是定義了一個值為1得有符號變量x,然后又定義了一個字符串,是用string類型定義的,然后判斷x是不是大於字符串的長度,這個字符串長度為11,這誰都知道!所以x肯定小於11啊,但是代碼的運行結果卻是yes,納尼?-1竟然大於11???
一定是我的打開方式不對,可是嘗試好幾次之后,結果都一樣,於是我就陷入了對人生的大思考之中……
那么最后,我終於發現,這個c++自帶的string類的size函數和length函數的返回值竟然是無符號數!那么這就可以說的通了,有符號數和無符號數比較的過程中,有符號數會轉換為無符號數,-1轉換為無符號數是4294967295,所以它就大於11了,所以就輸出yes了。
唉,沒想到罪魁禍首竟然是因為size函數和length函數的返回值是無符號數,其實這個也可以理解,當初開發C++的前輩一定是認為字符串的長度一定不能是負數,所以將返回值設成無符號數,這樣還能增大表示范圍。
所以以后再用size和length函數的時候,還是先用一個有符號變量來接收返回值吧,這樣就不會有問題了。
比如:
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 int x=-1; 5 string str="JOHN WALKER"; 6 int len=str.size(); 7 if(x>len) 8 cout<<"yes"; 9 else 10 cout<<"no"; 11 return 0; 12 }
這樣,輸出就一定是NO了。