编程旅行之数据的存储

Hello!大家好啊!我是你们的jw3啊,本期我将会带领大家去了解数据是如何在计算机里面存储调用的,也会讲一些基础的题目来方便大家更好的学习,希望本期文章对大家有所帮助



提出问题

1.你想知道C语言的整型与浮点型在计算机中如何存储的吗?
2.你想知道我们的输入数字的算法是怎么进行的吗?
别急,本章会为大家一一解惑


前言

在学习本章内容之前我们要会一些基础知识:
1.计算机是通过二进制形式来储存的,整数在内存中存储和运算都要先转换成补码;
2.之前我们提到的整型与浮点型所占字节大小,比如char占一个字节,int占4个字节,float占4个字节…
3.一个字节等于八个比特位;
4.计算机内存储的数据都是补码(计算也是通过补码来进行计算);
5.打印在屏幕的数据是原码,计算机会自动进行转换显示出来;
6.正数与负数原、反、补码的形式是怎么样的。

上面的知识大家有地方不懂也没有关系,正文内容我会将这些知识深入拓展,方便大家理解,话不多说,进入正文。


一、C语言的数据类型有哪些?

C语言有4种数据类型,如下图:
在这里插入图片描述
这里我们着重来讲一下基本数据类型:

在这里插入图片描述

二、整型类型的存储

整型的所有类型都包括有符号数(signed)和无符号数(unsigned)
注:char也算是整型数据,别看它是一个字符类型的,但是它在ASCLL表里面对应的是整数,所以说char算是整型数据
这里我们介绍char类型的,因为整型数据的存储都是相通的,而且char类型比较简单,方便我们学习

char存储的范围大小

我们知道char占一个字节的大小,也就是8个比特位,只有0与1这两个值。所以char类型的全部值就是下图所示:
在这里插入图片描述

接下来我们分析分析

1、有符号char(signed char)

从0000 0000到0111 1111想必大家都知道。在有符号数中,最高位表示符号,0表示正,1表示负,正数的原、反、补码相同,所以0000 0000到0111 1111就是数字0到127(进制之间的转换之前有讲过 进制间的转换 )(下面我们会讲小数部分的进制转换问题)。
在这里插入图片描述

接下来我们继续,既然正数分析完了我们再来分析负数,我们这次倒着看从1111 1111到1000 0000
在这里插入图片描述
从上图可以看出1111 1111所表示的数字是-1,大家可千万要注意不要把这个符号位1弄错了。既然1111 1111表达的是-1,那么1111 1110呢?
在这里插入图片描述
可以看出1111 1110转换成补码为1000 0010也就是-2,刚刚的1111 1111是-1,现在的1111 1110是-2,那么我们就能判断出1111 1111到1000 0001就是-1到-127

在这里插入图片描述
而此时还剩下一个数—1000 0000,这个数该怎么理解呢?
有人就会问了,1000 0000难道是-0?它怎么取反,怎么减一呢?
其实这个数我们可以直接把它当成-128,我们可以把它看成1000 0000=1000 0001-1,转换成补码就是-127-1=-128,这个数可以直接这样来看
所以我们把char的范围就整理了一遍

在这里插入图片描述

可以看出,有符号char(signed char)范围大小是从-128—127
为了方便大家进一步理解,我用一张图来表示
在这里插入图片描述

大家通过这张图应该更容易理解signed char 的范围与一些注意点

2、无符号char(unsigned char)

这个就容易理解了,无符号char表示第一位不管是0是1都是有效数字,直接计算即可
所以0000 0000到0111 1111是0到127,而1000 0000就是1*2^7=128,
直到1111 1111就是2的0次方到2的7次方之和也就是255
在这里插入图片描述
可以很容易看出无符号char范围是0到255
还是用一张图表示

在这里插入图片描述
看到这里相信大家对char类型的存储有了一定的认识
接下来再讲点其他内容

3、补充知识点

A、数据在计算机内部的运算

先来看一段代码

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

很容易看出来答案是0
在这里插入图片描述
但是在计算机内部的运算大家知道吗?
可以能大家会认为是两个数原码相加,我们来试试看
在这里插入图片描述
由上图可以看出,a和b在计算机里面是用补码进行相加的
补充:运算的时候是在cpu里面运算的,而cpu只有加法运算,当出现减、乘、除法运算都会转换成加法来运算

