【数据在内存中的存储】肝货满满

news2024/11/16 9:46:43

前言

我们知道在C语言中的基本内置类型:

  • char //字符数据类型
  • short //短整型
  • int //整形
  • long //长整形
  • long long //更长的整形
  • float //单精度浮点型
  • double //双精度浮点型

那么这些类型是如何存储的呢?

回顾指针类型:

  • *int pi
  • *char pc
  • *float pf
  • *void pv

void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型

在了解如何存储之前,我们先来了解原码,反码,补码

目录

  • 前言
  • 1原码,反码,补码
  • 2.整形在内存中的存储
  • 3.大小端介绍
  • 4.浮点型在内存中的存储
    • 4.1浮点数存储规则

1原码,反码,补码

计算机中的整数有三种2进制表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位
正数的原、反、补码都相同
负整数的三种表示方法各不相同
原码:
直接将数值按照正负数的形式翻译成二进制就可以得到原码
反码:
将原码的符号位不变,其他位依次按位取反就可以得到反码
补码:
反码+1就得到补码

对于整数来说,数据存放在内存中,其实存放的是补码
因为计算机中只能执行加法,例如:1-1在计算机中是1+(-1),1和-1的补码相加得到0。
在这里插入图片描述

2.整形在内存中的存储

一个变量的创建是要在内存中开辟空间的,空间的大小是根据不同的类型而决定的
那么接下来我们看看数据在所开辟的内存中到底如何存储的

例如:

int main()
{
	int a = 20;
	//00000000 00000000 00000000 00010100  -  补码
	//   00        00      00       14 - 16进制
	int b = -10;
	//10000000000000000000000000001010  - 原码
	//11111111111111111111111111110101  - 反码
	//11111111 11111111 11111111 11110110  - 补码
	//   ff       ff       ff       f6  - 16进制
	return 0;
}

在这里插入图片描述

我们可以看到把整数的补码转换为十六进制就是内存中存储的方式

3.大小端介绍

什么大端小端:
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

这句话什么意思呢?接着往下看

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8 bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式

在这里插入图片描述
设计一个程序来判断当前机器的字节序:

int check_sys()
{
	int i = 1;
	return (*(char*)&i);//解引用char*的指针能访问一个字节,如果第一个字节是1,那就是小端
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

4.浮点型在内存中的存储

常见的浮点数:
3.14159
1E10
浮点数家族包括: float、double、long double 类型
浮点数表示的范围:float.h中定义

4.1浮点数存储规则

详细解读

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

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

举例来说:
十进制的5.0,写成二进制是 101.0,转换为科学计数法是1.01,小数点向左移动两位,即1.01 * 2^2,那么按照上面的公式S=0,M=1.01,E=2
5.0
101.0
1.01*2^2
(-1)^0 *1.01 * 2^2

对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M
在这里插入图片描述
S:
无非就是0或者1
M:
1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分
IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时
候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字
E的情况就比较复杂
首先,E为一个无符号整数(unsigned int)
这意味着,如果E为8位,它的取值范围为0 ~ 255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位(双精度浮点数64位,E是11位)的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即
10001001。

指数E从内存中取出还可以再分成三种情况:

E不全为0或不全为1:

这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1

E全为0:

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字

E全为1:

这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)

例题:

int main()
{
	int n = 9;
	float* pFloat = (float*)&n;

	printf("n的值为:%d\n", n);
	//00000000000000000000000000001001 - 9的补码

	printf("*pFloat的值为:%f\n", *pFloat);
	//0 00000000 00000000000000000001001
	//(-1)^0 * 0.000000000000000001001 * 2^-126  - 无限接近于0的数字
	//打印出来当然是0.000000

	*pFloat = 9.0;
	//1001.0
	//1.001 * 2^3
	//(-1)^0 * 1.001 * 2^3
	//0 10000010 00100000000000000000000 - 9.0以浮点数的视角存进n
	
	printf("num的值为:%d\n", n);
	//n打印的时候以%d有符号整数打印,高位为0,正数的原反补相同
	//直接打印上面的二进制,是一个非常大的数字

	printf("*pFloat的值为:%f\n", *pFloat);
	//现在n里存的就是浮点数的二进制9.0,以浮点数方式打印,理所当然是9.000000
	return 0;
}
}

