C语言的进阶之数据的存储

本文详细介绍了C语言中的数据类型,包括整型、浮点型、构造类型和指针类型,并探讨了空类型的应用。同时,文章阐述了整型在内存中以补码形式存储的规则,以及如何通过查看内存判断大小端字节存储。此外,还讲解了浮点型在内存中的存储方式,遵循IEEE 754标准,并通过实例展示了浮点数的转换和存储过程。
摘要由CSDN通过智能技术生成

 (一)C语言的数据类型

  首先,C语言的数据类型有哪些呢(即内置类型)

  整形大家族:(1)char  //字符数据类型
                        (2)short  //短整型
                        (3)int  //整形
                        (4)long  //长整型
                        (5)long long  //更长的整形

浮点型大家族:(1)float  //单精度浮点数
                         (2)double  //双精度浮点数

构造类型:(1)数组类型
                  (2)结构体类型  struct
                  (3)枚举类型  enum
                  (4)联合类型  union

指针类型:(1)int *pi
                  (2)char *pc
                  (3)float* pf
                  (4)void* pv

空类型:void表示空类型,通常应用于函数的返回类型、函数的参数、指针类型。

             例如调用函数的时候无参数时,写成Add(void),在传参时就会报错。

#include <stdio.h>
void Add(void)
{
    printf("hello! world");
}
int main()
{
    Add();
    Add(100);
    return 0;
}

(二)整形在内存中的存储

  整形在内存中是以补码的形式存放的,对于正整数来说,它的源码,反码,补码相同。对于负整数来说,它的补码等于源码符号位不变,其它位按位取反,然后再末位加一。

  例如,int a = -1;在VS2019中查看a的内存如图,一个整形四个字节,一个字节八个比特位,这时候我们看到的存储方式是十六进制的,一个f在二进制下是1111,那么在二进制下,a的补码为11111111111111111111111111111111。

  按照按位取反,末位加一的规矩,a的反码为10000000000000000000000000000000,a的源码为10000000000000000000000000000001。

   当int a = 0x11223344时,我们再来看内存,可以看到,从44到11,内存以字节为单位进行存放的时候,是从高地址向低地址存放的,像这样把一个数字的低位字节的内容,存放在内存的低地址处,把高位字节的内容存放在内存的高地址处,就是小端字节存储。与小端字节存储正好相反,大端字节存储把一个数字的低位字节的内容,存放在内存的高地址处,把高位字节的内容存放在内存的低地址处。

 

 

    那么,如何判断是小端字节存储还是大端字节存储呢?我们是这样来实现的。因为char类型的整形含两个字节,int类型的变量含四个字节,定义一个数为1,通过强制类型转换,int转换为char,如果是小端字节存储,在内存中为01 00 00 00,转换后为1,如果是大端字节存储,转换后则为0,通过判断取值来判断大小端字节存储。

include<stdio.h>
int check_sys()
{
    int i=1;
    return (*(char*)&i);
}
int main()
{
    int ret=check_sys();
    if(ret==1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    return 0;
}

  (三)浮点型在内存中的存储

  浮点型在fioat.h头文件中定义了浮点型的范围,浮点数在内存中是怎样存储的呢?我们可以先来看一个例子。

int main()
{
    int n = 9;
    float* pFloat = (float*)&n;
    printf("n的值为:%d\n", n);
    printf("*pFloat的值为:%f\n", *pFloat);
    *pFloat = 9.0;
    printf("num的值为:%d\n",n);
    printf("*pFloat的值为:%f\n",*pFloat);
    return 0;
}

  这个代码得到的结果是这样的。

 浮点数的存储规则是怎样的?根据国际标准IEEE (电气和电子工程协会) 754标准, 任意一个二 进制浮点数V可以表示成下面的形式:

        ●  (-1)^S*M*2^E
        ●  (-1)^s表示符号位,当s=0, V为正数,当s=1, V为负数。
        ●  M表示有效数字,大于等于1小于2。
        ●  2^E表示指数位。

  例如,一个浮点数数5.5,第一位小数相当于2的-1次方,写成二进制就是101.1,即(-1)^0*1.011*2^2,其中S=0,M=1.011,E=2。,S,M,E在内存中的占比是这样的。

 因为规定M是大于1并且小于2的,所以在M中,默认第一位为1,所以只需要存小数点后面的位数就行了。E被解读成一个无符号数,但是实际上E也有可能是负数,对于这样的情况,IEEE 754规定,存入内存时必须加上一个中间数,对8位的E,加127,对11位的E,加1023。

  例如,存入5.5,S=0,M=1.011,E=2,得0 10000001 01100000000000000000000,转化为16进制为40 B0 00 00,可以观察到内存中就是此数。

  要从内存中取出E时,要分三种情况:

     (1)E不全为0或不全为1:即指数E的计算值减去127 (或1023) ,得到真实值,再将有效数字M前加上第一位的1。
     (2)E全为0:E等于1-127 (或者1-1023) 即为真实值,
     (3)E全为1:这时,如果有效数字M全为0,表示无穷大(正负取决于符号位s) 。

这样就可以很好的解释前面的代码啦,(不足之处,欢迎大家指正)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值