数据在内存中的存储(一个新手的理解)

 

目录

1.整数在内存中的存储

2.大小端字节序和字节序判断

2.1什么是大小端?

2.2为什么有大小端呢?

2.3那怎么知道编译器是什么存储呢?

2.4几个有趣的小练习 

3.浮点数在内存中的存储

3.1练习

3.2浮点数的储存 

3.2.1 浮点数存的过程

3.2.2浮点数取的过程

1.E不全为0或1.

E全为0

E全为1


1.整数在内存中的存储

  正整数的原,补,反码都相同。

  负整数的三种表示方法各不相同。

提示:负数的反码等于原码符号位不变,其他位置的二进制位取反。

           负数的补码等于反码+1.

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

  为什么呢?

  使⽤补码,可以将符号位和数值域统⼀ 处理;

2.大小端字节序和字节序判断

首先看一个代码(VS系统)

#include <stdio.h>
int main()
{int a = 0x11223344;return 0;
}

 这个代码的结果呢?

可以看出低位的数字存储在了前面;这是小端存储

2.1什么是大小端?

超过一个字节的数据在内存中存储时,就有存储顺序的问题,按照不同的存储顺序,我们可以把分为大端字节存储和小端字节存储。在不同的编译器中不同。

大端存储:通俗来说就是数字的比较大的位数存到了前面。就像 0x11223344,如果为大端存储的话那在内存里面 先存储的就是 11 22 33 44,和上面的图片相反

小端存储:就是数字的比较小的位数存到了前面。和上图一样!!!

一个自编小口诀,前大大,前小小。就是前面如果是数字位数大的数字的话就是大端存储,反之相同。

2.2为什么有大小端呢?

每个地址单元都 对应着⼀个字节,⼀个字节为8 bit 位,但是在C语⾔中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了⼤端存储模式和⼩端存储模式。

2.3那怎么知道编译器是什么存储呢?

可以写一个小代码来研究

#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;
}

 这个代码这样看,在最上面的check 函数中先给 int i = 1,之后返回时将 i 的 强制转换为 char * 是因为 本来 存储的是 int 变量 占了4个字节 ,如果把这个 存储的 字节 单独拿出来看呢, 如果 前面 第一个 字节存的 是 01,那就代表了 将小位的数字存在了前面,为小端存储,反之相同。

2.4几个有趣的小练习 

#include <stdio.h>
int main()
{char a= -1;signed char b=-1;unsigned char c=-1;printf("a=%d,b=%d,c=%d",a,b,c);return 0;
}

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

这个练习,可以看出用char 来存储数字,但存储数字的时候存的是补码。因为char 其实是signed char的缩写。所以a b 其实是相同的。因为 sighed char 是有符合的字符型,只保存一个字节,所以 3个变量的二进制位都是 11111111.因为前两个变量是有符号的,所以在下面要求打印%d 时发生整型提升,因为两个变量是有符号的,所以提升时前面的符号位为1.所以提升时32个二进制位全为1 。但打印时 是以原码打印,因为前两个变量的符号位是1 是负数。负数的原码 等于 补码减一 并取反。所以最终前两个变量的 原码就是 第一位二进制位和最后一位二进制位为1,其他全为0,所以等于-1.

但不同的是 unsighed char 因为 是无符号整型,在整形提升时,c变量的二进制位前面全部补0.所以c 的二进制表示是 00000000 00000000 00000000 11111111.因为正数的原反补码相同所以,c = 255.

#include <stdio.h>
int main()
{char a = -128;printf("%u\n",a);return 0;
}#include <stdio.h>
int main()
{char a = 128;printf("%u\n",a);return 0;
}

第一个a 打印出来一个特别大的数字,第二个char

这个练习要求打印 %u 就是无符号整型。给的两个有符号的 char 类型。

第一个 char 因为是负的-128,所以他的 原码其实就是 10000000,对他整型提升后 就是。

11111111 11111111 11111111 10000000,因为要打印无符号整型,所以第一个二进制位不看做符号位。,所以这个数字是正数,原码反码补码相同,所以打印出来一个特别大的数字。

第二个 a 其实写下来和第一个a 的原码其实是一样的,因为 char 只有 一个字节8个二进制位。-128 和 128的二进制位其实相同,所以两个数字的结果相同。

#include <stdio.h>
int main()
{char a[1000];int i;for(i=0; i<1000; i++){a[i] = -1-i;}printf("%d",strlen(a));return 0;
}

 这个代码的最终结果是255.

为什么呢?首先给了一个 1000的i 循环。将a【i】 = -1 - i;

