• 不同类型数据运算的总结


    前几天在学习交流群里,有个小伙伴问了一个问题,是关于有符号整数和无符号字符数的运算的问题。对于这部分,我个人理解的也有点问题,现在来做个总结回顾。

    有符号整型和无符号数整型

    举例

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int a = -1;
        unsigned int b = 1;
        printf("%d", a > b);
        return 0;
    }
    

      输出结果为:1

    解析

      无符号整型和有符号整型比较时,有符号整型会转化成无符号整型。因此,-1转化为无符号数为0xFFFFFFFF,所以a>b,输出1。

    有符号字符型和无符号字符型

    举例

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        char a = -1;
        unsigned char b = 1;
        printf("%d", a > b);
        return 0;
    }
    

      输出结果:0

    解析

      要解释以上这个现象,首先要明白整型提升:

      整型提升是C程序设计语言中的一项规定:在表达式计算时,各种整形首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。

      整型提升的意义在于:表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。(来源百度百科)

      举个例子

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        char a = '2';
        char b = '2';
        printf("%d
    ", sizeof(a+b));
        
        char c = a+b;
        printf("%c
    ", c);
        printf("%d
    ", sizeof(c));
        
        return 0;
    }
    

      输出结果为:4 d 1。

      第8行,按理来说应该输出1的,但是这里输出的是4.因为,进行a和b都为char型,a+b时,会将a和b提升为int型计算,所以会输出4。

      第11行,c为char型,计算a+b时,其实是先提升为int型,再转换为char型赋值给c,进行了两次类型转换。所以,printf时,c是char型,输出d(ASCII:100)

      同样的,第12行输出的就是1。

      接下来回到本题中,a = -1,提升为int型为-1,b = 1,提升为int型为1,所以结果为0。

    有符号整型和无符号字符型

    举例

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int a = -1;
        unsigned char b = -1;
        printf("%d", a > b);
        return 0;
    }
    

      输出结果为:0。

    解析

      整型提升,b转化为int型为0xFF,所以a<b。输出0。

    有符号字符型和无符号整型

    举例

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	char a = -1;
    	unsigned int b = -1;
    	printf("%d
    ", a == b);
        return 0;
    }
    

    输出结果:1。

    解析

      char类型被扩展为unsigned int后与b相等,同为0xFFFFFFFF

    -1源码:1000 0001

    -1补码:1111 1111

    扩展: 1111 11111111 1111(占用字节小的数据赋值给占用字节大的需要扩充符号位,相反需要截断高位

    转为unsigned int:0xFFFF FFFF

    转为int: 求扩展后的源码,还需要-1,除去符号位,取反。因此结果为:1000 0000 0000 0001 = -1。

    结论

      1.无符号int与有符号int比较大小,都转化为无符号int来比较。

      2.int类型与非无符号int的类型比较时,非无符号int的类型转化为int来比较。

      3.无符号int类型与其他类型如unsigned short,signed short,unsigned char, char 比较时,其他类型一律转化为无符号int类型来比较。

      4.非无符号int类型和非int类型如unsigned short,signed short,unsigned char, char 比较时,一律转化为int类型来比较。

      养成习惯,先赞后看!如果觉得写的不错,欢迎关注,点赞,在看,转发,谢谢!
    如遇到排版错乱的问题,可以通过以下链接访问我的CSDN。

    CSDN:CSDN搜索“嵌入式与Linux那些事”

    欢迎欢迎关注我的公众号:嵌入式与Linux那些事,领取秋招笔试面试大礼包(华为小米等大厂面经,嵌入式知识点总结,笔试题目,简历模版等)和2000G学习资料。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    sencha touch学习心得之FormPanel
    从零开始学习Sencha Touch MVC应用之十九
    sencha touch中datepicker的汉化
    从零开始学习Sencha Touch MVC应用之十九
    从零开始学习Sencha Touch MVC应用之十八
    sencha touch中datepicker的汉化
    sencha touch学习心得之FormPanel
    常用内置模块(二)——logging模块
    包的介绍
    常用内置模块(一)——time、os、sys、random、shutil、pickle、json
  • 原文地址:https://www.cnblogs.com/dongxb/p/14138935.html
Copyright © 2020-2023  润新知