C 隐式类型转换

在项目中遇到一个奇怪的问题,伪代码如下:

int8_t  a = 0x8F;uint8_t b = 0x8F;if( a == b ){    printf("a = b\n");}else{    printf("a != b, a = %02x, b = %02x\n", a, b);}

按照我的理解,if(a == b)一定为真。但运行结果却让我大跌眼镜:

a != b, a = ffffff8f, b = 8F

首先,变量a不等于b已经让我吃惊了,然后,打印出来a的值竟然是ffffff8f!查了一通资料,我才知道,原来在 C 语言中有隐式类型转换这么一个规则。隐式类型转换是指变量在运算中的一种隐式的类型转换,主要分两种:算术赋值转换。

算术转换


算术转换的规则可以用一张图来表示:

HIGH  ^double <-- float  |long  |unsigned   |int <-- char, short  ^LOW  

此图中有两个箭头。

竖向箭头表示不同的数据类型在进行混合运算的时候,会有一个低字节向高字节转换的过程。术语叫寻常算术转换usual arithmetic conversion)。

横向箭头表示不管该类型有没有进行混合运算都势必会进行转换,再进行运算,术语叫整型提升Integral promotions)。

赋值转换


进行赋值操作时,赋值运算符右边的数据类型必须转换成赋值号左边的类型,若右边的数据类型的长度大于左边,则要进行求余的截取操作。

如定义变量uint8_t a = 257;,因为uint8_t类型的最大值是256,所以要求余的截取操作,最终a = 257 % 256 = 1

又如:

int8_t a = -1;int32_t b = a;printf("a = %x, b = %x\n",a, b);

这就是一个扩展操作,a先被转为int,再被转为unsigned,b的十六进制值等于0xFFFFFFFF

回到最开始的那个问题,在==运算中,ab都被隐式地转换成了int型,一个是-113,一个是143,肯定不一样。

prinf的参数实际上也是一种赋值转换,因为%02x指定了参数的类型是uint32_t,所以a被隐式地转换为了uint32_t的类型,也即0xfffffff8

参考:


整型提升

C的隐式类型转换

关于C语言的隐式类型转换

悠然享受和大自然融合之乐。

C 隐式类型转换

相关文章:

你感兴趣的文章:

标签云: