C语言----类型强转

        在C语言代码中我们经常会遇到对变量进行类型强转,如果没有深入理解类型强转,很容易引入代码bug,比如把int类型强转成char就有可能会截断数据,后面代码流程会造成意想不到的错误。这里将会总结一下C语言里的类型强转,建议在安全的前提下进行类型转换。

一:符号扩展和零扩展

        在C语言中每种类型都有相应的字节数,比如char是1个字节,short是2个字节,那从1个字节转成2个字节,多出来的一个字节应该填什么。大部分同学可能一开始说用0填充,其实这是需要分情况的,详细如下:

1,符号扩展:对于要扩展量为有符号数,扩展存储位数的方法。在新的高位字节使用当前最高有效位即符号位的值进行填充

char a=0xff;//有符号值为-1,二进制为11111111,其中最高位为符号位
short b=a;//b的有符号值为-1,二进制为1111111111111111
-----
char a=1;//有符号值为-,二进制为00000001,其中最高位为符号位
short b=a;//b的有符号值为1,二进制为0000000000000001

2,零扩展:对于要扩展量为无符号数,扩展存储位数的方法。在新的高位字节用0填充

unsigned char a=0xff;//二进制为11111111,所有值都是有效值
unsigned short b=a;//b经过零扩展后,内存中存储的值为0000000011111111

总结:若要扩展的量为有符号量,不管扩展成有符号还是无符号,都遵循符号扩展;若要扩展的为无符号量,不管扩展成有符号还是无符号,都遵循零扩展。

例:

char a=0xff;//a=-1,其为有符号量,二进制为11111111
unsigned short b=a;//此处a要进行符号扩展,b的二进制为1111111111111111
---------
unsigned char a=0xff;//a=255,为无符号量,二进制为11111111
short b=a;//此处a要进行零扩展,b的二进制为0000000011111111

 二:从有符号类型到其他类型转换合集


方法

char short

符号位扩展

char  long  符号位扩展
char  unsigned char 最高位失去符号位意义,变为数据位
char unsigned short 符号位扩展到short,然后从short转换为unsigned short
char  unsigned long

符号位扩展到long,然后从long转换为unsigned long

char float 符号位扩展到long,然后转到double

char

double

符号位扩展到long; 然后从long 转到double

char

long double

符号位扩展到long; 然后从long 转到long double

short

char

保留低位字节

short

long

符号位扩展

short

unsigned char

保留低位字节

short

unsigned short

最高位失去符号位意义,变为数据位

short

unsigned long

符号位扩展到long; 然后从long转到unsigned double

short

float

符号位扩展到long; 然后从long 转到float

short

double

符号位扩展到long; 然后从long 转到double

short

long double

符号位扩展到long; 然后从long 转到double

long

char

保留低位字节

long

short

保留低位字节

long

unsigned char

保留低位字节

long

unsigned short

保留低位字节

long

unsigned long

最高位失去符号位意义,变为数据位

long

Float

使用单精度浮点数表示。可能丢失精度。

long

double

使用双精度浮点数表示。可能丢失精度。

long

long double

使用双精度浮点数表示。可能丢失精度。

三:从无符号类型到其他类型转换合集

方法

unsigned char

char

最高位作为符号位

unsigned char

short

0扩展

unsigned char

long

0扩展

unsigned char

unsigned short

0扩展

unsigned char

unsigned long

0扩展

unsigned char

float

转换到long; 再从 long 转换到float

unsigned char

double

转换到long; 再从 long 转换到double

unsigned char

long double

转换到long; 再从 long 转换到double

unsigned short

char

保留低位字节

unsigned short

char

保留低位字节

unsigned short

long

0扩展

unsigned short

unsigned char

保留低位字节

unsigned short

unsigned long

0扩展

unsigned short

float

转换到long; 再从 long 转换到float

unsigned short

double

转换到long; 再从 long 转换到double

unsigned short

long double

转换到long; 再从 long 转换到double

unsigned long

char

保留低位字节

unsigned long

short

保留低位字节

unsigned long

long

最高位作为符号位

unsigned long

unsigned char

保留低位字节

unsigned long

unsigned short

保留低位字节

unsigned long

float

转换到long; 再从 long 转换到float

unsigned long

double

直接转换成double

unsigned long

long double

转换到long; 再从 long 转换到double

四:总结

  • char/short/uchar/ushort任意的混合运算,结果类型为int

  • char/short与uchar/ushort进行大小比较运算时,有符号数符号扩展为int类型,无符号数按照0扩展为int类型。最终按照int比较

  • char/short/int/uchar/ushort与uint进行大小比较运算时,转化为uint类型的比较

  • char/short/int/uchar/ushort与ulong进行大小比较运算时,转化为ulong类型比较

  • 无符号数之间的大小比较时,仍按照无符号比较

  • 有符号数之间的大小比较时,按照有符号比较

猜你喜欢

转载自blog.csdn.net/qq_27071221/article/details/130997225
今日推荐