C语言——数据的存储

C语言——数据的存储

数据类型介绍

​ 在C语言中常见的字符类型7种(由小到大列出)

​ char:(字符型)在内存中占1个字节

​ short:(短整型)在内存中占2个字节

​ int:(整型)在内存中占用4个字节

​ long:(长整型)在内存中占用(long long>=long>=int)个字节,根据编译器决定

​ long long:(长整型)在内存中占用8个字节

​ float:(单精度浮点型)在内存中占用4个字节

​ double:(双精度浮点型)在内存中占用8个字节

​ 这里提一下在使用长整型时一般使用 long long,因为long的字节数是不确定的,所有建议直接使用long long。

​ 数据类型有无符号数(unsigned)和有符号数(signed)只需在创建数值时在类型前面加上,一般只有创建无符号类型时才会加上,普通数都是默认有符号。

数据在内存中的存放

​ 内存中的有符号数有三种二进制的形式:原码,反码,补码。但是在内存中有符号数都是以二进制补码的形式存放,当在内存中存放一个数值时,编译器会自动将数值转换为二进制。三种形态分别由符号位数值位组成,二进制的第一个数字,**‘1’代表的是负数,‘0’**代表的是正数。

​ 如何转换二进制为补码和如何转换回原码?

​ 一般我们在读一个数字时都是二进制的原码,原码转换成反码(符号位1不变其他位按位取反),反码转换为补码(反码加一)。补码转换为原码有两种方法:1.补码减一,再符号位不变,其他位按位取反。2.补码加一,再符号位不变其他位按位取反。其实原码变成补码和补码变成原码方法一样!

​ 正数在内存中原码,反码,补码相同。

​ 负数在内存中需要转换才可以得到补码。

在这里插入图片描述

​ 数据在内存中都是先使用高地址存储再使用低地址,例图:

在这里插入图片描述

但是在这里会发现数据的存储似乎很奇怪!这时候就不可避免的会谈到我们的大小端问题

大小端(存储模式)

小端:数据的低位放在低地址处,数据的高位放在高地址处

大端:数据的高位放在低地址处,数据的低位放在高地址处

在这里插入图片描述

可以看见本机的存储方式是小端模式,一般的编译器采用的都是小端模式存储。

那么如何知道自己的编译器使用的是大端还是小端呢?

这里为大家提供一个函数:

#include<stdio.h>
int is_what()
{
    int a=1;
    return*(*char)&a);//取出a的地址强制类型转换,然后解引用得到a的最低位地址,返回
}
int main()
{
    if(is_what())//如果返回值为真,也就是 1 判断编译器为 小端
    {
        printf("小端\n");
    }
    else
        printf("大端\n");
   return 0; 
}

在一般的编译器下都会使用小端存储模式,但是我们应该知道如何去实现这个函数和判断编译器的存储模式。

整型char 的范围

整型char的范围是127~-128,所以当你为整型char赋值时应该格外小心,特别是遇到 unsigned char 时,一不小心可能便会遇见bug。

例如:

#include<stdio.h>
int main()
{
    unsign char i=0;
    for(i=0;i<=127;i++)
    {
        printf("hello\n");
    }
    return 0;
}

看起来好像并没有什么问题,可是当你打印时会出现死循环的现象。

原因就是当i=128时会自动变成-128,条件成立,程序继续,所以应该特别注意当使用char类型时应该避免写出bug。

浮点型在内存中的存储

整型和浮点型,两个相同的数字,16进制却不同:
在这里插入图片描述

可知浮点型和整型在内存中是不同的存储方法,所以当你将一个浮点型的强制类型转换的时候,可能会出现意料不到的结果。

那么浮点数是如何存储在内存中呢?

根据相关资料,我找到了这个公式。
( − 1 ) s ∗ M ∗ 2 E (-1)^s*M*2^E (1)sM2E
s位是用来表示该浮点数的正负,为正数时s=0,负数时s=1。

M是有效数字,大于1 ,小于2

2^E是用来表示指数位

float数据在内存中存储方式图解:double S也是一位,E是11位,M是52位

在这里插入图片描述

例如:5.5在内存中存储

先将5变成二进制->101,在将0.5变成二进制->.1,结合起来->101.1->1.011*2^2,得到:E=2,M=1.001,s=0;

根据规定,当E存入内存中时需要+127(double+1023),M存入需要把 1 省略。

得到 5.5的二进制序列->

0100 0000 1011 0000 0000 0000 0000 0000

16进制->

40 b0 0000

在这里插入图片描述

不过当E<0 时,编译器会自动判定该数为0,当E为全1时,编辑器默认无穷大,取决于S为正或者负。

今天的分享就到这里,觉得有用的话,可以留下你的赞吗?☺

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值