【C语言】数据存储篇,内存中的数据存储----C语言整型,浮点数的数据在内存中的存储以及大小端字节序【图文详解】

欢迎来CILMY23的博客喔,本篇为​【C语言】数据存储篇,内存中的数据存储----C语言整型,浮点数的数据在内存中的存储以及大小端字节序【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注+收藏。 

 前言

C语言中整型的存储是原码反码补码,那么浮点数的存储又是什么样的呢?本篇将以整型的数据存储开始,带大家了解C语言中数据的存储。

目录

 一、整型的存储

二、大小端字节序

三、练习题

四、浮点数的数据存储


 一、整型的存储

在C语言中,整型数据是以二进制的形式存入内存中的,那在c语言中能对二进制进行操作的有几个操作符,~ ,&,|,^,<<,>>。整数的二进制表示⽅法有三种,即原码、反码和补码,三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位最高位的⼀位是被当做符号位,剩余的都是数值位。

   符号位:

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

例如:4

它的原码,反码,补码都为

00000000 00000000 00000000 00000100

负整数的原码反码补码则表示不一样
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。 

例如以下负四这个例子: 

对于整形来说:数据存放内存中其实存放的是补码
为什么呢?
在计算机系统中,数值⼀律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统⼀处理;
同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

二、大小端字节序

虽然整型数据是按二进制存入内存的,但是在vs的编译器上却采用的是十六进制表示。

例如:

这是整型四的表示,在内存中的地址是 0x00CFFC8C

但是为什么vs的表示是04在前面的呢? 

这就涉及大小端字节序了,大小端字节序分大端字节序和小端字节序,字节序说的就是字节的顺序,当一个字节超过一个数值大小的时候,就有存储的顺序问题。内存中的存储单元是1字节的。

 大端字节序,是指数据的低位字节内容保存在内存的⾼地址处,而数据的高位字节内容,保存在内存的低地址处。

小端字节序,是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。

vs采用的是小端字节序存储

三、练习题

 3.1 如何判断机器的大小端字节序?

 思路一、通过1的二进制来判断,如果位于低地址处的1字节是01,那么是小端字节序,如果位于低地址处的1字节是00.那么是大端字节序。

    int a = 1;if (*(char*)&a == 1){printf("小端字节序");}else{printf("大端字节序");}

 图解如下:

 思路一优化:我们可以根据(char*)&a的值进行封装函数,解引用后得到1就是1,得到0就是零,

#include<stdio.h>int check_sys()
{int a = 1;return (*(char*)&a);
}int main()
{if (check_sys() == 1){printf("小端字节序");}else{printf("大端字节序");}return 0;
}

 3.2练习题1

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

 答案是:

解析: char类型比较特殊,我们没法单纯通过观察判断char类型到底是signed,还是unsigned,而在vs上,它是被认为成signed char的。 

首先char a 的内部是什么样的呢?如下图所示:

b其实也同理可得,其中存放的是八个1,那c也是如此,只是因为没有了符号位,所以这里的三个变量都存了八个1.

%d是以十进制的形式打印有符号整型,所以会对a进行整型提升,也就是将其补充成四个字节的数据

由于b 和a一样都是signed char类型,所以过程也一样

而c不一样,c由于是无符号整型

因此打印的时候是-1,-1,255

 3.3练习题2

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

%u打印无符号整数 

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

  答案如下:

补充:

char类型的取值范围,char一个字节对应八个比特位,而这八个比特位的取值又如下 所示,所以有符号的char类型取值是-128-127.

所以a当中存储的是

00000000000000000000000010000000----补码

11111111111111111111111110000000----原码

故答案为4294967168

3.4练习题3


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

 根据前面所说,其实signed类型是在兜圈子

 所以这里只要确定0的位置即可,a当中从-1开始存,存够255之后又开始新的轮回

 3.5练习题5

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

结果是死循环 

解析:

无符号char取值是0~255,所以会无限制的打印

3.5练习题4 

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

解析:

i的数据类型是unsigned int ,是恒大于等于0的,而循环的条件是i>=0,恒成立,所以会不限制的答应i的值。会从9一直开始打印,然后进入2^ 0~2^32-1. 0~4294967295

3.6练习题5 

#include <stdio.h>int main()
{int a[4] = { 1, 2, 3, 4 };int* ptr1 = (int*)(&a + 1);int* ptr2 = (int*)((int)a + 1);printf("%x,%x", ptr1[-1], *ptr2);return 0;
}

结果如下:

解析:

