為什麼int型的負數會比字元串函數length()返回的值大?
如圖:
執行結果:
int和unsigned int比較大小時,int會轉換為unsigned int.
String.length()返回類型是String::size_type, 這是一個unsigned的整型,但標準沒聲明是具體哪一個整型,只要求保證能容納可能的最長string的字元個數。所以,這是平台相關的,比如32位平台的地址空間只能到4G(=2^32) bytes,這意味著理論的最長的String長度是4G bytes, 那一個unsigned int 就夠了(假設int是32位,幾乎都是); 又如64位平台,現在可支持的地址空間達到2^48 bytes,則int(如果還是32位的話)就不夠了,可能要unsigned long, 甚至unsigned long long. 這得看你平台的實現,看頭文件里咋定義的。
假設String::size_type是unsigned int, 則 i &> t.length() 這個表達式中,兩個操作數是 signed int 和unsigned int,按照標準中尋常算術轉換(usual arithmetic conversions)[1]的要求:signed int要被轉換為 unsigned int, 此例中, i 被轉換,相當於(unsigned int)-1, 等同於UINT_MAX, 大於 t.length()。
假設String::size_type是unsigned long, 且sizeof(unsigned long) &> sizeof(unsigned int)。 則 i &> t.length() 這個表達式中,兩個操作數是 signed int 和unsigned long,按照標準中尋常算術轉換(usual arithmetic conversions)的要求: signed int要被轉換為更大類型的unsigned long, 此例中,相當於(unsigned long)-1, 結果也一樣。
尋常算術轉換(usual arithmetic conversions)有點複雜,但核心是轉換到一個包含更大的類型, 並且要保證轉換不失真,見:[1]Usual Arithmetic Conversions因為length返回的數字是unsigned的,signed和unsigned在一起比較會有一些神奇的效果。
今天剛好看到了CSAPP的第二章,就有講到。。int的負數轉為unsigned會加上2的w次方的(w是你電腦的位數)。反過來,unsigned轉為int的話,如果這個unsigned超過int的最大值的話就會減去2的w次方。至於原因的話,請去讀CSAPP,即《深入理解計算機系統》。
我擦 不應該是 負數在計算機里存儲的是補碼嘛?-1 = ~1 + 1 =0xFFFF_FFFF(假設是32位)當然大於5了
string返回的長度類型是string::size_type,而size_type是unsigned的,當一個signed和一個unsigned做運算時signed會轉化為unsigned。一個負數轉化為無符號數時,其值等於該負數值加上無符號數最大值。這樣應該知道了吧。
請查看unsigned int 與signed int 的取值範圍,和二者進行強制類型轉換的規則,如果沒有明確的強制類型轉換,會使得int 向unsigned int 轉換,導致負數變為INT_MAX
我又來安利「蕭三本」了。
趕緊去讀蕭三本之首,《CSAPP(深入理解計算機系統)》。
讀完第二章,你不但能知道為什麼負數的int比較大,還能知道大多少。心動了嗎?京東上73塊錢一本,隔天就送到家。(五毛錢一條,括弧內刪掉。)
length()返回size_type類型,而size_type在string內部被定義為size_t類型,size_t為unsigned的,具體請看c++ - unsigned int vs. size_t。int與無符號比較時會轉化為無符號的整數。而-1的二進位表示為32個1(32位的),它按照無符號數來解釋就是2^32 - 1,當然遠遠比5大了。
0xfffffffff是最大的,但它可能等於-1
推薦閱讀:
※C++ 用輸入的變數作為數組長度是壞習慣嗎?
※在oi/acm中,有什麼冷門但好用的stl函數?
※如何向完全不懂編程的小夥伴解釋「程序寫死」?
※為什麼 C++ 只比 VBA 快 4倍?
※正在學c++但是越學越覺得自己還有好多東西不知道?
TAG:C |