• 无符号类型的误导


         近日在写程序时,无意间遇到了错误,经反复推敲和调试,确定了错误就出在无符号类型下,百度许久,总结一下。

          相信很多人都知道关于C语言的标准大致有两种,一个是老的K&R C标准,一个是新的ANSI C标准(当然,这也不能算新了),这两种标准关于一些细节方面有很多的不同,但毕竟标准只允许改正,不允许废除,就像intel 8086的段地址:偏移地址的寻址方式也不得不为了兼容性而一直保留着一样,而C语言标准的改变,有人称之为“安静的改变”。

          这段代码可以告诉你,你现在使用的到底是K&R C还是ANSI C,因为虽然-1的位模式是一样的,但是在这两种不同的编译器下的解释确不尽相同,ANSI C将其解释为负数,而K&R C奇怪的将其解释为正数。

          说奇怪也不算奇怪,因为都是有标准可以参照和拿来解释的:

    K&R C采用无符号保留(unsigned preserving)原则,就是当一个无符号类型与int或更小的整形混合使用时,结果类型是无符号类型。这是个简单的规则,与硬件无关。但是,它却会如上面的例子那样,使一个负数丢失符号位。

    ANSI C采用值保留(value preserving)原则,就是当几个整形操作数像上面例子这样混合使用时,结果类型有可能是有符号数,也可能是无符号数,取决于操作数的类型的相对大小。

          我遇到的问题是这样的,参见下面的例子:

          经过调试发现,原本if判断语句应该成立的地方却不是这样的,然后翻阅sizeof()的介绍时发现其返回值类型为size_t,即unsigned int,而if语句在signed int和unsigned int之间进行大小判断时,d被升级为unsigned int类型,这就导致了-1被强制转换成了一个非常大的数,致使表达式为假。

         其实要修正这个问题也很简单,进行强制类型转换,即:

         经过这一次,需要更正一个观点,不要因为某些数不可能出现负数(如年龄)而想当然的将其定义为无符号数,这样可能会在后面的编程中,莫名其妙的出现上次问题。建议只在使用位段和二进制掩码时,才去使用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或者无符号数,不要由编译器去选择结果的类型。

  • 相关阅读:
    联机交易场景持续拓展,巨杉数据库中标吉林省农信
    巨杉数据库与深度操作系统合作共建基础软件技术生态
    SequoiaDB报告创建线程失败的解决办法
    巨杉数据库中标张家口银行、保定银行,华北地区布局再升级
    扩展国产数据库生态,巨杉技术社区与恩墨学院建立全面合作
    巨杉Tech | SequoiaDB虚机镜像正式上线
    跨越数据库发展鸿沟,谈分布式数据库技术趋势
    喜讯 | 国际智慧城市大会巨杉喜获两项大奖
    巨杉数据库再夺“广州独角兽”称号
    巨杉Tech | 使用 SequoiaDB 分布式数据库搭建JIRA流程管理系统
  • 原文地址:https://www.cnblogs.com/pang123hui/p/2309958.html
Copyright © 2020-2023  润新知