数据存储(C语言进阶)(上)

前言

        对于C语言的学习,想要更近一步的话,我们不得不要拨开代码的外表,对其内在逻辑进行分析,只有这样,我们对代码的理解才会更加深刻。本篇文章带你了解数据是怎么在内存中存储的,这是C语言进阶的必修课之一。希望对你有帮助。

1、数据类型介绍                            

 char  字符数据类型 1字节 
short 短整型  2字节
int 整型 4字节 
long 长整型 4/8字节(32平台4字节,64位平台8字节)
long long 更长的整型 8字节
float  浮点型 4字节 
double 双精度浮点数 8字节

                              

        类型的意义:

        1、使用这个类型开辟内存空间的大小(大小决定了使用范围)。

        2、如何看待内存空间的视角(例如:float 和 int 都是4字节,但是定义float类型的话计算机会按照浮点数去处理数据,int定义计算机就按照整型去处理,不同处理效果不同,后面讲解)。     

1.1 类型的基本归类

        整型家族:

char

                unsigned char

                signed char

short

                unsigned short

                signed short

int

                unsigned int

                signed int

long 

                unsigned long [int]

                signed long [int]

long long :

                unsigned long long [int]

                signed long long [int]

        提一提为什么char被分为整型家族:因为字符的本质是ASCII码值,所以被分为整型家族

        以上除了char以外,其他类型如果直接定义(如:int  a ;),都看作是 signed 类型。char类型直接定义后,是signed char 还是unsigned char 是不确定的,这取决于编译器的实现。

        signed和unsigned区别:

        signed:有符号的  ;unsigned:无符号的。

        在内存中存储数据时,是通过二进制存储的。对于有符号的类型数据来说,内存会分配一个比特位表示正负:00000000000000000000000000000000。第一位就被当作符号位,表示正数时为0,表示负数时为1。而对于无符号的类型数据来说,就不需要分配符号位,会比有符号数多出一位来表示大小,因此,仅表示整数时,无符号类型能够比有符号类型表示得更多。

        生活中有些数据是没有负数的,如:升高、体重、长度.......想表示这些数据就可以用无符号类型数据来表示,这样可以存储更大得范围。但如果想表示得数据有正有负,则只能用有符号类型。

        浮点型家族:

float
double

        浮点型家族表示的是小数,float的精度低,存储的范围小,double的精度高,存储的数据范围更大。

        构造类型:

数组类型                         如:int arr1[5]       类型为: int [5]
结构体类型                     struct   
枚举类型                        enum                                
联合类型                        union        

        指针类型:

int*
char*
float*
void*

        空类型:

        void 表示空类型(无类型)

        通常应用与函数的返回类型、函数的参数、指针类型。        

2、整型在内存中的存储

        一个变量的创建时要在内存中开辟空间的,空间的大小事根据不同的类型而决定的。

        那么数据在开辟的内存空间中事如何储存的呢?

        接下来我们就要介绍一个概念了:

        2.1 原码、反码、补码

        对于整数的二进制数据来说,有三种表示形式:

        1、正整数原码、反码、补码不用算,都相同

        2、负数的原码、反码、补码是需要计算的

        原码:通过正负形式写出的二进制序列就是原码(正数二进制加符号位0,负数二进制加符号位1)

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

        补码:反码加一就是补码

举例:

        对于数字“7”来说,他的原码、反码和补码如下
        00000000000000000000000000000111 - 原码
        00000000000000000000000000000111 - 反码
        00000000000000000000000000000111 - 补码

        16进制:00 00 00 07

        对于数字“-7”来说,他的原码、反码和补码如下
        10000000000000000000000000000111 - 原码
        11111111111111111111111111111000 - 反码(原码符号位不变,其他位按位取反就是反码)
        11111111111111111111111111111001 - 补码(反码+1就是补码)

        16进制:ff ff ff f9

        无论是正数还是负数,在内存中储存的都是补码的二进制数序列

        为什么存放补码?

        在计算机中,数字一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时加法和减法也可以统一处理(CPU只有加法器,把1-1转化成1+(-1))。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

       数据存储(C语言进阶)(上)_第1张图片 

        这是7 和-7在内存中存放的样子,我们看到它确实存放的是补码,但是发现顺序不对,这是为什么呢?

        接下来解答这个问题

2.2 大小端介绍

什么是大小端:

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

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

为什么会有大端和小端:

        因为计算机对于一个多字节的数据,存在一个存放问题,一个数据如果占用了多个字节,那么其每一个字节都对应一个地址。那么存放它的时候总得找到一个统一的处理办法,于是就出现了大端存储和小端存储的模式。(我们常用的x86,也就是我刚刚那个截图用的,是小端存储模式,所以会出现“反着存”的现象;而对于像C51,它就是大端存储模式。         

3、浮点数在内存中的存储   (这一部分在下一篇中讲解)

总结

        本文通过介绍数据类型、整型在数据中的存储、浮点数在内存中的存储,详细的地讲解了C语言中的数据是如何存储的,这可以让我们对代码的理解更加深入,也是C语言进阶的必修课之一。

你可能感兴趣的:(c语言,数据结构)