• 为啥-1大于1,-1乘3却不等于-3?直到了解C语言自动转换原则后...


    今天我们由C语言的一个经典题目入手,跟大家聊聊C语言一个非常重要的规则,不要着急,让我们从-1大于1的例子说起。

    unsigned int i=1;

    signed int j=-1;

    很简单,无符号数i,有符号数j,比较i和j的大小,按照常理i是大于j的,但是实验证明j>i,也就是说-1>1,为什么会这样呢?

    其实出现这个情况的原因就是C语言中的自动转换原则,这也是今天我们想给大家说的话题。在C语言中,若遇到无符号数和有符号数之间的操作,这时候会出现数据类型的提升现象,编译器会自动把有符号数转化为无符号数来进行处理,因此i是1没错,但j却不是-1了,而是变成了 4294967295。所以j>i了。


     

    关于数据为何是4294967295,我们今天从数学的角度给大家分析一下,供大家参考。

    首先大家知道无符号数unsigned int的表示范围是:[0 4294967295 ]= [0 2147483647] U [2147483648 4294967295],数学上称为值域。而有符号数int的值域是 [-2147483648—2147483647]。两个区间的元素个数都是4294967296个。

    由此看出,二者的公共域是[0 2147483647],所以有符号数int的[-2147483648 -1] 对应 unsigned int的[2147483648 4294967295],这种一一对应的关系,数学上叫做映射。到这里,数据的对应关系就一目了然了, -1 自然对应的就是 4294967295了。

    由-1大于1的例子,我们对C语言的自动转换原则进行简单总结。

    一般来说,C语言存在4种情况的自动转换,也称为隐式转换。

    1、算术运算式中,低级类型转换为高级类型。(下面的图对低级和高级进行了说明,大家可以参考)


     

    2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。

    3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。

    4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

    当然,以上情况只是进行了一般的总结,有些细节还没有提到,比如字符必须先转换为整数,short必须转换为int,float型数据在运算时必须转换为double来提高运算精度等等,有兴趣的可以自行去了解学习。

    了解自动转换原则后,我们再来看这个微软面试题

    #include<iostream>

    using namespace std;

    int main(void)

    {

      unsigned int i=3;

      cout<<i * -1;

      return 0;

    }

    问结果会输出什么?有人说不是3而应该是12884901885,因为发生了隐式转换。其实本题的答案是4294967293,哪里有问题呢?我们一步一步分析,有符号数-1与无符号数3进行算数运算,-1变为无符号数4294967295,再乘3得12884901885。到这里都没问题,但是有一点很多人忽略了:那就是无符号数unsigned int只能表示32位,而此时的结果发生了溢出!因此结果是4294967293。

    最后,关于本题这里有一点,因为上述代码是C++,大家可以改写成C语言,用printf来输出,再看看运行结果,你会有新的发现哦!

    好啦,就写到这里吧,希望今天的文章对大家的学习有所帮助。


     

    最后,如果你也想成为程序员,想要快速掌握编程,赶紧加入学习企鹅圈子!

    里面有资深专业软件开发工程师,在线解答你的所有疑惑~编程语言入门“so easy”

    编程学习书籍:


     

    编程学习视频:


     
  • 相关阅读:
    U10783 名字被和谐了
    P1151 子数整数
    P2756 飞行员配对方案问题
    P3227 [HNOI2013]切糕
    BZOJ 2127: happiness(最小割解决集合划分)
    linux脚本初体验
    130902 周赛
    Citrix 服务器虚拟化之三十二 XenConvert
    数据字典统一管理,动态下拉框
    [置顶] oracle 数据库表中转换成java代码
  • 原文地址:https://www.cnblogs.com/mu-ge/p/14085748.html
Copyright © 2020-2023  润新知