因为a 【i】是char 类型 只有 1个字节 8 个二进制位。第一个a【i】 = -1.二进制位是

10000001.每次都减一直到 11111111 ,它的原码就是 10000000.在vs 中这个数字为-128

所以-128再减一 就变成了 127 在一直减到 00000000.其中总共走了 255次。出现 0 。

strlen 计算字符直到出现 0.所以得出255.

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

无符号char型的范围如上图。

本题的无符号char 类型 的范围 0 -255.因为for 循环一直打印到255.但255加一 又 等于 0.

这就会导致死循环。

#include <stdio.h>
int main()
{unsigned int i;for (i = 9; i >= 0; i--){printf("%u\n", i);}return 0;
}

这题也是一个死循环,因为是无符号整型,所以当减到0时,再减一,就变成了 32个二进制位都是 1.这样一直循环下去。 

3.浮点数在内存中的存储

常⻅的浮点数:3.14159、1E10等,浮点数家族包括: float double long double 类型。
浮点数表⽰的范围:float.h中定义

3.1练习

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;
}

由上图可以看出浮点数和整型的存储方式是不同的

3.2浮点数的储存 

上图则是浮点数在计算机内部的表示方法。

⼗进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2
那么,按照上⾯V的格式,可以得出S=0,M=1.01,E=2。
⼗进制的-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

3.2.1 浮点数存的过程

M保证是 1<=M<2.

E如果为8位取值范围就是0-255,如果为11位就是0-2047.根据IEEE的规定,需要给E中额外存入一个数字 8位E就是 127 ,11位就是 1023.⽐如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

3.2.2浮点数取的过程

指数E从内存中取出还要分为三种情况。

1.E不全为0或1.
这时,浮点数就采⽤下⾯的规则表⽰,即指数E的计算值减去127(或1023),得到真实值,再将有效
数字M前加上第⼀位的1。
⽐如:0.5 的⼆进制形式为0.1,由于规定正数部分必须为1,即将⼩数点右移1位,则为1.0*2^(-1),其
阶码为-1+127(中间值)=126,表⽰为01111110,⽽尾数1.0去掉整数部分为0,补⻬0到23位
E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,⽽是还
原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字。
E全为1
这时,如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s);
好了,关于浮点数的表⽰规则,就说到这⾥。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java-LangChain:使用 ChatGPT API 搭建系统-4】评估输入-分类

第三章&#xff0c;评估输入-分类 如果您正在构建一个允许用户输入信息的系统&#xff0c;首先要确保人们在负责任地使用系统&#xff0c;以及他们没有试图以某种方式滥用系统&#xff0c;这是非常重要的。 在本章中&#xff0c;我们将介绍几种策略来实现这一目标。 我们将学习…

pytorch之nn.Conv1d详解

自然语言处理中一个句子序列&#xff0c;一维的&#xff0c;所以使用Conv1d

开启创意思维,畅享Mindomo Desktop for Mac思维导图之旅

在数字化时代&#xff0c;我们需要一个强大而直观的工具来整理和展现我们的思维。Mindomo Desktop for Mac&#xff08;Mindomo&#xff09;作为一款免费的思维导图软件&#xff0c;将为您提供卓越的创意思维体验。 Mindomo拥有直观的界面和丰富的功能&#xff0c;让您能够方便…

[React] Zustand状态管理库

文章目录 1.Zustand介绍2.创建一个store3.使用方法3.1 获取状态3.2 更新状态3.3 访问存储状态3.4 处理异步数据3.5 在状态中访问和存储数组3.6 持续状态 4.总结 1.Zustand介绍 状态管理一直是现代程序应用中的重要组成部分, Zustand使用 hooks 来管理状态无需样板代码。 更少…

JVM篇---第一篇

系列文章目录 文章目录 系列文章目录一、知识点汇总二、知识点详解:三、说说类加载与卸载一、知识点汇总 JVM是Java运行基础,面试时一定会遇到JVM的有关问题,内容相对集中,但对只是深度要求较高. 其中内存模型,类加载机制,GC是重点方面.性能调优部分更偏向应用,重点突出实践…

python二次开发CATIA:为选中元素上色

先打开一个零件文档&#xff0c;然后用鼠标选中元素&#xff0c;再运行如下python程序&#xff1a; import win32com.client import pywintypes # 导入pywintypes模块 import random # 启动CATIA应用 catia win32com.client.Dispatch(CATIA.Application) catia.visible1try:…

python中实现定时任务的几种方案

目录 while True: sleep()Timeloop库threading.Timersched模块schedule模块APScheduler框架Celery框架数据流工具Apache Airflow概述Airflow 核心概念Airflow 的架构 总结以下几种方案实现定时任务&#xff0c;可根据不同需求去使用不同方案。 while True: sleep() 利用whil…