B、大小端存储

在这里插入图片描述
可以看到a的值是ff bb 00 00,但是在内存里面存放的是00 00 bb ff,
好像反了啊,是不是电脑出故障了?
其实这就涉及到大小端储存了:
当数据的低位存放在内存低地址处,数据高位存放在内存高地址处时,称为小端储存,也叫小端字节序
当数据的低位存放在内存高地址处,数据高位存放在内存低地址处时,称为大端储存,也叫大端字节序

接下来用一段代码来判断大小端:

#include<stdio.h>
int main()
{
	int a = 1;
	char* p = (char*) & a;//我们只用判断前面一个字节是数字0还是1就可以判断出大小端了
	if (*p == 1)//如果第一个字节放的是1,那么就是10
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

这样写又有点太low了,我们改进一下

#include<stdio.h>
int cherk()
{
	int a = 1;
	char* p = (char*)&a;
	/*if (*p == 1)
		return 1;
	else
		return 0;*/
	//return *p;
}
int main()
{
	int ret = cherk();
	if (ret == 1)
		printf("小端\n");
	else
		printf("大端\n");
	return 0;
}

上面两种注释方法都可以,只不过下面只用一个return更方便

小结

我们学习到signed char的范围是-128~127,unsigned char的范围是0~255;计算机有大端与小端两种存储方法。

代码如下(示例):

data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

该处使用的url网络请求的数据。


三、整型提升

上面我们对char类型储存有了一定的了解,其他的整型,int short,long等与char类型原理一样,只不过范围更广
整型提升:用一句话概括就是:短整型以及字符类型的变量之间或者相互进行算术运算操作时,就会发生整型提升。一般来说整型提升前面会补符号位

我们通过几道例题来研究研究整型提升:

例题1

char a=-1;
signed char b=-1;
unsigned char c=-1;
printf("%d\n%d\n%d\n",a,b,c);

我们来分析分析:
在这里插入图片描述
signed char是有符号char,而char默认就是有符号的形式,所以signed char和char过程差不多一模一样

在这里插入图片描述
所以可以看到打印值是-1,-1和255

例题2

char a=-128;
char b=128;
printf("%u\n%u\n",a,b);

继续分析:
在这里插入图片描述

可以看出如果对char类型范围运用不清楚的话很容易踩坑

例题3

unsigned char a=0;
for(a=0;a<=255;a++);
printf("hehe\n")

这一题打印出来的是什么呢?
我就不卖关子了,会死循环打印hehe
在这里插入图片描述

通过这3道例题相信大家对整型提升有一定的了解,整型提升就是要绕一个弯子,大家以后多注意就行

四、浮点型类型储存

1.存入

我们主要讲float类型,double类型与float类型原理相同,在有区别的地方我会提出来的

在这里插入图片描述
我们看到打印结果第一行和最后一行是我们想要的答案,但是中间两行不是我们想要的,这是为什么呢?
那是因为我们规定,浮点型类型储存计算公式位:(-1) ^S * M * 2^ E
(-1)^S表示符号位,s=0表示正数,s=1表示负数
M是有效数字,范围是1<=M<2
E表示次数,同时也是一个无符号数

举个例子:float a = 5.5:
在这里插入图片描述

这就是一个十进制浮点数储存如何储存在计算机里面的过程

2、取出

浮点数存入我们了解了,那如何取出呢?
取出分三种

1.取出的E不为全0或者全1

上图例子:40b00000
取出:S取0
(float)E取出时减127,129-127=2,所以E=2。(double取出时,E要减1023
M取出时要在整数部分补上1,后面接小数部分
(-1)^ 01.0112 ^ 2---->1*101.1—>5.5

2、取出的E为全0

E由之前加127得到,所以原来的E+127=0,我们直接返回写成:
(-1)^s*0.0112 ^1-127—>(-1) ^ S0.011*2 ^ -126
在E为全0的时候取出数据时,M前面不用补上1,表示一个正负无限接近于0的数

3、取出的E为全1

直接写成(-1)^S1.0112 ^ 128,表示一个正负无穷大的数字

3、例题

在这里插入图片描述

我们再来看看:
在这里插入图片描述

在这里插入图片描述
可以看出答案是一模一样的,由此推断我们的做法是正确的

最后

希望个位看官老爷有所收获,也多多支持小编,不胜感激,我们下期见!

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值