【C语言】数据在内存中的存储

目录

1.各种数据类型

2.整形数据是如何存储的

2.1原码、反码、补码

3.浮点型数据是如何存储的

3.1浮点型数据的存储规定

3.2浮点型数据在内存中的存储

3.3浮点型数据的取出

4.大小端存储

4.1什么是大小端存储:

4.2为什么会有大小端模式之分呢?

4.3检测当前编译器是存储方式


1.各种数据类型

我们在以往的学习中已经学过许多种内置类型:char、short、int、long、longlong、float、double……

然而在C语言中还有许多基本的数据类型:struct、int*、float*……

接下来我们对其中进行简单的分类:

整形类型:

char
unsigned char
signed char


short
unsigned short [int]
signed short [int]


int
unsigned int
signed int


long
unsigned long [int]
signed long [int]

浮点型类型:

float
double

构造类型:

> 数组类型 arr【】
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union

指针类型:

int *pi;
char *pc;
float* pf;
void* pv;

空类型

viod表示空类型(无类型),通常应用在函数的返回类型、函数的参数、指针类型等等,应用也十分广泛。

接下来我们重点了解本篇博客的重点:整形、浮点型数据在内存中的存储方式

2.整形数据是如何存储的

2.1原码、反码、补码

首先我们应该知道,计算机中整数有三种表示方式:原码、反码、补码。

原码

直接将十进制数转化为二进制数的形式。

反码

将原码的符号位不变,其他位按位取反得到

补码

反码+1得到补码

而在内存中,整数数据的存储都是以补码的方式存储的。

正数的原、反、补码都相同,负数的原、反、补码各不相同。

3.浮点型数据是如何存储的

3.1浮点型数据的存储规定

浮点型数据的数据的存储是具有规则的,与整数数据的截然不同,所以,为了了解浮点数的存储规则,我们要来了解IEEE754的规定:

任何一个二进制的浮点数V可以表示成以下形式:

(-1) ^S * M *2^E

(-1)^S表示符号位,S为0表示正数,S为1表示负数。

M表示有效数字,大于等于1,小于等于2

2^E 表示指数位

在内存的存储中,只存储S、M、E3种格式:

对应float(单精度)类型:

对应double(双精度)类型:

接下来举几个例子:

十进制的5.5,对应的二进制:101.1。

改为以上的表示形式:(-1)^0 * 1.011 * 2^3

其中S=0,M=1.011,E=3;

这便是十进制下5.5的表示形式;

其中M的处理为:将小数点移动,移动小数点直到M在1-2的范围中,而E可以理解为小数点的移动位数。S则就是正数是0,负数是1。

这样才能保证(-1)^0 * 1.011 * 2^3的结果等于101.1。

3.2浮点型数据在内存中的存储

了解了浮点数的存储规则,那浮点数是如何存储到内存中的呢?这里,IEEE协会又做出了一些规定。

M

因为M属于[1,2)之间,可以写成1.xxxxxx的形式,其中1是肯定存在的,所以M存储到内存中,总是保留小数点以后的部分xxxxxxxxx,这样可以存储更多的位数。

E

首先E是一个无符号整形(unsigned int)

所以E的取值范围是0-255之间(float)或0-2047(double)。

而在我们实际的使用过程中,E肯定是会出现负数的,比如我们要存储0.5(十进制),

0.5-->0.1(二进制)-->(-1)^1.0*2^(-1) [IEEE]-->这里小数点向右移动了1位,所以要乘上2*-1,才能表示二进制下的0.1,这时E就为-1了,而E是无符号整形,这是不允许的。

所以IEEE 754规定,E在存入内存时要加上一个中间值,即127(float)或1023(double)。所以上面的例子中,E=-1,所以在存到内存中,E=-1+127=126,再转为二进制,则存为0111,1111。

则例子0.5在内存中的存储形

3.3浮点型数据的取出

对于取出浮点数,只需要将S、M、E读出,然后相乘,就可以读出这个浮点型数据。

M的取出:

因为存入时,M的地方只保存了M小数点的后几位,所以在拿出是将M的值加上1.0,即可得到真实的M的值。

而E的取出中存在以下三种情况:

当E不全为0或不全为1

因为存进去时,E的值加上了中间值,所以在取出时,E的值就为内存中存储的数再减去127(1023),这样得到了E的真实值。比如上面的例子中0.5在内存中的存储形式:


当E为全0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值。这样真实的E就表示为-126,即乘以2*(-126),这就表示了一个无限接近于0的数。
这时有效数字M也不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字

当E为全1

这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。

4.大小端存储

4.1什么是大小端存储:

大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

4.2为什么会有大小端模式之分呢?

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元
都对应着一个字节,一个字节为8bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就
导致了大端存储模式和小端存储模式

4.3检测当前编译器是存储方式

那如何检测当前的编译器使用的大端存储还是小端存储呢?这里我们就可以写出一个程序来判断:

如果检测是1则就为大端存储,0则为小端存储。

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

//代码2
int check_sys()
{
union
{
int i;
char c;
}un;
un.i = 1;
return un.c;
}

本篇文章的内容就到此结束了,看到这的留个赞呗~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Brant_zero2022

素材免费分享不求打赏,只求关注

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

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

打赏作者

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

抵扣说明:

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

余额充值