【C++进阶(七)】仿函数深度剖析模板进阶讲解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 模板进阶 1. 前言2. 仿函数的概念3. 仿函数的实…

【GO 编程语言】面向对象

指针与结构体 文章目录 指针与结构体一、OOP 思想二、继承三、方法 一、OOP 思想 Go语言不是面向对象的语言&#xff0c;这里只是通过一些方法来模拟面向对象&#xff0c;从而更好的来理解面向对象思想 面向过程的思维模式 1.面向过程的思维模式是简单的线性思维&#xff0c;…

C#学生选课及成绩查询系统

一、项目背景 学生选课及成绩查询系统是一个学校不可缺少的部分&#xff0c;传统的人工管理档案的方式存在着很多的缺点&#xff0c;如&#xff1a;效率低、保密性差等&#xff0c;所以开发一套综合教务系统管理软件很有必要&#xff0c;它应该具有传统的手工管理所无法比拟的…

visual studio禁用qt-vsaddin插件更新

visual studio里qt-vsaddin插件默认是自动更新的&#xff0c;由于qt-vsaddin插件新版本的操作方式与老版本相差较大&#xff0c;且新版本不稳定&#xff0c;容易出Bug&#xff0c;所以需要禁用其自动更新&#xff0c;步骤如下&#xff1a;     点击VS2019菜单栏上的【扩展】–…

ChatGPT启蒙之旅:弟弟妹妹的关键概念入门

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

Docker Alist 在线网盘部署

文章目录 拉取镜像创建并运行查看容器自动生成的密码在浏览器中进行访问 挂载本地磁盘 拉取镜像 docker pull xhofe/alist-aria2创建并运行 # -v /data/alist:/opt/alist/data 挂载本地目录 docker run -d --restartalways -v /data/alist:/opt/alist/data -p 5244:5244 -e P…

Linux系统常用指令篇---(一)

Linux系统常用指令篇—(一) 1.cd指令 Linux系统中&#xff0c;磁盘上的文件和目录被组成一棵目录树&#xff0c;每个节点都是目录或文件。 语法:cd 目录名 功能&#xff1a;改变工作目录。将当前工作目录改变到指定的目录下。 (简单理解为进入指定目录下) 举例: cd .. : 返…

vscode 打开后 默认terminal power shell 报错 名为“.C”的驱动器不存在。

这是 默认terminal power shell 打开报的错 Test-Path : 找不到驱动器。名为“.C”的驱动器不存在。 所在位置 C:\Users\HUAWEI\Documents\WindowsPowerShell\profile.ps1:4 字符: 5 If (Test-Path "C:\Users\HUAWEI\AppData\Local\Temp\_MEI319962\Scripts\ ... …

python二次开发CATIA:文字轮廓草图

CATIA V5 版本的草图中&#xff0c;并没有文字轮廓的创建命令。通常的做法是&#xff0c;再Drawing 文件中创建所需文本-->将 Drawing 文件另存为 dwg / dxf 格式-->打开另存的文件&#xff0c;文字已转为轮廓线条-->复制线条并粘贴到草图中。 本例中&#xff0c;基于…

Hono——一个小型,简单且超快的Edges Web框架

Hono - [炎]在日语中的意思是火焰&#x1f525; - 是一个小型&#xff0c;简单且超快的Edges Web框架。它适用于任何JavaScript运行时&#xff1a;Cloudflare Workers&#xff0c;Fastly ComputeEdge&#xff0c;Deno&#xff0c;Bun&#xff0c;Vercel&#xff0c;Netlify&…

【单片机】14-I2C通信之EEPROM

1.EEPROM概念 1.EEPROM 1.1 一些概念 &#xff08;1&#xff09;一些概念&#xff1a;ROM【只读存储器---硬盘】&#xff0c;RAM【随机访问存储器--内存】&#xff0c;PROM【可编程的ROM】&#xff0c;EPROM【可擦除ROM】&#xff0c;EEPROM【电可擦除ROM】 1.2 为什么需要EE…

接口测试入门实践

简单接口搭建(表单/REST) 五步教会你写接口 首先要安装flask包: pip install flask 从flask中导入Flask类和request对象: from flask import Flask, request从当前模块实例化出一个Flask实例:appFlask(__name__)编写一个函数来处理请求 从请求对象中获取数据:arequest.values.…

LeetCode【121. 买卖股票的最佳时机】

你才不是什么小人物&#xff0c;你在我这里&#xff0c;是所有的天气和心情。 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一…