数据存储(C语言)

一、前言

我们都知道,在C语言中数据可以分为字符型(char)、整型(int)、浮点型(float,double)这几种基本类型,其中字符型数据在计算机中是以整型形式存储的,因此,主要讨论一下整型和字符型数据在内存中存储的形式。

运行以下程序:

#include<stdio.h>
int main()
{
	int num = 4;
	float* p = (float*)&num;

	printf("%d\n", num);
	printf("%f\n", *p);

	*p = 9;
	printf("%d\n", num);
	printf("%f\n", *p);
	return 0;
}

 如果整型和浮点型数据在内存中存储方式相同,那么无论以什么类型打印num,结果都应该一样,但事实恰恰相反,这也说明了整型与浮点型数据在存储方式上完全不同。

二、整型数据的存储

整型数据在内存中以补码的形式存储。关于原码、反码、补码的转换,请参照:https://blog.csdn.net/weixin_61486281/article/details/126102365

C语言中char类型是1个字节,但也存在4个字节的int ,8个字节的double;16位或32位的处理器的寄存器宽度也大于1个字节。因此,在内存中存储时就存在字节存储顺序的问题,这就是大小端字节序的问题。

大端字节序:数据的低位保存在内存的高地址中,高位保存在内存的低地址中。

小端字节序:数据的低位保存在内存的低地址中,高位保存在内存的高地址中。

那么,要怎么查看机器的字节序呢?有以下方法:

#include<stdio.h>
//检验机器字节序
int Fun1()
{
	int i = 1;
	return (*(char*)(&i));
}

//利用共用体的特点
int Fun2()
{
	union
	{
		int i;
		int c;
	}un;
	un.i = 1;
	return un.c;
}

int main()
{
	char ret = Fun2();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

三、浮点数的存储

根据国际标准IEEE规定,浮点数在内存中以(-1)^S*M*2^E表示。

  1. (-1)^S表示浮点数的符号位,当S=1时,浮点数是负数;当S=0时,浮点数是正数;
  2. M是浮点数的有效数字位,1<M<2,但计算机保存M时,默认整数位是1,只保存有效数字 位;
  3. E是指数。

例如,十进制数5.5,写成二进制是101.1,即(-1)^0*1.011*2^2.

IEEE规定:对于32位浮点数,最高位是符号位,存储S;之后的8位是指数位,存储E;剩下的23位是有效数字位,存储M。对于64位浮点数,最高位是符号位,存储S;之后的11位是指数位,存储E;剩下的52位是有效数字位,存储M。

对单精度浮点数,E只占8个比特位,取值在0~255,在实际中,E有可能是负数,因此在存储时,E要加上127,而双精度浮点数则要加上1023.

 

 注意: 

1.当E全为1时,若有效数字全为0,则该数表示正负无穷大;

2.当E全为0时,若将内存中的数还原成真实值,E的真实值是1-127(1023),同时M还原时不用加上整数部分的1,直接写成0.XXXXX,表示的是接近于0的数。

3.由于浮点数在内存中存储时,小数部分可能无法正好配齐,如十进制数3.14,因此浮点数无法直接比较大小,可以通过判断浮点数是否在某个范围内比较。

四、总结

现在我们再来看前言中的题目,

  •  int类型的十进制数num=4在内存中存储形式00000000 00000000 00000000 00000100 
  • 以float形式将num从内存中取出,由于指数部分全为0,则E=1-127=-126,有效数字部分M=0.0000000 00000000 00000100,还原出的数num约等于0;
  • float类型数据*p=9,在内存中存储的是0 10000010 00100000000000000000000,以int 类型取出,从符号位可知是正数,原反补码都一样,则得到1,091,567,616。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值