C语言中不同类型的运算和比较问题

今天写代码的时候遇到这样一种情况:
首先我能获取到一个配置的电压信息,类型是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.

 

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您的问题是关于 C 语言的混合运算规则。在 C 语言的混合表达式不同类型的数据可能会进行运算。在这种情况下,C 编译器通常会进行自动类型转换,以使操作数的类型匹配,并且确保计算结果的正确性。一般来说,C 语言的混合运算规则是按照一定的优先级以及类型转换规则进行执行的,具体规则如下: 1. 如果两个操作数的类型不同,C 编译器会自动将其一个操作数转换为另一个操作数的类型,以使它们类型相同。 2. 如果两个操作数的类型都是整型,且其一个操作数的长度比另一个操作数的长度小,则 C 编译器会将较短的操作数进行符号扩展或零扩展,使其长度与另一个操作数相同。 3. 如果一个操作数是浮点数,而另一个操作数是整型,则 C 编译器会自动将整型操作数转换为浮点数类型。 4. 如果一个操作数是 long double 类型,则 C 编译器会自动将另一个操作数的类型转换为 long double 类型。 5. 如果一个操作数是 double 类型,则 C 编译器会自动将另一个操作数的类型转换为 double 类型。 6. 如果一个操作数是 float 类型,则 C 编译器会自动将另一个操作数的类型转换为 float 类型。 7. 如果两个操作数都是字符类型,则 C 编译器会将它们作为 ASCII 码值进行计算。 8. 如果两个操作数都是指针类型,则 C 编译器会根据指针类型进行指针运算,并返回一个新的指针值。 希望这个答案能够解决您的问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值