在这里插入图片描述
如果觉得对你有用的话,记得三连哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/140567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

String的讲解(Java系列9)

目录 前言&#xff1a; 1.String 1.1字符串的构造 1.2Sting对象的比较 1.3字符串的查找 1.4字符串的转化 1.4.1数值和字符转换 1.4.2大小写转换 1.4.3字符串转数组 1.4.4格式化 1.5字符串的替换 1.6字符串拆分 1.7字符串截取 1.8字符串去空格 1.9字符串的不可变…

Matplotlib笔记 · 绘图区域的结构和子图布局与划分(figure, axes, subplots)

文章目录1. 绘图区域的结构2. subplot系方法 ( subplot布局 )2.1 使用 add_subplot(nrows, ncols, index) 逐一创建子图2.2 控制子图大小和位置 ( add_subplot(nrows, ncols, index) 参数详解 )2.3 使用 subplots(nrows, ncols) 批量创建多张子图3. axes系方法 ( axes布局 )3.1…

基于张量变换域低秩正则化的图像恢复方法

高光谱图像、磁共振图像、RGB图像等都可以表示成三维数组的形式&#xff0c;在数学上将这种多维数组称为高阶张量&#xff0c;同样&#xff0c;上述三种图像都可以表示成三阶张量。在空间上&#xff0c;图像本身就具有结构相似性&#xff0c;在高光谱图像的第三个模态上&#x…

日志分析工具

iis、windows日志做日志分析比较麻烦&#xff0c;这里找到了一款好用的免费的日志分析工具 Log Parser Lizard&#xff0c;下载这个工具之前建议先安装LogParser虽然他会自动弹窗提示。 1. 安装软件 安装没什么好说的一直下一步下一步就行 启动之后点击OK 弹出激活页面让激活…

mod函数怎么取模

mod 是 MySQL 中的数值函数&#xff0c;写法为&#xff1a;mod(x,y)&#xff0c;意思是返回x/y的取模的值。 什么是取模&#xff1f;取模就是取余数。 ① 如果第一个值比第二个值大&#xff0c;我整理出来的取模公式就是&#xff1a;第一个值-第一个值里面包含了几个第二个值相…

MATLAB-多边形填充图绘制

fill函数用于绘制并填充二维多边图形。将数据点视为多边形顶点&#xff0c;并将此多边形涂上颜色&#xff0c;便于用户理解图形中的数据代表的含义。具体调用方法如下:fill(X, Y,C):用X和Y中的数据生成多边形&#xff0c;用C指定颜色填充。其中C为色图向量或矩阵。若C是行向量&…

商标注册流程有什么步骤

​一、商标注册流程有什么步骤? 商标注册流程&#xff1a; 1、需要企业提供营业执照副本复印件和商标样稿及主要商品或服务&#xff0c;递交商标局; ​ 2、商标局形式审查(7-15个工作日)接到《商标注册申请受理通知书》; 3、商标局实质审查(5-8个月左右); 4、商标公告(3…

【Linux多线程编程】3. 多线程共享资源

回顾 上篇文章【Linux多线程编程】2.线程创建与回收 简单介绍了如何创建一个线程并且回收它&#xff0c;末尾给出了如下这段代码&#xff0c;本文将从这段代码入手介绍线程资源、线程共享资源、线程独占资源&#xff0c;并在最后引出多线程安全访问资源的方法。 /** test_pth…

新华三(H3C)的沉浮往事

根据2023年1月3日紫光股份发布的最新公告&#xff0c;Hewlett Packard Enterprise Company全资子公司H3C Holdings Limited&#xff08;“HPE 开曼”&#xff09;和Izar Holding Co&#xff0c;将向紫光股份全资子公司紫光国际信息技术有限公司出售其持有的新华三集团有限公司合…

【Linux】伪目标 PHONY | 探讨项目构建问题 | Makefile | 依赖关系与依赖方法

&#x1f923; 爆笑教程 &#x1f449; 《看表情包学Linux》&#x1f448; 猛戳订阅 &#x1f525; &#x1f4ad; 写在前面&#xff1a;本章我们要学习的是 makefile。会不会写 makefile&#xff0c;从一个侧面说明一个人是否具备完成大型工程的能力。一个工程中的源文件不计…

