1 字元和整型(整型提公升)
如果char、short int或者int型位段(bit-field),包括它們有符號或無符號變型,以及列舉型別,可以使用在需要int或者unsigned int的表示式中。如果int可以完整表示源型別的所有值,那麼該源型別的值就轉換為int,否則轉換為unsigned int。這稱為整型提公升。
2 尋常算術轉換
許多運算元型別為算術型別的雙目運算子會引發轉換,並以類似的方式產生結果型別。它的目的的產生乙個普通型別,同時也是運算結果的型別。這個模式成為「尋常算術轉換」。
如果其中乙個運算元型別是long double,那麼另乙個運算元也被轉換為long double。其次如果乙個運算元的型別是double,那麼另乙個運算元也被轉換為double,再次,如果其中乙個運算元的型別是float,那麼另乙個運算元也被轉換為float。否則兩個運算元進行整形公升級,執行下面的規則:
如果其中乙個運算元的型別是unsigned long int,那麼另乙個運算元也被轉換成unsigned long int。其次,如果其中乙個運算元型別是long int,而另乙個運算元的型別是unsigned int,如果long int能夠完整表示unsigned int的所有值,那麼unsigned int 型別運算元運算元被轉換為long int,如果long int 不能完整表示unsigned int的所有值,那麼兩個運算元都被轉換為unsigned long int。再次,如果乙個運算元的型別是long int,那麼另乙個運算元被轉換為long int。再再次,如果乙個運算元的型別是是unsigned int,那麼另乙個運算元被轉換為unsigned int。如果所有以上情況都不屬於,那麼兩個運算元都為int。
採用通俗語言大意如下:
當執行算術運算時,運算元的型別如果不同,就會發生轉換。資料型別一般朝著浮點精度更高、長度更長的方向轉換,整型數如果轉換為signed不會丟失資訊,就轉換為signed,否則轉換為unsigned。
int array = ;
#define total_elements (sizeof(array)/sizeof(array[0]))
int main()
/*...*/
}
total_elements所定義的值是unsigned int 型別(因為sizeof()的返回型別是無符號數)。
if語句在signed int和unsigned int 之間測試相等性,所以d被公升級為unsigned int型別,
-1 轉換成unsigned int 的結果將是乙個非常巨大的正整數。致使表示式的值為假。
修復這個bug:
if (d < (int)total_elements - 2)
3 對無符號型別的建議
1 盡量不要再你的**中使用無符號型別,以免正價不必要的複雜性。尤其是,不要因為無符號數不存在負值(如年齡、國債)而用它來表示數量。
2 盡量使用像int那樣的有符號型別,這樣在涉及公升級混合型別的複雜細節時,不必擔心邊界情況(如-1被翻譯為非常大的正數)
3 只有在使用位段和二進位制掩碼時,才可以用無符號數。應該在表示式中使用強制型別轉換,使運算元均為有符號數或者無符號數,這樣就不必由編譯器來選擇結果的型別。
C整型公升級和尋常算術轉換以及資料型別轉換
一 在算術表示式中存在整型公升級和尋常算術轉化問題 unsigned char,unsigned short unsigned int float double long double float double long double為浮點型資料。當沒有浮點型資料參與計算時,統一轉為 unsigne...
C 中字元型變數與整型的算術運算
最近在學習c 經常碰到字元與整數的加減,如 char b a 1,碰到這種比較容易蒙,b的結果是什麼呢?為啥字元可以與整數相加減呢?當幾個數一起做算術運算時,如 加 減 乘 除 求模等,以其中精度高的型別為準。也就是說其中精度低的型別會先轉化成精度高的型別。這樣開頭那個表示式中 a 1,a 為字元型...
C 算術運算子與表示式 強制型別輸出整型
基本的算術運算子 在上一節大概介紹了算術運算子有哪些,接下來將會詳細講解 加法運算子 2 5 正值運算子 6 減法運算子 9 5 負值運算子 3 乘法運算子 4 6 除法運算子 6 2 兩個整數相除結果為整數,會捨去小數部分,如果除數或者被除數有負數,則結果不定,要看具體額編譯系統,意義不大,一般不...