前面我们基本已经介绍了C语言的基础知识,今天这节我们学习一些底层的知识,即数据在内存中的存储方式,这些内容在使用上可能并不频繁,但是,对我们理解其他C语言相关知识有着举足轻重的作用。这节的主要内容包括:数据类型的分类、数制转化的基本知识,大端与小端、整型数据在内存中的存储方式以及浮点型数据在内存中的存储方式。
目录
一、数据类型的分类
所谓的类型,就是数据分配存储单元的安排,包括存储单元的长度(占用多少字节)以及数据的存储形式。不同的类型分配不同的长度和存储形式。
类型的意义:
1、使用类型,开辟的内存空间的大小。
2、内存空间的存储的形式。
数据类型的基本类型分为:整型类型与浮点型类型;
1.1整型数据;
整型类型包括:int、short(int)、long(int)、longlong(int)、char等;需要注意的是:字符型数据的本质是ASCII值,因此,将char也划分在整型家族中;
在实际应用中,有些数据的范围往往只有正值(如:身高、体重、年龄等),为了充分利用变量的值的范围,可以将变量定义为“无符号”类型。在类型符前面加上修饰符unsigned,表示指定的变量为无符号整型数据(如:unsigned int)用于扩展变量的值的范围。
例如:
在C语言中,int类型的数据占据系统4个字节,每个字节8个bit,那一共就是32个比特,如果是有符号的int,在32位中,第一位为符号位,剩下的31位为数值位,这样int的取值范围为{-2^31~(2^31-1)}。那如果是无符号位unsigned int ,其32位都为数值位,取值范围为{0~(2^32-1)};
1.2浮点型数据
浮点型数据是用来表示具有小数点的实数。那么为什么要称为浮点数呢?因为在C语言中,实数是以指数形式存在的。同一数字,只要在小数点位置浮动的同时改变指数的值,就可以保证它的值不发生改变,所以被称为浮点数。
浮点数类型包括:float(单精度浮点型)、double(双精度浮点型)、longlong(长双精度浮点型);
其中,float的精度较小,存储的数值范围较小,double的精度较大,存储的数值范围大。
1.3其他类型
构造类型:自定义类型,我们可以创建新的类型,数组类型,结构体类型,枚举类型,联合类型,指针类型,空类型等等。
二、整型的存储
在介绍整型数据在内存中的存储之前,我们先介绍一下数制的相关知识;
2.1数制的基本知识
同样的数值具有不同的数制,比如:二进制、八进制、十进制、十六进制;当然我们接触最多的还是十进制的数字,那什么是数制呢?我们生活中其实也有好多别的进制,比如(七进制:星期,满七进一;十二进制:月份,满十二进一;)
同一个数值,在不同进制下具有不同的表现形式;
比如:十进制的21;在二进制中(0b)的形式为10101;
进制的含义:
在十进制中,每个数字不同的位数都是10的权重组合;比如:231代表的含义为:1×10^0+3×10^1+2×10^2=231;不同的位数表示不同的权重,但是都是以10为单位进行计算;
在二进制中,同样具有权重的说法,比如:1010代表的含义是
0×2^0+1×2^1+0×2^2+1×2^3=10(十进制);
在十六进制中,每一位的数字是由(0-9加上a-f)组成,比如:00f2表示的含义是:
2×16^0+f×16^1+0×16^2+0×16^3=242(十进制);
在C语言中,常见的进制都有自己的标志符:
二进制:以0b 、 0B 开头;八进制:以 0 打头;十六进制:0x 、 0X 开头;
2.2整数的存储
整型数据在C语言中,都是以二进制的方式进行存储的;
整数的二进制表示也有三种表示:原码、反码、补码;准确来说:整型数据,都是以二进制补码的方式进行存储的,下面介绍三个概念(以十进制数-23在计算机存储举例):
-23为整型数据,若以int型进行存储,其占据8个字节,32个比特位,其中第一位为符号位
1、原码
指数直接转化为二进制的数(注意第一位为符号位);
10000000000000000000000000010111;
2、反码(原码基础,符号位不变,其他位取反)
111111111111111111111111111111101000;
3、补码(反码基础上加一)
111111111111111111111111111111101001;
这就是原码、反码、补码的概念,然而需要注意的是:正整数的原码、反码、补码都是相同的;
举例:10与-20在内存中的存储;
#include <stdio.n>
int main()
{
int a=20;
int b=-10;
//20(十进制)
//00000000000000000000000000010100(正整数,原、反、补相同)
//-10(十进制)
//10000000000000000000000000001010(原码)
//11111111111111111111111111110101(反码)符号位不变,其他位按位取反
//11111111111111111111111111110110(补码)反码基础加一
return 0;
}
2.3大端与小端
我们知道在内存中,数据是以二进制补码的形式进行存储的,比如int型数据,内存会给其划分4字节的内存空间进行存储,共32个比特,我们在查看内存空间的时候,往往看到的是十六进制的数,这是在内存中,存储的数(本质二进制,显示16进制),二进制位数太多不宜观察。(一个十六进制顶四个二进制位)
比如:(二进制)10000000 00000000 00000000 00001010
0x 80 00 00 0a
我们知道内存中是以字节进行划分内存单元的,以字节为单位讨论它的顺序,那么一个int型的数据(4个字节),是怎放到内存划分的四个字节中呢?比如:0x 11 22 33 44(16进制,一个数字)四个字节数据,是先放11 ,还是先放44呢。这就有了大端和小端的说法;
大端字节序存储:把一个数据的高位字节序的内容存放在低地址处,把低位字节序的内容,放在高地址处。
小端字节序存储:把一个数据的高位字节序的内容存放在高地址处,把低位字节序的内容,放在低地址处。

