各位小伙大家好!今天小风将带给大家带着满满的干货来了!
本篇文章将带着大家一起详细了解数据在内存中的存储方式。我们平时日常生活中的四则运算在计算机中是如何运行起来的呢?真的是否如我们想象的那样呢?这其中究竟蕴含着怎样的转换机制?如何看待有符号和无符号的整型数?
这也是小风这篇文章想让大家了解的内容,相信如果大家如果真正理解其中的原理,我们的计算机“内功”将会打下扎实的基础!
目录
文章内容概要
由于本篇文章的内容涉及计算机中的二进制在内存中存储数据的形式,理解起来有定的难度,因此小风会通过由浅入深、层层递进并结合大量的相关实例分析的方式带着大家逐步深入了解。
基于Visual Studio 2019编译器运行环境进行讲解
文章涉及的重要知识点主要有:
- 类型的基本归类
- 原码、反码以及补码之间的关系
- 字符型(char),短整型(short int)整型提升(隐式类型转换)
- 什么是大小端
- 浮点型的存储规则(国际标准 IEEE 754)
一、数据类型分类
相信各位小伙伴们都了解C语言中的基本的内置类型:
char // 字符数据类型short // 短整型int // 整形long // 长整型long long // 更长的整形float // 单精度浮点数double // 双精度浮点数
1.1类型的基本归类
1.1.1 整型
charunsigned charsigned charshortunsigned short [ int ]signed short [ int ]intunsigned intsigned intlongunsigned long [ int ]ned long [ int ]
需特别说明的是,在上述的分类中,我们将char字符类型也划分到整型的家族中,这是因为字符在内存中存储的是字符的ASCII码值,而ASCII码值是整型,所以字符类型也可以看做是整型中的一员。
有符号数&无符号数
有符号数:表示该整数是带有正负属性的区分
无符号数:仅仅表示一个数值,不具备正负性
而在各种整型类型的划分中,我们又将其进行了细分,分为有unsigned(无符号)关键词修饰和原有类型(一般情况下使用原有类型声明的数值都是有符号数,取决于编译器规则)。可能在这里会有很多初学的小伙伴并不清楚为何会要这样来划分,众所周知,我们在进行数值计算时总是避免不了数值的正负性的问题,而数据在内存中的表现形式并不具备符号标注来说明是整数还是负数,而是通过一系列的01二进制序列来表示。
那么计算机是如何来划分整数数据的正负性问题呢?
对于符号数来说,在计算机中规定整型数值通过二进制转换所得到的二进制序列的最高位是这个数对的符号位(最高位为1,表示这是一个负数;最高位为0,则表示这是一个非负数)。在x86环境中,为int类型的数据分配的空间是4个字节(32个比特位),而在x64的环境中,分配的空间是8个字节(64个比特位)。
实例图示
但这里可能会有些小伙伴们提出质疑,说这里的数据结果有问题,应该是2,147,483,658
如果小伙伴们如果这样设想话就说明大家被小风带沟里去了哈哈!因为在计算机中整型数值的存储形式虽然是二进制序列,但它是以补码的形式存在的,由于无符号数是一个非负数,所以此时补码的值就是原码,所以最后的结果是通过补码转换而来,而上图计算的却是原码所以计算错误。(关于这方面的内容,小风将会在后面详细讲解,希望大家理解后再回顾这里)
1.1.2 浮点数
单精度浮点型 双精度浮点型 float double
double类型的浮点数的精度要高于float类型的精度
1.1.3 构造类型
数组类型 结构体类型 枚举类型 联合类型 Array_Name[]([][]) struct enum union
1.1.4 指针类型
int* pi ;char* pc ;float* pf