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)