今天写代码的时候遇到这样一种情况:
首先我能获取到一个配置的电压信息,类型是UINT8
然后我要用当前的实际电压与配置的电压进行比较,
问题是 我获取到的配置电压单位是0.1V,当前实际电压单位是0.01V
所以工需要将我获取到的配置电压 乘以 10,再和实际电压进行比较,
我是这样写的:
if(CurrentV < (ConfigV * 10))/* ConfigV :配置电压 CurrentV :实际电压 */
{
...
}
那么问题就来了,我的ConfigV 的类型是UINT8,随随便便给它做了*10的操作,会不会溢出呢?
不知道。
实际写代码测试了一下,代码如下:
int main(void)
{
unsigned char a = 222;
unsigned short b = 0;
b = a * 10;
printf("b:%d\r\n", b);
if(b > a * 10)
{
printf("b > a * 10; overflow!!\r\n");
}
else
{
printf("b <= a * 10; \r\n");
}
return 0;
}
结果如下:
所以这能证明真的没有问题吗?感觉并不能
好吧,去找书,看看C语言的祖宗书里《The C Programming Language》有没有相关的问题描述
果然没让人失望,还真有,书里面是这样描述的:
总结一下,如果有两个不同类型的数据需要进行运算时,会进行类型提升,
原则是从低往高转, unsigned优先。
又问了大佬,大佬发给我这样一段描述:
因此,从C语言的规则里来看,我上面那样写代码应该是没有问题的,
因为操作符左右两端的数据都被转换成了 unsigned int 类型了,所以没问题。
但是大佬又说,
如果这么写都要先确认编译器完全按照规则写了,
有些编译器实际上会存在不满足全部C特性的问题。
如遭重击。。。
所以这个故事告诉我们,有这种情况还是自己强转一下类型吧,否则出错哭都不知道找谁哭。。。
有符号数和无符号数的比较
例子1:
int a = -1;
unsigned int b = 1;
if(a > b)
{
printf("a > b, a = %d, b = %u\n", a, b);
}
else
{
printf("a <= b, a = %d, b = %u\n", a, b);
}
输出结果为:a > b, a = -1, b = 1
当执行一个运算时(如这里的a>b),如果它的一个运算数是有符号的而另一个数是无符号的,那么C语言会隐式地将有符号参数强制类型转换为无符号数,并假设这两个数都是非负的,来执行这个运算。
例子2:
int i = -12;
unsigned int j = 6;
//i+j 的值是多少?
printf("%u.\r\n",( ui+i ) ); // 无符号数解析:4294967290
printf("%d.\r\n",( ui+i ) ); // 有符号数解析:-6
有符号数和无符号数相加时,有符号数的类型被提升到无符号数,最高位符号位变成数据位。
例子3:
int i = -20;
unsigned int j = 10;
int k = 5;
if((i+j) > k)
{
printf("i+j:%u.unsigned.\r\n", i+j);
}
else
{
printf("i+j:%d.signed.\r\n", i+j);
}
输出结果为:i+j:4294967286.unsigned.
例子4:
int i = -20;
unsigned int j = 10;
int k = -5;//此处和上面不同
if((i+j) > k)
{
printf("i+j:%u.unsigned.\r\n", i+j);
}
else
{
printf("i+j:%d.signed.\r\n", i+j);
}
输出结果为:i+j:-6.signed.