当前位置: 首页 > news >正文

数据在内存中的存储

数据在内存中的存储

  • 一、整数在内存中的存储
  • 二、大小端字节序和字节序判断
    • 1.大小端
    • 2.练习
  • 三、浮点数在内存中的存储
    • 1.浮点数的存储
      • 1.1浮点数存的过程
      • 1.2浮点数取的过程
    • 2.题目解析

一、整数在内存中的存储

对于整型来说,数据存放内存中其实存放的是补码。

二、大小端字节序和字节序判断

1.大小端

超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,分为大端字节序存储和小端字节序存储:
eg:0x11223344

  • 大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。11 22 33 44
  • 小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。44 33 22 11

2.练习

1.设计一个小程序来判断当前机器的字节序。

//代码1
#include<stdio.h>
int check_sys()
{
	int i=1;
	return (*(char*)&i);
	//先取出1在内存中的存储,强转为char*可解引用取出第一个字节
}

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

//代码2
int check_sys()
{
	union
	{
		int i;
		char c;
	}un;
	un.i = 1;
	return un.c;
}
//union允许i和c共享同一块内存,c访问的是i的最低字节
int main()
{
	char a = -1;
	//10000000000000000000000000000001
	//11111111111111111111111111111110
	//11111111111111111111111111111111
	//char1字节:11111111
	//char默认signed,升int以符号位补齐
	//11111111111111111111111111111111
	signed char b = -1;//同char
	unsigned char c = -1;
	//11111111
	//unsigned升int以0补齐
	//00000000000000000000000011111111
	printf("a=%d,b=%d,c=%d,a,b,c);
	return 0;
}

输出结果:a=-1,b=-1,c=255
3.

//3.1
int main()
{
	char a = -128;
	//10000000000000000000000010000000
	//11111111111111111111111101111111
	//11111111111111111111111110000000
	//10000000
	//char整型提升:
	//11111111111111111111111110000000
	printf("%u\n",a);//4294967168
	return 0;
}
//3.2
int main()
{
	char a = 128;
	//00000000000000000000000010000000
	//10000000
	//可得到与上题相同结果
	printf("%u\n",a);
	return 0;
}
int main()
{
	char a[1000];
	int i;
	for(i=0;i<1000;i++)
	{
		a[i] = -1-i;
		//-1,-2,-3...-128,127,126...1,0
	}
	printf("%d",strlen(a));//\0的ASCII码是0,所以strlen到0结束,255
	return 0;
}

在这里插入图片描述
由图可得,-1后-128的下一个数是127。
5.

//5.1
unsigned char i = 0;//无符号char类型范围0~255
int main()
{
	for(i=0;i<=255;i++)//条件恒成立,死循环打印下面字符串
	{
		printf("hello world\n");
	}
	return 0;
}
//5.2
int main()
{
	unsigned int i;//无符号整型
	for(i=9;i>=0;i--)//同样死循环
	{
		printf("%u\n",i);
	}
	return 0;
}
//x86环境 小端字节序
int main()
{
	int a[4] = {1,2,3,4};
	int *ptr1 = (int *)(&a+1);//4
	int *ptr2 = (int *)((int)a+1);
	printf("%x,%x,ptr1[-1],*ptr2);
	return 0;
}

在这里插入图片描述
这里a是指数组首元素地址,指向01000000的地址被强转为int类型加一,则指向下一个字节,再转为int*解引用,一次取出的是四个字节int的值,小端存储打印02000000。

三、浮点数在内存中的存储

1.浮点数的存储

浮点数在计算机内部的表示方法,根据国际标准IEEE754,任意一个二进制浮点数V可以表示成下面的形式:
在这里插入图片描述

  • (-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数
  • M表示有效数字,M是大于等于1,小于2的
  • 2^E表示指数位
    eg:-5.0 -> -101.0 -> -1.01*2^2
    S=1,M=1.01,E=2。
    对于32位浮点数,最高1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M;
    对于64位浮点数,最高1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。

1.1浮点数存的过程

M:
IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的效数部分,等到读取的时候再把第一位的1加上去,目的是节省1位有效数字。
E:
首先E为一个无符号整数,但在实际中会出现E为负数的情况,因此规定存入内存时E的真实值还必须加上一个中间值,8位E:+127;11位E:+1023。

1.2浮点数取的过程

一共三种情况:
1.2.1 E不全为0或不全为1
E减去127,再将有效数字M前加上第一位的1。
eg:0.5 ->0.1(二进制形式) ->1.0*2^(-1)
E:-1+127:126 ->01111110
最终得到:1 01111110 00000000000000000000000
1.2.2 E全为0
这时,浮点数的指数E等于1-127(或1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数,表示±0,以及接近于0的很小的数字。
1.2.3 E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。

2.题目解析

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

当数值或指针的类型与打印的类型一致时,会出现希望得到的结果。

  • 第二问:00000000 00000000 00000000 00001001
    将原来9的二进制序列以浮点数的形式拆分:0 00000000 00000000000000000001001
    由上得:E全为0,即结果为0.000000
  • 第三问:9.0 ->1001.0 ->1.001*2^3
    S=0,E=3(+127=130),M=1.001(去1->.001)
    0 10000010 00100000000000000000000
    在这里插入图片描述
    使用计算器打印最终结果是1091567616。

相关文章:

  • 2025年02月17日Github流行趋势
  • JavaScript数组-创建数组
  • 投资组合风险管理
  • JDK 24:Java 24 中的新功能
  • 使用Java爬虫获取1688自定义API操作接口
  • Flutter 网络请求与数据处理:从基础到单例封装
  • 【吾爱出品】[Windows] 透明浏览器V1
  • 【Elasticsearch】监控与管理:集群安全管理
  • Rabbitmq的三个端口区分
  • 如何利用国内镜像从huggingface上下载项目
  • 实现可拖拽的 Ant Design Modal 并保持下层 HTML 可操作性
  • 人工智能(AI)的定义与硬件需求
  • 物理层芯片的Auto-negotiation(自动协商)的详细解释
  • 解决 matplotlib 不支持中文字符
  • C++(23):unreachable
  • 【算法与数据结构】字典树(Trie)详解
  • java爬虫抓取网页搜索数据
  • 蓝桥杯 Java B 组 之树的基础(二叉树遍历)
  • Linux Socket编程:TCP开发指南
  • MoE硬件部署
  • 南方降水频繁暴雨连连,北方高温再起或现40°C酷热天气
  • 古巴外长谴责美国再次将古列为“反恐行动不合作国家”
  • 习近平致电祝贺阿尔巴尼斯当选连任澳大利亚总理
  • 来伊份发布关于消费者反映蜜枣粽问题处理的情况说明:与消费者达成和解
  • 云南大理铁路枢纽工程建设取得两大进展,预计明年建成
  • 习近平出席中国-拉美和加勒比国家共同体论坛第四届部长级会议开幕式并发表重要讲话