a是数组名,单独放在&后面,取出的是整个数组的地址,+1跳过整个数组的大小,(不理解的可以看http://t.csdnimg.cn/BlJ00)指向末尾,将其存入ptr1, ptr[-1] == *(ptr-1),将其解引用后得到的就是4。

因为数据在vs上看是小端存放,本身转换成int类型后,就是a本身的地址直接加1,然后将其转换成int*类型是四个字节,解引用后,读取要反过来,所以是20 00 00 00

四、浮点数的数据存储

常⻅的浮点数:3.14159、1E10等,浮点数家族包括:  float、double、long double 类型。

看一个例子:

#include <stdio.h>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;
}

结果如下:

那为什么会这样呢?

这就涉及浮点数的存储了。

假设

V = 5.625 

V = 101 .101 -----二进制

V = 1.011 * 2 ^2

V = (-1) ^ 0 * 1.011 * 2^2 

 其实就是先转换成二进制,然后将二进制小数点向左移动一位的同时E+1,最后将二进制化成大于等于1小于2的数。

 那根据这样的化简,我们有两种存储方式

对于32位的浮点数,最高的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M

对于64位的浮点数,最高的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

 因为最终M都会化简成1...多少的形式,所以我们只需要在内存中存储有小数点的位置即可。

我们接着看是如何存和取的:

我们存入的时候将其转换成二进制,

所以我们就可以解释第一个练习了:

 9以整型的形式存储在内存中,得到如下二进制序列:

0000 0000 0000 0000 0000 0000 0000 1001

首先,将9的二进制序列按照浮点数的形式拆分,得到第⼀位符号位s=0,后面8位的指数 E=00000000 ,
最后23位的有效数字M=000 0000 0000 0000 0000 1001。
由于指数E全为0,因此,浮点数V就写成:
    V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146) 显然,V是⼀个很小的接近于0的正数,所以用十进制小数表⽰就是0.000000。

浮点数9.0,为什么整数打印是 1091567616
首先,浮点数9.0等于二进制的1001.0,即换算成科学计数法是:1.001×2^3
所以:9.0   =   (−1) ^0 * (1.001)*2^3,
那么,第⼀位的符号位S=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130, 即10000010
所以,写成二进制形式,应该是S+E+M,即

0 10000010 001 0000 0000 0000 0000 0000 

这个32位的⼆进制数,被当做整数来解析的时候,就是整数在内存中的补码,原码正是
1091567616

感谢各位同伴的支持,本期数据存储篇就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。 

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

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

相关文章

Mysql索引优化导致死锁问题

1、背景 随着公司业务的发展&#xff0c;商品库存从商品中心独立出来成为一个独立的系统&#xff0c;承接主站商品库存校验、订单库存扣减、售后库存释放等业务。在上线之前我们对于核心接口进行了压测&#xff0c;压测过程中出现了MySQL 5.6.35死锁现象&#xff0c;通过日志发…

vscode——本地配置(C和C++环境配置)(2)

vscode——本地配置&#xff08;2&#xff09; 配置C语言编译看看.json文件编译多个C文件C/C调试 今天我们继续来看vscode的配置&#xff0c;如果没看过上一次的文章&#xff0c;大家可以点击&#xff1a; https://blog.csdn.net/qq_67693066/article/details/136315696 配置C语…

NebulaGraph入门

感谢阅读 官方文档链接NebulaGraph简介nGQLnGQL简介占位标识符和占位符值注释实列大小写区分关键字 基本概念以及相关代码实现补充说明图空间语法以及列子创建克隆官方示例代码(创建并克隆)USE语句指定图空间时查看所有SPACESPACE详情CLEAR SPACE删库跑路&#xff08;看玩笑的说…

什么是生成式人工智能?

近年来&#xff0c;人工智能取得了重大进展&#xff0c;其中发展迅速的领域之一就是生成式人工智能。生成式人工智能是人工智能和深度学习的一个子领域&#xff0c;主要使用机器学习技 术根据现有数据训练算法和模型&#xff0c;生成诸如图像、文本、音乐、视频等新内容。 要更…

LTD营销枢纽2023年度功能升级回顾

在过去的2023年&#xff0c;我们的团队致力于不断进步和创新。经过一年的不懈努力&#xff0c;我们共发布了50次的系统升级&#xff0c;引入了16种全新的解决方案与业务应用&#xff0c;并实施了1363项各类细致优化。 这些更新和改进不仅在我们的营销枢纽系统现有功能的基础上实…

【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C那些事儿 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 1. 面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符…

从零开始学PS