具体数据是以那种方式进行存储的,是由计算机硬件所决定的;
三、浮点型的存储
浮点数家族包括:float、double、long double
3.1浮点数存储规则
任何一个二进制浮点数可以表示下面的形式:
V=(-1)^S*M*2^E
其中(-1)^S表示符号位,当S=0,V为正数,当S=1,V为非负数;M表示有效数字,大于等于1小于2; 2^E表示指数位;
例如1:
V=5.0f;
小数的二进制,101.0;浮点数,科学计数法:1.01*2^2.
V=(-1)^0*1.01*2^2
S=0;M=1.01;E=2;
例如2:
V=9.5f
小数的二级制,1001.1;浮点数,科学计数法:1.0011*2^3
V=(-1)^0*1.0011*2^3
S=0;M=1.0011;E=3;
浮点数的存储规则为:V=(-1)^S*M*2^E
(fioat)型对于32位的浮点数。最高位的1位是符号位s,接着是8位指数E,剩下的23位为有效数字M。
(double)型对于64位的浮点数,最高的1位是符号位s,接着11位是指数E,剩下的52位为有效数字M。

例如:
V=9.5f;
小数的二级制,1001.1;浮点数,科学计数法:1.0011*2^3
V=(-1)^0*1.0011*2^3
S=0;M=1.0011;E=3;
在对于有效数字M和指数E,还有一些其他的说法。
首先是M,前面我们说过M的取值范围是1~2,也就是说M可以写成1.XXX……,其中XXXX……表示的是小数部分,在计算机内部保存E的时候,默认这个数的第一位总是1,因此可以舍弃,只保存后面的部分,比如保存1.01时,只保存01,等到读取的时候,再把第一位加上1,这样做的目的是,节省一位有效数字,这样M的位数就可以增加一位。
其次是E,首先计算机中设置的E为8(11)位无符号的整数,这就说明E的取值范围为0~255(0~2047),但是实际中,我们知道E的计算是可能出现负数的,所以我们规定存入内存的E并不是实际计算出的E,而是在其基础上加上一个中间值(127或1023).
例如
V=0.5f;
小数的二级制0.1;浮点数,科学计数法:1.0*2^(-1)
V=(-1)^0*1.0*2^(-1)
S=0;M=1.0;E=-1;但实际存入内存的E=-1+127=126;
综上所述,我们举一个例子来探究其浮点数在内存中真实的存储方式:
V=5.5f;
小数的二级制101.1;浮点数,科学计数法:1.011*2^(2)
V=(-1)^0*1.011*2^(2)
S=0;M=1.011;E=2;
但实际存入内存的E=2+127=129;M为011(不够位补0);

3.2浮点数取出规则
前面我们讲了浮点数的存入内存的规则,特别是在E和M的方面进行了一些说明,接着我们学习,如何将浮点数从内存中取出来。
指数E从内存中取出来还分为三种情况;
1、E不全为0或不全为1
指数E计算值减去127(或1023)得到真实值,再将有效数字M前面加上第一位的1,再按照公式拼出来。
举例:
例如:
V=5.5f;其在内存中存储为:
0 100000001 01100000000000000000000 取出为:1000000001=129,减去中间值127,剩余2;01100000000000000000000去掉补的0,加上首位1,为1.011.按照公式V=(-1)^0*1.011*2^(2)=101.1=5.5(十进制);
2、E为全0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1(没必要,因为太小了),而是还原0.xxxx的小数,这样做是为了表示+-0,以及接近于0的很小的数字。
3、E为全1
这时如果有效数字M全为0,表示+-无穷大(正负号取决于符号位S)
综上,本节主要学习了数据在内存中的存取相关知识,主要的内容包括,数据的类型,整型数据在内存中的存放,浮点数在内存中存放以及取出,本节内容在计算机深层中十分重要,还请读者多多理解,由于能力有限,不足之处还请大佬指出。
创作不易,还请大家多多支持;



被折叠的 条评论
为什么被折叠?