Vector - VT System - 板卡_VT1004

今天我们来聊一下导入和测量模块VT1004版本&#xff0c;我们从它的技术参数、通道介绍、功能介绍几个方面来全面的介绍这块板卡&#xff0c;废话不多说&#xff0c;我们直接来看这2块板卡吧。 测量模块 - VT1004 通道功能介绍&#xff1a; >通过继电器切换到原始负载和母线…

Qt扫盲-QSet理论总结

QSet理论总结一、概述二、使用1. 声明2. 插入元素3. 遍历元素4. 删除元素5. 集合的运算6. 其他一、概述 QSet是Qt的通用容器类之一。俗称一个集合。QSet会按未指定的顺序存储值&#xff0c;也就是随机存值的方式&#xff0c;并提供非常快速的值查找。在内部&#xff0c;QSet实…

python学习|第二天

文章目录1.函数函数调用函数返回值函数参数2.bug常见类型粗心类型知识点不扎实思路不清被动掉坑常见异常类型3.文件的读写打开模式文件对象常用方法with方法4.os模块操作目录相关函数5.打包成可执行文件1.函数 函数调用 p89&#xff0c;笔记待补 函数返回值 1&#xff09;如…

微信小程序开发过程整理

目录1微信开发相关介绍1.1微信公众平台1.2微信开放平台1.3注意事项2微信小程序开发整体介绍2.1微信小程序简介2.2小程序接入流程3框架简介3.1uni-app简介3.2学习使用uni-app3.3学习微信小程序开发4开发规范5开发示例5.1开发工具5.2开发调试5.2.1导入代码5.2.2项目运行5.2.3在微…

java常见题3

11.二分查找的次数 奇数取 中间那一个作为中值 偶数个取 中间靠左 然后不断模拟这个算法 查找的最多次数&#xff1a;n个元素里最多查找log二N 个元素Log2 128 7 12.equals和hashCode java.lang.Object类中有两个非常重要的方法&#xff1a; public boolean equals(Obje…

YOLOV5模型训练

之前在博文中讲到了YOLOV5的运行,以及转tensorrt. 但是, 一个模型通常需要结合数据训练,才能得到更好的结果. 因此,我们有必要熟悉yolov5的训练过程. 执行训练的过程 Yolov5的github提供了官方的训练脚本. 第一次运行,会自动下载数据集,然后会检测到你的gpu配置,如果不对,…

【数据结构】树

树(Tree) 知识框架 树的定义 树和图一样都是非线性结构&#xff0c;树是n个结点的有限集合&#xff0c;当n0时&#xff0c;称这棵树为空树。 非空树有以下特征&#xff1a; 有且仅有一个称为根的结点。如果n>1, 除根结点以外其它结点可以分为m(m>0)个不相交的集合T1,T…

E4445A频谱分析仪

18320918653 E4445A 名称&#xff1a;E4445A 频谱分析仪&#xff0c; 3 Hz - 13.2 GHz 详细&#xff1a;主要技术指标 性能 /-0.24 dB幅度精度 -155 dBm/Hz显示的平均噪声电平&#xff08;DNAL&#xff09; 10 kHz偏置时的相噪&#xff1a;-118 dBc/Hz 81 dB W-CDMA AC…

春节倒计时,让我来秀一手:用Python制作一个对联生成器

前言 跨年跨完了&#xff0c;马上就要迎来春节了&#xff0c;这不得秀一手&#xff1f; 那就直接开始春节的表演呗 勉勉强强来用python制作对联生成器吧 效果展示 这里的话&#xff0c;你自己想要啥春联主题是可以搜索滴&#xff0c;有些地方也是可以看着改的&#xff0c;…

FPGA知识汇集-FPGA的低功耗设计方法总结

精确的热分析在很多电子产品设计中都有着举足轻重的作用&#xff0c;在高端的PCB设计中尤为突出。热分析的结果常常会影响PCB的机械层设计和产品的外壳设计:是否需要安装散热片、散热风扇等。如果安装散热风扇&#xff0c;往往需要降低其噪音&#xff0c;这将使得机械层设计变得…