• 深入理解C语言(1):数据在内存中的存储


    标头
    风景图片


    • 文章主题:数据在内存中的存储🌏
    • 所属专栏:深入理解C语言📔
    • 作者简介:更新有关深入理解C语言知识的博主一枚,记录分享自己对C语言的深入解读。😆
    • 个人主页:[₽]的个人主页🏄🌊


    数据类型介绍

    整型

    char(字符型)

    char
    unsigned char
    signed char

    short(短整型)

    short [int]
    unsigned short [int]
    signed short [int]

    int(整型)

    int
    unsigned int
    signed int

    long(长整型)

    long
    unsigned long [int]
    signed long [int]


    浮点型

    float
    double
    long double


    构造类型(自定义类型)

    数组类型:
    结构体类型:struct
    枚举类型:enum
    联合类型 union


    指针类型

    int*
    char*
    float*
    void*
    ······


    空类型

    void


    类型简析

    整型

    关键字

    整型分为无符号整型和有符号整型两种,分别用关键字signedunsigned来表示,其中除了 char类型在C语言中没有明确表示用char来作为signed char的省略,而是取决于编译器之外,其余整型在不加signed时,均会默认成signed类型。

    表示方法

    整型二进制表示方法:原码、反码、补码;
    转换方法:原码符号位不变取反 -> 反码,反码 + 1 -> 补码,补码 + 1 -> 原码;
    特性:正整数原码、反码、补码相同;负整数原码、反码、补码需遵循转换方法计算得出。

    存储

    整数在内存中是补码形式的二进制序列


    浮点型

    关键字

    浮点型没有无符号的类型,所以只要是浮点型就会自带符号,也就没有有无符号只类的概念一说。因为其在内存中的贮存方式和整型的原、反、补码的方式完全不同,因此专门为了整型数据设计出来的关键字signed以及unsigned对于浮点型来说并不适用。

    表示方法

    存储公式

    根据IEEE(电气与电子工程师协会)的规定,浮点的存储公式为如下,其中内存中只储存S、M、E三个的数据。
    ( − 1 ) S ∗ M ∗ 2 E (-1)^{S}*M*2^{E} (1)SM2E

    S(符号位):

    因为只需通过0或1就可以来表示一个数据的正负,在所有浮点类型中都只占一个bit位。

    M(有效数字):

    在IEEE规定的标准中,M的存储类型为无符号整型(符号已经由符号位确定了),float型在内存中占23bit位,double型在内存中占52bit位,另外因为浮点的存储采用的是科学计数法,科学计数法浮点以前的数因为是有效位,所以在二进制中将浮点符号位丢弃之后单看这个无符号的整型,有效位只会是1,所以IEEE中还规定了去掉科学计数法中前面固定的1.而只取后半部分存入M中,这样的话储存空间等于是由原来的可保存23/52位有效数字变成了现在的可以保存24/53位有效数字了,等于是数据的存储量将比原储存空间又扩大了一位。

    E(指数):

    因为也是无符号整型,float型中占8bit位,double型中占11bit位,但是E完全有可能出现负数的情况,所以IEEE中又规定,对于8位的E加上中间数127,11位的E加上中间数1023,这样就可以实现负指数的效果,可能是因为一段内存中有多个符号位不好处理,实际上这样存储的指数范围和有符号存储的指数范围完全相同。

    存储

    float型和double型存储方式如图:


    float内存存储


    double内存存储


    由此,我们也可以很清楚的看出来为什么float被称为单精度浮点型而double被称为双精度浮点型了,通过duoble通过增加内存长度为float的双倍,指数E和有效位数的长度也得到了提升(因为小数点之后的位数是由有效位以及指数共同决定的),从而成为了精度更高的双精度。


    构造类型

    数组类型:
    元素类型 数组名[元素个数](初始化后元素个数可以不加)

    结构体类型:
    struct 结构体名(struct和结构体名共同构成了该结构体类型的类型名)
    {
    结构体成员类型 + 结构体成员名;
    ······
    }

    枚举类型:专门文章讲解

    联合类型:专门文章讲解


    指针类型

    类型名*就是该类型的类型名,其中*起标记变量名为指针的作用,因此一次只会作用在一个变量上(一颗*只能标记一个变量,该变量之后接着定义的变量都会为该变量解引用之后得到的变量类型,也就是*前面的类型)


    空类型

    无类型,就是在一些在一些可以无需加具体类型定义的情况下使用的类型,如函数无参数就是无类型,函数无返回值也是无类型。其也有对应的指针类型——空指针(void*),作用主要是用来标记暂时没有赋有意义地址的指针,并防止其成为野指针。


    字节序(数据在内存中存储的顺序)

    高低字节位

    一个数的高位与低位和这个数在内存中的高字节位与低字节位位置相同,只是转换成二进制码后将其高位上的前八位的数字,也就是在VS中看到的前两个16进制数字称作一个高字节位,低字节位的定义也是同理。

    大小端

    我们将高字节位的一端称作该二进制码的大端,低字节一端为小端,就有了大小端的定义,因此大小端的定义也只适用于单个数值的数据存储,而不适用于数组等结构类型的存储规律,这些类型较单个数字较为高级一些,都是由高级语言C语言本身的语法和其底层运行逻辑来决定的。

    字节序

    表示单个数值二进制码的存储顺序,内存中地址位是由低至高的,栈区中是有上堆积数据一直往上堆的,越往后(越靠进的是低地址)堆积的是小端就是小端字节序,越往后(越靠近堆积的方向即地址更低的方向)堆积的是大端就是大端字节序。
    字节序

    结语

    以上就是对数据在内存中的存储的深度解析,😄希望对你的C语言学习有所帮助!作为刚学编程的小白,可能在一些设计逻辑方面有些不足,欢迎评论区进行指正!看都看到这了,点个小小的赞或者关注一下吧(当然三连也可以~),你的支持就是博主更新最大的动力!让我们一起成长,共同进步!

  • 相关阅读:
    会用redis吗?那还不快来了解下redis protocol
    monaco-editor 行号、内容装饰器
    9. Java字符串支持正则表达式的方法
    时间序列预测:用电量预测 07 灰色预测算法
    走近棒球运动·亚洲职棒大赛·MLB棒球创造营
    上周热点回顾(5.15-5.21)
    MFC下拉框控件用法
    树莓派+墨水屏 = DIY一个超慢速电影播放器
    Tomcat的动静分离
    PostgreSQL问题记录:column “...“ does not exist
  • 原文地址:https://blog.csdn.net/2303_78612872/article/details/133250214