C語言對類型的轉換
文章目錄
- C語言對類型的轉換
- 整形提升和截斷
- 整形提升
- 整形提升規則
- 整形提升的意義
- 截斷
- 截斷規則
- 算數轉換
我們都知道,C語言中內置了多種整形類型,占用空間從大到小,基本滿足各類使用場景(比如超長數字的運算就不屬此范疇),當程序對大小小于 int 類型的整形進行調用或是儲存時,會發生整形提升和截斷,當不同類型的數據進行計算時,會發生算數轉換
整形提升和截斷
整形提升
在C程序中,整形的算術運算總是以缺省(默認)整形類型進行運算的,即使用 int 類型進行運算。因此,在使用 char 等長度小于 int 的類型進行計算時,會發生整形提升。
整形提升規則
對于 signed 類型,高位補充符號位
對于 unsigned 類型,高位補0
注意 整形提升和截斷均是對補碼的操作
int main()
{char a = -1;//此時a為 10000001//求補碼:11111111char b = 4;//b:00000100//此時對a,b進行調用char c = 0;c = a + b;//發生整形提升// a:11111111 11111111 11111111 11111111// b:00000000 00000000 00000000 00000100// 相加:(1)00000000 00000000 00000000 00000011// 0x 00 00 00 03return 0;
}
如打印、計算等操作都會發生整形提升
整形提升的意義
通過整形提升,可以對CPU中的運算器件進行復用
對于大多數現代的 CPU 架構來說,整數運算器通常會以特定的字長(word length)為單位進行計算。這個字長通常是指 CPU 寄存器的位數,比如32位或64位,當CPU為32位時,會以 int 為單位進行計算
因此,即使是兩個 char 類型的計算,也要轉換成兩個 int 類型之間的計算。即先轉換成 int ,再進行運算
當一個表達式中包含了大于 int 的類型時,寬度超過了 CPU 字長,在運算時需要進行額外的處理,比如拆分成多個操作數進行運算、進行額外的位操作等
截斷
以上面這段代碼為例,得到的 c 仍舊為 4 bytes ,顯然無法存入 char,此時發生截斷
截斷規則
從低位開始,按照存入空間的大小對整形進行截斷,保留低位,丟棄高位
如 char c = 00000011
以下是一個對整形提升和截斷的規則進行解析的例子
//使用不當時,整形提升和截斷也會造成一些問題
#include <stdio.h>
int main()
{char a = -128;// 10000000 00000000 00000000 10000000// 11111111 11111111 11111111 01111111// 11111111 11111111 11111111 10000000// 截斷,存入a// 10000000 -- a// 整形提升,有符號數,高位補1// 11111111 11111111 11111111 10000000// 打印無符號printf("%u\n", a);//4294967168// %u - 打印無符號整數printf("%d\n", a);// 11111111 11111111 11111111 10000000// 認為是負數,求原碼// 10000000 00000000 00000000 01111111// 10000000 00000000 00000000 10000000// -128return 0;
}
算數轉換
當不同類型的整形之間進行運算時,需要將整形轉換為同一類型后進行計算
下面這個表格中位置較低的類型,在遇到位置較高的類型時,會發生算數轉換
類型 |
---|
long double |
double |
float |
unsigned long |
long |
unsigned int |
int |
short |
char |
long long 和 long double 的優先級尚不明確(我還沒有找到明確解析)
long double 在 C99 標準中被引入,用以表示更高精度的浮點數
長度可能會應編譯器和平臺的不同而產生差異,可能和 double 一樣長,可能更長(8/12/16Bytes)