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。
回到最开始的那个问题,在==运算中,a和b都被隐式地转换成了int型,一个是-113,一个是143,肯定不一样。
prinf的参数实际上也是一种赋值转换,因为%02x指定了参数的类型是uint32_t,所以a被隐式地转换为了uint32_t的类型,也即0xfffffff8。
参考:
版权声明:本文为博主原创文章,转载请注明出处。

浙公网安备 33010602011771号