坑!坑!坑!防不勝防的unsigned int的運算

  我很早之前就知道,unsigned int與int運算的時候,int會被轉化爲unsigned int來進行運算。一直覺得定這條規則的人是極度反人類的,雖說unsigned int可以表示更大的正值,但畢竟我們不太會把unsinged想像成一個負數,而一個負的int數可能在無意間就變成了最大的正數。

  所以,我對這個問題很慎重。小心翼翼地,一直沒怎麼出過錯。直到有一天。

第一回合

  那是一個陽光明媚的午後,我正愜意地刷leetcode。要遍歷vector中除最後一個元素的所有元素。我這樣寫道:

for(int i=0;i<nums.size()-1;++i)
    bulabula;

  沒什麼錯吧?沒錯!提交的時候發現程序出現了內存訪問錯誤。

  作爲一個自信的程序員,我自然想到了編譯器出了問題。於是在VS上測試,是沒有問題的!Stupid Leetcode!居然說我的代碼有問題,我的代碼怎麼可能有問題?

  就在我要放棄這一題的時候,我突然想到了邊界條件,於是把nums清空再測試,VS提示內存訪問錯誤。Soryy Leetcode,是在下輸了……

  在進行一番絞盡腦汁之後,我把目光聚焦在了size_t,查了資料後發現,size_t就是個unsigned類型,恍然大悟……nums.size()-1就等於最大的正數,i與之比較,肯定是符合條件的!OH NO!

第二回合

  在經歷了上述事情之後,我一般會這麼寫程序:

for(int i=0;i<(int)nums.size()-1;++i)
    bulabula;

  再也沒有出現過問題。每次看到別人還寫我之前那樣的代碼,我都會會意一笑,然後告訴他人的我心得。直到有一天,我看到一個大牛寫了這樣的代碼:  

for(int i=nums.size()-1;i>=0;--i)
    bulabula;

  我想我發現了大牛的錯誤。有了上次的教訓,這次我測試了一下邊界條件。什麼?居然正常運行?

  在想了很久之後,我得出以下結論:nums.size()-1的確得到了一個最大的unsigned int,可是把它賦給int的時候,編譯器就傻傻地直接把unsigned int賦給了int,於是int就爲-1了。大牛畢竟是大牛……

  在學知識的道路上總會有羊腸小道,多走一些羊腸小道,我才能知道有沒有近道!加油加油!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章