一、软件安装&#xff1a; 1.安装creative cloud&#xff1a; 2.下载安装PS&#xff1a; 3.下载完成&#xff1a; 二、PS主界面构成&#xff1a; 三、快捷键&#xff1a; 以下是 Photoshop 常用的 100 个快捷键&#xff1a; Ctrl N&#xff1a;新建一个文档 Ctrl O&am…

【数据结构和算法初阶(C语言)】链表-单链表(手撕详讲单链表增删查改)

目录 1.前言&#xff1a;顺序表回顾&#xff1a; 1.1顺序表的优缺点 2.主角----链表 2.1链表的概念 2.2定义一个单链表的具体实现代码方式 3.单链表对数据的管理----增删查改 3.1单链表的创建 3.2单链表的遍历实现 3.2.1利用遍历实现一个打印我们链表内容的函数的函数…

【软件测试】--功能测试4-html介绍

1.1 前端三大核心 html:超文本标记语言&#xff0c;由一套标记标签组成 标签&#xff1a; 单标签&#xff1a;<标签名 /> 双标签:<标签名></标签名> 属性&#xff1a;描述某一特征 示例:<a 属性名"属性值"> 1.2 html骨架标签 <!DOC…

Java基础八股

基础概念与常识 Java 语言有哪些特点? 简单易学&#xff1b;面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&#xff1b;支持多线程&#xff08; C 语言没有内置的多线程…

Ansible自动化运维(四)jinja2 模板、Roles角色详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

Retrofit核心原理

Retrofit是一个类型安全的HTTP客户端库&#xff0c;广泛用于Android和Java应用中&#xff0c;用于简化网络请求和响应的处理。本文将深入探讨Retrofit的核心原理&#xff0c;帮助开发者理解其背后的工作机制。 Retrofit简介 Retrofit是Square公司开发的一个开源库&#xff0c…

非线性优化资料整理

做课题看了一些非线性优化的资料&#xff0c;整理一下&#xff0c;以方便查看&#xff1a; 优化的中文博客 数值优化|笔记整理&#xff08;8&#xff09;——带约束优化&#xff1a;引入&#xff0c;梯度投影法 (附代码)QP求解器对比对于MPC的QP求解器 数值优化| 二次规划的…

Socket网络编程(一)——网络通信入门基本概念

目录 网络通信基本概念什么是网络&#xff1f;网络通信的基本架构什么是网络编程?7层网络模型-OSI模型什么是Socket&#xff1f;Socket的作用和组成Socket传输原理Socket与TCP、UDP的关系CS模型(Client-Server Application)报文段牛刀小试&#xff08;TCP消息发送与接收&#…

nebula容器方式安装:docker 安装nebula到windows

感谢阅读 基础环境安装安装docker下载nebula 安装数据库命令行安装查询network nebula-docker-compose_nebula-net并初始化查询安装初始使用root&#xff08;God用户类似LINUX的root&#xff09; 关闭服务 安装UI 基础环境安装 安装docker 点我下载docker 下载nebula 数据…

柯桥会计培训学校,会计职称考试,考中级会计怎么证明工作年限?

中级会计考试是会计从业人员的重要考试之一&#xff0c;对于中级考生来说&#xff0c;工作年限证明是必不可少的一步。因此&#xff0c;在考中级会计之前&#xff0c;需要对如何证明工作年限进行了解和掌握。 为大家整理了工作年限证明相关信息&#xff0c;一起来看看吧~ 一、…

手把手教你使用python中的循环for和while

python中的for循环是一个通用的序列迭代器&#xff0c;可以遍历任何有序的序列对象内部的元素&#xff0c;&#xff08;注意是遍历&#xff09;&#xff0c;也就是说循环的方式一开始就固定好了&#xff0c;本质上是遍历。 python&#xff1a;代码 count 0for i in range(8):…

挑战杯 基于YOLO实现的口罩佩戴检测 - python opemcv 深度学习

文章目录 0 前言1 课题介绍2 算法原理2.1 算法简介2.2 网络架构 3 关键代码4 数据集4.1 安装4.2 打开4.3 选择yolo标注格式4.4 打标签4.5 保存 5 训练6 实现效果6.1 pyqt实现简单GUI6.3 视频识别效果6.4 摄像头实时识别 7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xf…

【代码解读】OpenCOOD框架之model模块(以PointPillarFCooper为例)

point_pillar_fcooper PointPillarFCooperPointPillarsPillarVFEPFNLayerPointPillarScatterBaseBEVBackboneDownsampleConvDoubleConv SpatialFusion检测头 &#xff08;紧扣PointPillarFCooper的框架结构&#xff0c;一点一点看代码&#xff09; PointPillarFCooper # -*- c…