我们知道,C语言中有许多变量类型,其中主要可以分为以下两类:
- 内置类型:char, int, float, double,指针等
- 构造类型:数组,结构体,枚举,联合类型
这是很多教C语言的老师在上课时会直接告诉我们的知识,但是我们是否思考过以下几个问题:
1.这些类型的本质是什么?
2. 我们为什么要定义各种不同类型的数据?
接下来我将针对这些问题做出自己的一些思考。
在现实生活中,我们会碰到许许多多的数据,根据这些数据的特点,我们可以把它们分成整数,小数,分数,百分数等等。为了更快捷高效的处理这些数据,我们会借助计算机对这些数据进行处理(计算机的本质就是对数据进行处理)。在处理之前,我们首先需要将这些待计算的数据放在内存中(我们可以把内存看做是一个有很多楼层的房屋,每个房屋都有一个编号即地址),而在存放的时候,我们需要考虑以下几个问题:
1. 数据应该放在内存中的哪个位置?
2. 这些数据占用多大的内存空间?
3. 不同数据在内存中如何表示?
针对第一个问题,我们主要关注的是计算机的读取效率。操作系统会将整个内存空间划分为各种不同的段,比如.text段、.data段、.bss段等等。
它们的作用是针对各个数据的功能和特点合理地对内存进行划分,从而能够更加有效地利用内存空间。这种做法是非常自然的,我们可以想象,在家里如果我们对我们的衣服裤子袜子等不加整理随意摆放的话,找起来的时候是非常麻烦费时的。因此,对数据在内存中进行存放的时候,也需要对数据进行分门别类,这样可以大大提高计算机的读取效率。
而第二个问题我们主要关注的是计算机内存空间的利用率。在现实问题中,我们对于数据精度的要求是不同的,有的领域可能对数据的精度要求非常高,比如航天领域,可能要精确到小数点后面的几十位数;而有的领域对数据的精度没这么高,比如咱们出门买个菜,以元为单位的话最多也就精确到小数点后两位。因此,这两种要求精度不同的场景下,数据该如何保存呢?如果都按照精度要求最高的原则存储数据,则会造成极大的空间浪费;而如果都按照精度要求最小的原则存储数据,则不可避免会产生数据的失真。所以,为了节省内存空间并同时满足各个场景下的精度的要求,我们给各种数据内置了几种不同的类型,包括整型、浮点型等。它们的作用主要有两个:
1. 表明该数据所占内存的大小。比如char一般占1个字节,int一般占4各字节
2. 表明该数据的类型。告诉操作系统该数据是一个整数还是浮点类型的数(也就是解决第三个问题数据在内存中如何读的问题)
关于第三点,需要补充一下整型和浮点型数据在内存中是如何存储的。以int和float类型举例:
int类型在内存中规定占4个字节,其中第最高位是符号位,后面都为数据位。
float类型由于数据一般带有小数点,比如3.5,写成二进制为 11.1,我们用二进制的科学计数法对它进行表示可以写为 。从这个例子我们可以发现,对于浮点型数据,我们只需要存储一个符号位表示该数的正负,小数点后面的数据(即该例子中的11)以及2的幂(即该例子中的1)这三个数就可以完整的表示出该数据。所以,对于float型,它的存储方式如下图所示
同样,double类型有8各字节,其存储方式如下
因此,理解了上述的分析,我们再来回看一开始提出的问题,我们可以很容易得到结论:
类型的本质就是为了提高计算机的效率以及内存利用率而人为对数据进行的分类。
它的主要作用是规定了该数据的内存大小以及该数据在内存中如何存放。
未完待续... 本栏还将继续深入探究C语言的本质!