K&R C中關於算術轉換的規定:
- 任意類型爲char或是short的操作數被轉換爲int;
- 任意類型爲float的操作數被轉換爲double;
- 如果其中一個操作數爲double,那麼另一個操作數也被轉換爲double,計算結果也是double;
- 一個操作數是long,那麼另一個操作數也被轉換爲long,結果也是long;
- 如果其中一個操作數是unsigned,那麼另一操作數也被轉換爲unsigned,結果也是unsigned;
- 如果不符合上述所有情況的任意一種,那麼兩個操作數都作爲int型,計算結果也是int型。
ANSI C關於算術轉換的規定:
整型提升:
- char,short int或者int型位段,包括他們的有符號無符號變型,以及枚舉類型,可以使用在需要int或unsigned int 的表達式中,如果int可以完整表示源類型的所有值,那麼就轉換爲int型,否則轉換爲unsigned int ,稱爲整型升級。
尋常算術轉換:
- 其中一個操作數是long double,那麼另一個操作數也被轉換爲long double ;
- 如果其中一個操作數爲double,那麼另一個操作數也被轉換爲double;
- 如果其中一個操作數爲float,那麼另一個操作數也被轉換爲float;
- 不是上述任一情況則按下述規則進行整型升級:
- 如果一個操作數是unsigned long int,那麼另一個操作數也轉換爲unsigned long int;
- 如果一個操作數是long int,而另一個操作數是unsigned int ,如果long int(32bit)能夠完整表示unsigned int(16bit) 值,那麼unsigned int 類型操作數被轉換爲long int,如果long int(32bit)不能完整表示unsigned int(32bit)的所有值,那麼兩個操作數否被轉換爲unsigned long int;
- 如果一個操作數是unsigned long int,那麼另一個操作數也轉換爲unsigned long int;
- 如果一個操作數是unsigned int,那麼另一個操作數也轉換爲unsigned int;
- 都不屬於上述,則轉換爲int;
浮點操作數與浮點表達式的值可以比類型本身所要求的更大精度和更廣範圍來表示,而它的類型並不改變。
ANSI C標準所表達的意思:當執行算術運算時,操作數的類型如果不同,就會發生轉換。數據類型一般朝着浮點型精度更高,長度更長的方向轉換,整型數如果轉換爲signed不會丟失信息,就會轉換爲signed,否則轉換爲unsigned。
K&R C採用無符號保留的原則:當一個無符號類型與int或更小的整型混合使用時,結果類型是無符號類型;
ANSI C標準採用值保留原則:將幾個整型操作數像下面這樣混合使用時,結果可能是有符號數也可能是無符號數,取決於操作數的類型相對大小。
main()
{
if(-1 < (unsigned char)1)
{
printf("-1 is less than (unsigned char)1:ANSI semantics");
}
else
{
printf("-1 is NOT less than (unsigned char)1:K&R C semantics");
}
}
-1的位模式都一樣,對於編譯器(ANSI C)而言解釋爲負數,而K&R C解釋爲無符號數
ref:《C專家編程》著[Peter Van Der Linden],徐波譯。