安靜的型別轉換

2021-05-24 14:04:37 字數 2105 閱讀 5229

sizeof(i)等於4,i等於-1,照理來說控制台應該會列印jj,可是實際上

jj他他媽的不見了

這和c的隱式轉換有關。先解釋乙個術語integer promotion

在乙個算術表示式中,編譯器總要把表示式的運算元統一成同一種型別才能做處理,如果不同,就要進行型別轉換。型別轉換過程中,遇到char, short int 或者 bit-field (包括他們的有符號和無符號型別),如果源型別能完整的用 int 型別表示,就轉換成 int,否則轉換成 unsigned int,這個過程叫做integer promotion

下面是ansi c標準6.2.1.5的翻譯

兩個算術型別的運算元做算術運算,比如a + b,如果兩邊運算元的型別不同,編譯器會自動做型別轉換,使兩邊型別相同之後才做運算,這稱為usual arithmetic conversion。轉換規則如下:

如果有一邊的型別是long double,則把另一邊也轉成long double

否則,如果有一邊的型別是double,則把另一邊也轉成double

否則,如果有一邊的型別是float,則把另一邊也轉成float

否則,兩邊應該都是整型,首先按上一小節講過的規則對ab做integer promotion,然後如果型別仍不相同,則需要繼續轉換。首先我們規定charshortintlonglong long的轉換級別(integer conversion rank)乙個比乙個高,同一型別的有符號和無符號數具有相同的rank。轉換規則如下:

如果兩邊都是有符號數,或者都是無符號數,那麼較低rank的型別轉換成較高rank的型別。例如unsigned intunsigned long做算術運算時都轉成unsigned long

否則,如果一邊是無符號數另一邊是有符號數,無符號數的rank不低於有符號數的rank,則把有符號數轉成另一邊的無符號型別。例如unsigned longint做算術運算時都轉成unsigned longunsigned longlong做算術運算時也都轉成unsigned long

剩下的情況是:一邊有符號另一邊無符號,並且無符號數的rank低於有符號數的rank。這時又分為兩種情況,如果這個有符號數型別能夠覆蓋這個無符號數型別的取值範圍,則把無符號數轉成另一邊的有符號型別。例如遵循lp64的平台上unsigned intlong在做算術運算時都轉成long

否則,也就是這個有符號數型別不足以覆蓋這個無符號數型別的取值範圍,則把兩邊都轉成有符號數的rank對應的無符號型別。例如在遵循ilp32的平台上unsigned intlong在做算術運算時都轉成unsigned long(摘自http://learn.akae.cn/media/ch15s03.html)

回到前面那個例子,i是int型別,sizeof(i)是unsigned int型別。根據條件要用4.b這個分支來處理,兩個數都要轉換成 unsigned int ,而 -1 轉換成無符號數是個很大的數,大於 sizeof(i),所以 jj 就不見了。。。。

再來看個例子

這一次,

jj他他媽的回來了!

要解釋這個結果,可以用integer promotion 來回答。

因為兩個運算元型別不一致,所以對unsigned char進行integer promotion,由於1完全可以用 int 來表示,所以右邊的運算元就隱式轉換為 int 型別,-1和1比較,當然-1比較小。。

安靜的轉換有多安靜?

include int main else return 0 在c語言中要特別注意型別的隱式轉換,如上 a為int型別,b為unsigned int,根據表示式的型別轉換原則,a b中,先將a轉換為unsigned int型別。因為計算機儲存數值採用二進位制補碼形式,架設a為乙個4位的有符號整數,那...

安靜的思考

做好一件事的方法有千百種。但是自己做到最好的方法只有一種,就是在當前情況下我能想到的那種。所以不要糾結迷茫,想好了就去做,如果錯了,下次再改進。很難保證每做一件什麼事都恰好做到最好。忘掉過去的成績,也忘掉過去的失敗。我很明白現在應該怎麼做。過去的成功不會有多大幫助,過去的失敗也不能說明什麼。實事求是...

型別轉換 容器型別之間的轉換

強轉成字串,無非就是在原有的資料的基礎上兩邊套上引號 如果是字串,會把每乙個字元單獨的作為乙個元素放到列表中 如果是字典,只保留鍵,形成一套新的列表 如果是其他的容器,只是單純的在原有資料的基礎上換上 如果是字串,會把每乙個字元單獨的作為乙個元素放到元組中 如果是字典,只保留鍵,形成一套新的元組 如...