目录
1.1.2从短整形 short 到更长的整型 long long
一,基本数据类型分类
我们知道的是,数据在内存中是有整型,浮点型,字符型等数据类型的,如下图所示:
但是当我们仔细分析来看,应该是只有整型以及浮点型。分析如下:
1.1整型
1.1.1char型与整型的关系
因为字符型char数据在内存中是一个字节存放的,而整型int型是四个字节存放的。而字符型数据表示的128个字符表示的ASCII码值,其内容在整型中是可以存放的。
除此之外,char在vs编译器中默认为有符号的char型,即unsigned char其大小范围为:-128~127。这个区间在整型的区间范围之内,所以可以将其称为整型的一个小部分,但是也不能完全称为整型,因为整型不能表示字符。
1.1.2从短整形 short 到更长的整型 long long
short型数据,即短整形数据,是两个字节存储的数据类型,即整型的一半。
long型数据,即长整形数据,是四个数据字节存储的数据类型,也可以称为long int型。
longlong型数据,是八个字节存储的数据类型,也可以称为两倍的整型。也即是一个64位存储单元。
以上这些数据类型,基本都是整型的衍生,与整型的使用相差不大,所以我们认为,从char到longlong型,基本都可以认为是整型。
1.2浮点型
在我们日常生活中,当然不仅仅有整数,还有小数,那么这些小数在内存中是如何处理的,浮点数为我们提供一个方便的存储小数的数据类型。
1.2.1浮点数分类
float 单精度浮点数,四个字节空间,即32位存储空间。其特点是运算快,占用空间少。
double 双进度浮点型,八字节空间,64位存储空间。其特点是运算进度高。
二,整型在内存中的存储
变量在内存中存储是需要开辟空间的,那么开辟多大的空间是高效的呢,这就需要根据不同的变量类型来决定了,下面我们来学习整型变量是如何开辟空间来供自己使用的。
首先我们的需要先学习整型的几个重要的概念。
2.1原码,反码,补码
那么首先我们需要知道一个很简单的规则,那就是二进制符号位,0 表示正数,1 表示负数。
二进制数是有三种表示形式的,分别为原码,反码,补码。计算机在内存中是以补码的形式存放数据的,所以计算机在存储时,会将十进制数据变成二进制数据的补码形式存入内存,那么为什么计算机这样做呢,这是因为整型数据有正负之分,换算成补码之后,计算机便可以统一处理。
2.1.1正数
对于正数,由于符号位为0 ,所以它的原反补码都是一样的。、
2.1.2负数
由于负数的符号位1,所以需要将其统一,然后计算机就可以统一处理了。
原码:将十进制整型数据以二进制形式表示,即为原码,但需要注意符号位的区别。
反码:将原码符号位不变,其他位按位取反得到的便是反码。
补码:反码取反加1,得到补码。
那么从计算器取出的时候,我们直接对补码取反加1 ,之后就得到了原码,将其翻译成十进制数即可。
那么我们来看一个例子:
那么我们知道char类型在内存中是一个字节存放的,但是打印的时候我们发现,是需要按照有符号整型打印的,那这样的话,我们应该怎么求其值呢?
首先我们知道,a,b,a+b在内存中存放的形式如下图:
那么首先,直接打印 a+b 时,由于a+b 的补码满足%d的32位整型数据打印,所以直接打印,该二进制换算成十进制之后,值为300。
好的,那么第二个打印,我们是需要将a+b的和放入字符型数据c中,但是字符型数据只有8个比特位,所以我们需要取出a+b的补码的后8位,然后将其存入c 中。
最后我们发现,以%d打印的时候,需要整型提升。所以最后结果为:
所以最后打印的结果为:
2.2大小端(字节序)存储
大端存储:数据的低位存储在内存地址的低位,数据的高位存储在内存地址的高位。
小端存储:数据的低位存储在内存地址的高位,数据的高位存储在内存地址的低位。
那为什么有大小端存储之分呢(已知内存地址是有高低之分的)?
因为数据在内存中是按字节存放的,那么必然有多于一个字节的数据,那么假如一个四字节整型数据在内存中如何存放的呢?
此时就有了大小端字节序存储之分了。
那么怎么区分大小端存储呢?
这个是根据编译器决定的,一般的编译器是按小端存储的,但是大端存储也没有任何的坏处,因为数据在内存中存储,它的值始终是不变的。
三,浮点数在内存中的存储
要知道浮点数在内存中的存储规则,我们首先需要知道国际标准IEEE754协议,它规定浮点型数据有如下格式:
任意浮点数:(-1)^S * M * 2^E
S:S为0, 该浮点数为负数,S为1,该浮点数为正数。
M:M为有效数字,其值大于1小于等于2。
E:E为指数(阶码)
3.1 IEE754的规定
3.1.1对不同大小浮点数的规定
首先,对于32位浮点数。
最高位1 位为S,接着的8位为阶码E,最后 23 位为有效数字E。
而对于64位浮点数。
最高位1 位为S,接着的11位为阶码E,最后 52 位为有效数字E。
3.1.2对有效数字M的规定
因为M必然是一个1和2之间的数,所以当存储时,规定将其正数部分去掉,只保留小数部分,这样小数部分的位数便多了一位。比如1.XXXXXX存储时,只存储XXXXXX,而当从内存中取出时,再将整数部分加上,还原为1.XXXXXX。
3.1.3对指数部分(阶码)的规定
首先,E为一个无符号整数。
E有8位和11位,那么E的最大范围是0~255,0~2047,但是我们知道科学计数法E是可以为负数的,所以,规定,当E存放时,32位浮点数E+127,之后再存入,而64位浮点数E+1023,然后再换算成二进制数存入,这个中间数是必不可少的。
存入内存之后,我们需要将其从内存中取出。
3.2取出浮点数的规定
3.2.1E不是全0,不是全1
此时E为正常数,所以取出时,以32位浮点数为例,将E减去中间数127,然后,将有效数字M加上整数部分1,得到原来的1.XXXXXX。这样一个一般正常的浮点数就完成了存取操作。比如我们存放一个数0.5,将其写为二进制数为0.1,正数所以S为0,然后0.1化为 1.0*2^(-1),所以阶码E为-1+127=126,M则去掉正数部分1,留下小数部分0,所以二进制表示为:
然后,当我们取出时,E-127,M加上整数部分1,再转变为十进制数,得到原来的数0.5。
3.2.2 E为全0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值。
此时,取出时M的值不再加上整数部分,而是直接变为0.XXXXXX,这样做是为了避免出现出现无穷接近于0 的数。
我们简单的分析下,为什么会出现无限小的数。如果E为全0 ,此时原先的E应该是 -127,那么2^(-127),即为1/(2^127),这个数将是一个无限小的数。
3.2.3 E为全1
此时如果有效数字为全0,则将产生一个无穷大的数。
3.2.4浮点数不能错过的例子
如图所示:
那首先,我们分析当存储的是整型数据的时候,我们应该怎么做,如图所示:
这里我们用到的当E为全0时,E是用1-127,M为0.XXXXXXX。但是,用%f打印时,只能打印默认六位小数,所以打印结果为0.000000。
其次,当存储的是浮点型时,而用整型打印时,如图所示:
此时,当满足了整型的存放空间即32位时,会直接求出该二进制数字的值,为1091567616。
四
,其他数据类型
当然,除了基本数据类型之外,还有结构体等一些数据类型,后续再介绍。
最后不得不提的是类型的意义到底是什么???
我觉得,分为两个部分,首先是存放时开辟的内存空间,其次是取出时的视角,即你打算以什么方式取出。
好了,关于数据类型的介绍后续更精彩哦,如有错误,还请指正哦!