• 记录几道整型提升的题目



    前言

    此篇博客主要用来记录博主再整型提升是遇到的疑惑;


    题目一

    1.
    //输出什么?
    #include 
    int main()
    {
      char a= -1;
      signed char b=-1;
      unsigned char c=-1;
      printf("a=%d,b=%d,c=%d",a,b,c);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    首先我们要先直到在a、b、c中的补码
    1、再放入数据时数据类型只是告诉我们该开辟多大的空间,至此与我们放入数据毫无关系,暂时把数据类型抛入脑后;我们只管专心求补码,然后按照大小端放进去就行了,千万不要管它是什么类型!!!!!
    2、补码:
    示范:
    a是char只有一个字节的空间给我们存数据,至此这个类型我们再也不需要了!!!!
    -1是个负数;
    原码:11(最左边的1表示符号位,最右边的才是数值位)
    反码:10
    补码:11
    然后一个字节的空间(不要考虑他是什么类型!!!)等我们去放,从低比特位开始放,显然放不满,怎么办?甚于位置补符号位直至补满!!!!;
    如果我们求出来补码已经等于或超出了我们对应类型所开辟的空间,则直接按照对应的比特位读取进去,剩余没读进去的直接一刀砍断,不要了,专业术语叫做截断;!!!
    我写过例子:
    char a=300;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    正是咱们的101100!!!
    其它类型也是如此!!!!!!当然这是存数据的过程!!!!
    因此回到该题:
    a:11111111
    b:11111111
    c:11111111
    然后我们用的%d打印的,%d是打印int的,所以肯定要发生整型升!!!!
    这时候我们就特别需要注意数据的类型(也就是你定义时写的类型,不是数据本身的类型!!!!切记,不要搞错了!!!)
    我们看到a是char,vs环境下,char被解释位signed char
    那么对于a中的最高比特位会被解释为符号位!!!
    于是整型提升就是直接补符号位(对于有符号数)
    故a发生整型提升就是:
    11111111111111111111111111111111
    同理b
    11111111111111111111111111111111
    对于c是unsigned char,我们直接补0
    00000000000000000000000011111111;
    但是我们是用的%d打印的,%d打印有符号整型!!
    那么提升过后的最高位就会被解释为符号位;
    因此:
    a、b被解释为负数,我们打印的是原码;
    因此算一下它的原码:(补码的补码就是原码)
    补码:11111111111111111111111111111111
    反码:1000000000000000000000000000
    补码:1000000000000000000000000001
    也就是:-1!!!
    因此:a、b打印出来就是:-1、-1;
    再来看看c
    最高位是0,c、被解释为一个正数;
    补码:00000000000000000000000011111111;
    反码:00000000000000000000000011111111;
    补码:00000000000000000000000011111111;
    也就是:255;c打印的就是255!!
    综上:运行结果是-1、-1、255
    我们来看看运行结果:
    在这里插入图片描述

    与我们运算结果一样,很nice!!!

    题目二

    2.
    #include 
    int main()
    {
      char a = -128;
      printf("%u\n",a);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这不运用我们上面题目的经验:
    -128
    原码:11000 0000(最高位是符号位)
    反码:10111 1111
    补码:11000 0000
    最终放入char中的就是
    1000 0000;
    我们再来看看,题目是用%u,又要发生整型提升:
    数据类型为char,为有符号整数;
    ,发生整型提升,最高位补符号位;
    11111111111111111111111110000000
    然后我们按照%u打印,(%u打印无符号整型),最高位被解释为数值位,原反补相同;
    这个数有点大,我们拿计算机算算;
    在这里插入图片描述
    我们看看程序运行是不是这样:
    在这里插入图片描述
    与我们分析的一模一样,nice~

    题目三

    3.
    #include 
    int main()
    {
      char a = 128;
      printf("%u\n",a);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    a:1000 0000
    整型提升:
    11111111111111111111111110000000
    %u最高位被解释位数值位;
    在这里插入图片描述
    与上面一道题结果是一样的;

    题目四

    4.
    int i= -20;
    unsigned  int  j = 10;
    printf("%d\n", i+j);
    //按照补码的形式进行运算,最后格式化成为有符号整数
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:我们表示的是补码
    i:11111111111111111111111111101100
    j:00000000000000000000000000001010
    i+j由于i、j类型不一样,i会向j发生算术转换;i会变为unsigned int类型,只有类型相匹配才能进行运算;
    故i+j
    11111111111111111111111111110110
    用的是%d打印,最高位被解释为符号位,妥妥的负数
    补码:11111111111111111111111111110110
    反码:10000000000000000000000000001001
    补码:10000000000000000000000000001010
    也就是-10,故最后打印的就是-10;
    看看运行结果:
    在这里插入图片描述

    nice~~

    题目五

    int main()
    {
        unsigned int i;
    
        for (i = 9; i >= 0; i--)
    {
        printf("%u\n", i);
    }
    return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这道题printf没卵用,我们主要看看i就行了;
    首先我们能确定9~0肯定都没问题,我们再来看看i=-1;
    在内存中:
    11111111111111111111111111111111;
    然后i–参与运算时以unsigned int的形式参与;
    最高位被解释为数值位,且i>=0也会发生算术转换,是连个无符号整型参与运算;那么i就会被以无符号的方式读出来,这样读出来就是一个很大的数;
    我们可以确保肯定是个正数,既然是正数,就一定比0大;那么当i=-1时,循环不会停下来;后面的话,我们也可以确保肯定时一直比0大的,而且最后又会回到0的位置(从11111111111111111111111111111111开始依次-1)(读者可以自行验证)因此就会造成死循环!!
    我们来看看你运行结果:
    在这里插入图片描述
    在这里插入图片描述
    nice~

    题目六

    int main()
    {
      char a[1000];
      int i;
      for(i=0; i<1000; i++)
     {
        a[i] = -1-i;
     }
      printf("%d",strlen(a));
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    char能承载的范围是-128~127
    那么i在[0,127]的范围内坑定没问题,那么问题坑定出在,i=128开始
    a[128]=-129;
    -129为整型
    补码:11111111111111111111111101111111
    放在char会发生放不下,专业术语就是发生截断:
    实际char放的是
    01111111,是char类型
    最高位被解释位符号位,也就是正数
    转为10进制就是:127
    同理我们再来看看a[129]=-130
    -130
    11111111111111111111111101111110
    放在char会发生放不下,专业术语就是发生截断:
    实际char放的是
    011111110
    最高位被解释位符号位,也就是正数
    转为10进制就是:126
    注意与上头的二进制位比较
    再来看看你a[130]=-131;
    -131
    11111111111111111111111101111101
    放在char会发生放不下,专业术语就是发生截断:
    实际char放的是
    01111101,是char类型
    最高位被解释位符号位,也就是正数
    转为10进制就是:125
    其实算到这里我们就可以大概猜测大接下来的结果是124、123、122……
    我们观察到每次存入char中的二进制都在减1;
    最后会减到0
    我们strlen遇到‘\0’停下来也就是数字0,并且是不算0的;
    那么通过我们值之前的运算结果是
    (-1~-128)+(127 ~ 1)
    中间包含了-128~127的所有数,除了0,也就是strlen总共会计算255次;
    我们看看运行结果:
    在这里插入图片描述

    题目七

    #include 
    unsigned char i = 0;
    int main()
    {
      for(i = 0;i<=255;i++)
     {
        printf("hello world\n");
     }
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们知道unsigned char的范围是[0~255],那我们来看看最后一次
    i=256时会发生什么;
    原码:0100000000
    反码:0100000000
    补码:0100000000
    放入unsigned char中放不下,会发生截断,实际放进去的是
    00000000,按照unsigned char方式读出来就是0
    i<=255参与运算是会发生算术转换也就是0<=255,也就是i中放的是0,又回到初始条件了,又重0开始了,那么不就是死循环了吗?
    我们来看看运行结果:
    在这里插入图片描述
    在这里插入图片描述
    以上是博主对于整型提升的练习;

  • 相关阅读:
    第02章 变量
    大数据之LibrA数据库常见术语(七)
    开源办公OA平台教程:SmartBI集成版快速部署及使用(O2OA容器化部署)
    浅谈性能测试稳定性 Constant Throughput Timer(常数吞吐量定时器)
    Hadoop(MapReduce)
    np.partition介绍
    简单入门seleniumUI自动化测试
    Iframe通信
    基于STM32F1-C8T6无人机(二)——舵机/电调/空心杯电机/飞控/机架/subs接收机/充电器和电池(给出链接和思考)
    vue3中使用v-html解析后table表格的线不展示
  • 原文地址:https://blog.csdn.net/qq_62106937/article/details/126254787