深度剖析C语言数据在类型中的存储之整型在内存中的存储

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第1张图片

目录

 1.数据类型介绍(数据知识基础复习铺垫)

1.1类型的意义

​编辑

1.2.类型的基本归类

2.正文:整形在内存中的存储 

2.1.原码、反码、补码

2.1.1 思考:为什么整型数据在内存中存放的是补码?

2.1.2(重要)关于整形家族有符号类型和无符号类型的区别 

2.2 大小端存储字节序。 

2.2.1 数位的低位高位

2.2.2高地址和低地址 

2.2.3大小端的例子理解 

3.结语


 

 1.数据类型介绍(数据知识基础复习铺垫)

内置类型                释义                   大小

char                    字符数据类型       1字节

short                    短整型                  2字节

int                           整型                   4字节

long                     长整型                4/8字节(注:C语言标准只规定了sizeof(long)>= sizeof(int)

long long           更长的整型           8字节

float                  单精度浮点型         4字节

double              双精度浮点型          8字节

1.1类型的意义

不同的类型开辟的内存空间是不一样的,类型的大小决定了使用范围

例如:如果我们要精确些来创建一个表示人的体重的变量。我们应该使用什么类型呢?

我们来看一下使用最小的整型,short int类型可以表示多大的数值范围:

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第2张图片

我们可以看到一个短整型的表示范围是:-32768~32767  已经很大了,如果使用其他的类型就会造成内存空间的浪费。

关于如何查看方法如下:

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第3张图片

1.2.类型的基本归类

在本章节我们注重注意整型家族的数据

①整形家族

int 

        signed int

        unsigned int

short

        signed  short

        unsigned short

long

       signed long

        uunsigned long

long long

char

        signed char

        unsigned char 

关于整型家族的两点问题解释:

一.关于char类型为何归类在整形家族:

          字符本身来说存储的ACSII码值,是整形。所以归类的时候放进了整型家族

二.只有整形才有有符合和无符号的区别,区别的体现放在下文整型如何存储完了过后进行讲解,大家稍安勿躁,继续往下。

        

②浮点数家族

        float

        double 

③指针类型

        int* p  整型指针

        char* p  字符指针

        float * pf  浮点数指针

        结构体指针

        void* p   空类型指针

         

④空类型

        void表示空类型(无类型)

        通常用于函数的返回类型、函数的参数、指针类型 

⑤构造类型

        结构体类型 struct

        枚举类型 enum

        联合类型 union

        数组类型

关于数组类型的说明补充:

数组的元素类型和数组元素个数不一样的时候数组类型不一样

int arr[10] —— 类型是int  [10]

int arr[5] —— 类型是 int  arr[5]

char arr[5] —— 类型是char [5]

2.正文:整形在内存中的存储 

        我们说变量的创建必然伴随着要在内存中开辟空间,而能开辟空间的大小是依照不同的数据类型来决定的。比如创建一个int 类型的变量,我们知道就要给这个变量分配四个字节的空间。

那么数据是如何,又是按照什么样子存储在这四个字节的空间中呢?

答案:对于整形来说,数据存放在内存中存放的是补码,数据的存储顺序由系统决定大端存储还是小端存储。

引出正文,大家接着看就会理解答案,亲手摘下果实。

2.1.原码、反码、补码

        计算机中的整数有三种二进制表示方法:原码 反码 补码

三种表示方法均有符号位(数值的最高位)数值位两部份来组成。

符号位用‘0’表示正,用‘1’表示负。

原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码。

举例:1和-1的原码(在32位操作系统下)

1: 0 0000000 00000000 00000000 00000001 ,最高位为符号位,1为正数,最高位为0,数值位表示1

-1:1 0000000 00000000 00000000 00000001 ,最高位为符号位,-1为负数,最高位为1。数值位表示1

反码:正数的反码和原码相同

           负数的反码:将原码的符号位不变,其他位按位取反得到反码

举例:1和-1的反码

1:0 0000000 00000000 00000000 00000001  和原码相同

-1:1  1111111   11111111 111111111 11111110

补码:正数的补码与原码相同

          负数的补码是其反码+1

举例:1和-1的补码

1:0 0000000 00000000 00000000 00000001  和原码相同

-1:1  1111111   11111111 111111111 11111111

总结:

1.正数的原、反、补码相同

2.对于来说 

原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码。

 负数的反码:将原码的符号位不变,其他位按位取反得到反码

负数的补码是其反码+1

2.1.1 思考:为什么整型数据在内存中存放的是补码?

 我们来看一下如果使用的原码存储,我们来计算一下1+1的结果是怎么样的:

1的原码:0 0000000 00000000 00000000 00000001

-1的原码:1 0000000 00000000 00000000 00000001

1+(-1) = 100000000 00000000 00000000 00000010

结果为-2

但是正确结果应该是0,是不正确的,我们再用补码试一下:

1:0 0000000 00000000 00000000 00000001  

-1:1  1111111   11111111 111111111 11111111

1+(-1) = 00000000 00000000 00000000 00000000 

我们看到结果为0,结果正确

得出结论:

①使用补码存储,可以将符号位和数值领域统一进行处理

②加法和减法也可以统一处理(计算机是没有减法操作的,1-1,执行是看做1+(-1)来进行操作1的)

③补码和原码相互转换,运算过程是相同的,不需要额外的硬件电路。 

2.1.2(重要)关于整形家族有符号类型和无符号类型的区别 

对于整形家族来说,有有符号和无符号的区分。有符号的数据类型一般省略signed

int->signed int

但是:char 到底是signed char 还是 unsigned char C语言并没有给出标准规定,但是在VS上,char是表示有符号的字符类型。

对于:

有符号的整形来说,最高位为符号位,剩余的位为数值位

对于无符号的整形来说,所有的位都是数值位,没有符号位。

二者在表示的数的范围上有很大的区别,由于这种特性,有时会将有无符号的整型作为考点。下面我们看一下直观例子

首先我们看一下无符号的整形,由于八个位都是数值位,所以,无符号整形的数值范围就是:0~255. 

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第4张图片

对于有符号的整形来说,最高位是符号位,内存中存放的是补码,如果符号位表示负数我们应该求出其原码才能看出其表示的数字

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第5张图片

所以,有符号的字符型表示的数的范围就是-128~127.

2.2 大小端存储字节序。 

我们知道了整型是以二进制补码的形式放在我们的存储空间中的,我们来看看:(调试看看内存中的情况)。

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第6张图片

 注:在Vs中,值是用16进制数展示出来的。

16进制的一个位表示四个二进制位,2个16进制位就是8个二进制位,就是一个字节。

 那么,究竟什么叫做大端字节序,什么叫做小端字节序呢?

1.首先,字节序,是一种以字节为单位,讨论存储顺序的数据排序方式。然后才是大端小端

2.小端字节序存储:把一个数据的低位字节的内容放在低地址处。高位字节内容放在高地址处。

大端字节序存储:把一个数据的低位字节的内容放在高地址处。数据的高位字节的内容放在低地址处。

要能理解这种存储方式,就需要理解几个概念,数位的高位低位以及地址的高位低位,接下来我们来看看。

2.2.1 数位的低位高位

数据的高位是数据的左边位置的数,数据的低位是数据右边位置的数,数据的高位和低位又称高字节和低字节。

我们用一个十进制数123来理解

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第7张图片

而二进制数中也是同理

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第8张图片

2.2.2高地址和低地址 

对内存空间进行分配,每一字节的内存空间都有一个编号,编号较低的是低地址,编号较高的是高地址,数据的存储是从低地址开始存储的。如图:

深度剖析C语言数据在类型中的存储之整型在内存中的存储_第9张图片 

2.2.3大小端的例子理解 

有了上面的内容,我们看一个例子方便理解。

一个16Bit的short类型X,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节数据位,0x22为低字节数据位。

那么对于大端模式存储,就将高字节位的0x11放在低地址0x0010中,0x22就放在高地址0x0011中,小端存储方式就刚好相反。

我们常用的x86就是小端存储。

3.结语

整形的存储的理论知识到这里就完成了。我会在后续的几篇文章中,将一些其他内容作为子篇章补充,比如整型提升的问题,还有如何验证自己的机器是大端还是小端,以及更新一篇整合知识的比较有意思的关于整形存储的一些题型分析,非常感谢大家的支持,不对的地方请大家指出,互相学习进步,下一篇文章见。

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