C语言signed和unsigned之间的编程陷阱

C语言中的整数可分为有符号整数(signed)和无符号整数(unsigned)。如果在程序中没有特殊标识,整数类型默认为signed,这里包括直接书写的整数数字。定义unsigned类的整数时,可用unsigned作为前缀,如果是直接书写的数字,则在数字后加‘U’,如2456326U。

signed类的整数和unsigned类的整数之间可以进行转换,包括显式转换和隐式转换。C语言对隐式转换的规定是什么呢?当带符号数和无符号数之间进行操作的时候,要将带符号数字转换成无符号数字,再进行比较大小等各种操作。

下面举一个非常易错的例程。

#include <stdio.h>
#define gap sizeof(int)
int main()
{
    for(int i = 20;i-gap >= 0;i-=gap)
    {
      printf("循环\n");     //gap是unsigned,则i-gap>=0恒成立,造成死循环。
    }
    return 0;
}

另外,由于整数在机器中的表示问题,往往会使程序出现各种trick,很难找到问题出现的根源对于带符号数x,将其转换为无符号数。如果x>=0,那么转换为无符号数没有什么特别的问题。但是若x<0,就会出现很严重的问题,因为系统是直接将x看做无符号数进行处理的。请看下面这个不等式。

-1>0U (√)

我们假设是16位整数。当进行比较的时候,-1先转换为unsigned类型,然后两者按照无符号数字进行比较。而数字-1的机器表示是11111111 11111111,该01串作为无符号数字的话会是16位整数中的最大值,显然大于00000000 00000000!

我们看到,有符号数和无符号数混在一起时很容易出错。正确的做法是,尽量避免使用无符号数,特别是不能仅仅因为变量的值始终大于0就去使用。当需要移位操作等情况下使用无符号数才是推荐的做法。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值