整型提升的题目


前言

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


题目一

1.
//输出什么?
#include <stdio.h>
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;
}

首先我们要先直到在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 <stdio.h>
int main()
{
  char a = -128;
  printf("%u\n",a);
  return 0;
}

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

题目三

3.
#include <stdio.h>
int main()
{
  char a = 128;
  printf("%u\n",a);
  return 0;
}

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

题目四

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

注意:我们表示的是补码
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;
}

这道题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;
}

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 <stdio.h>
unsigned char i = 0;
int main()
{
  for(i = 0;i<=255;i++)
 {
    printf("hello world\n");
 }
  return 0;
}

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

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南猿北者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值