数据存储补充以及专项练习(整型提升,截断,循环图,指数基数)

在上一篇文章中,我们学习了整型和浮点型在内存中的存储,但是有些内容讲解的比较模糊,所以在这篇文章中,将会进行针对性的讲解与练习
请添加图片描述

1.🚩整型提升

简单来说,占用字节数次小于int的,在使用之前会被提升为int(四个字节),这个过程就是整型提升
至于为什么是整型提升,有没有短整型提升?这主要是计算机体系结构来决定的,计算机进行计算时,产生作用的是CPU中的ALU(运算器),而ALU的操作字节最小就是int的字节数,而数据实际上是存在寄存器中(register),寄存器的字节大小与ALU操作字节数保持一致,也是四个字节,所以会发生整型提升。
整型提升遵循两个原则

1.如果是无符号数,在最高位补0。
2.如果是有符号数,在最高位补符号位。

我们举个例子来看一下:
在这里插入图片描述
我们把0xbb赋给了a,然后让a与0xbb比较,看看结果如何。
在这里插入图片描述
在这里解释一下0xbb是十六进制,对应的十进制是11*16+11=167,对应的二进制是 1011 1011
在上一篇博客中我们说,计算机中存储数据都是用补码表示,我们看到的数据都是原码,在这里, 我们把 1011 1011赋给了char a,相当于a现在在内存中存储的是 1011 1011,那1011 1011就是补码,我们把他转化成原码就是
1100 0101 因为char是有符号数,那就是-69。

我们再看a==0xbb这个表达式,0xbb 是一个整型常量 也就是
0000 0000 0000 0000 0000 0000 1011 1011
再看a,此时a是char,需要进行整型提升,因为是有符号数,所以补上符号位,也就是全部1,此时a为
1111 1111 1111 1111 1111 1111 1011 1011
显而易见a与0xbb不相等,在进行运算以后,a又会发生截断,取低八位
又变成了 1011 1011
这就是一个整型提升的过程,在这里我们又提出了一个概念,就是截断,那什么是截断呢?

🚩截断

当变量接收了一个超过他所有字节数的变量时,就会发生截断,保存所能容纳的位数,其余高位抛弃:
例如 char a = 4294967295;4294967295是2^32-1 ,对应的二进制存储就是
1111 1111 1111 1111 1111 1111 1111 1111 那么存储到a里的会是什么呢?
取低八位 1111 1111 ,并转化成原码 1000 0001,那么a == -1;
这就是发生了截断。
了解了基本概念之后我们练习几道题,来看看我们理解的怎么样:

🚩习题

📍例题一

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存入了a ,-1的原码是 1000 0001 补码就是 1111 1111
char 是有符号的,所以a和b,打印出来都是-1,但是看c,c是无符号数,他直接把补码看成原码,直接翻译过来就是 27-1 =255.
所以打印结果是 -1 -1 255

📍例题二 知识点(整型提升,截断)

#include<stdio.h>

int main()
{
	char a = -128;
	printf("%u\n", a);
	return 0;
}

我们分析一下,用无符号整型打印a,会打印出什么?
首先-128是一个整型,把他赋给a,是要发生整型提升的,也就是原来-128的原码是 1000 0000 补码是 1000 0000 在整型提升以后,char是有符号的,提升的是符号位,-128提升为了 1111 1111 1111 1111 1111 1111 1000 0000但是我们知道,存入char类型中只能存入两个字节的数据,也就是八个比特位,那么除了低八位,要发生截断,最后留在a中的数据就是 1000 0000
可是当你在用无符号打印的时候,由于运算器只能从四个字节开始操作,你又要进行整型提升,char是有符号数,所以又要补上符号位,也就是
1111 1111 1111 1111 1111 1111 1000 0000,这是一个很大的数,可以放在计算器中我们看一下他是多少

在这里插入图片描述
那我们在打印一下,看看程序的结果到底是多少:
在这里插入图片描述
可以看到,与我们计算的结果一致,考虑到这块有一点绕,我们再进行一个练习

📍例题三

#include<stdio.h>

int main()
{
	char a = 128;
	printf("%u\n", a);
	return 0;
}

这时,打印出的数据又会是多少呢?这个大家可以自己练习一下。

📍例题四

int main()
{
	int i = -20;
	unsigned int j = 10;
	printf("%u\n", i+j);
	return 0;
}

我们来分析一下这个问题, -20的补码是:
1111 1111 1111 1111 1111 1111 1110 1100
10的补码是:
0000 0000 0000 0000 0000 0000 0000 1010
计算机中加法是用补码和补码相加:
1111 1111 1111 1111 1111 1111 1111 0110
最后用无符号整数打印出来,因为是无符号数,原码反码补码相同,所以打印的就是 补码的十进制值:
在这里插入图片描述
在这里插入图片描述

♨️♨️♨️例题五

#include<stdio.h>

int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i);
	}
	return 0;
}

分析一下,这个循环是正确的吗,它会什么时候终止呢?
经过上面的练习相比你已经有了些许感悟,这是一个死循环,为什么呢?
因为i是一个无符号整数,当i减到-1时,经过编译 -1的补码是 1111 1111 1111 1111 1111 1111 1111 1110 ,而对于i来说,i是一个无符号的整数,原码反码补码都相同,所以他是一个很大的整数,最后演变成一个死循环

♨️♨️♨️例题六 知识点(循环)

#include<stdio.h>

int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; ++i)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}

请问,数组的长度会是多少?
我们都知道strlen遇到’\0’会停止技术,那么这道题的关键就是找到’\0’,但是仔细看这题,一直是-1-i,只会越来越小,也不会到0啊,这时候就用到了一个循环的概念:整型变量中的数据是在其范围中一直循环的例如:
char类型数据的范围是-128~127,那么我给他一个128,它实际上打印出来的数据会是多少呢?
在这里插入图片描述
那129呢?
在这里插入图片描述
这足够说明,数据是一直循环的,我们画图理解一下:
在这里插入图片描述
有点简陋,见谅,主要体现的是一个循环的思想。也就是说我们在不断增加的过程中,数据是循环的,同理,int long 这些数据类型也是循环的,只不过这个圈要更大一些
那么回到题中,-1要减多少次才会遇见0呢,看图我们可以知道,从-1到-128要减127次,从-128到0又要减128次,加起来就是255次,所以长度应当是255
在这里插入图片描述

小结

要补充的东西就这么多,比较重要的知识点就是整型提升,截断,以及循环的概念,希望大家能多加练习,也请看我博客的同学们给予一些意见,指出一些错误,谢谢大家。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值