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

C语言--数据的存储2

目录

  • 前言
  • 练习
    • 有符号类型与无符号类型
    • char类型的取值范围
      • 有符号char
      • 无符号char
    • 有符号与无符号类型混合运算
    • 有符号无符号类型形成的bug
    • char类型取值范围应用
  • 浮点型在内存中的存储
    • 浮点数的存储
    • 浮点数存储规则
    • 浮点数取出规则

前言

上篇文章我们讲解了数据类型,类型的基本归类,整形在内存中的存储方式以及大小端的知识,本篇文章我们来继续加深数据在内存中存储形式的理解。

练习

有符号类型与无符号类型

我们来看一个例子,看下面这段代码输出是什么:

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

我们在编译器里运行这段代码,结果如图1
图1
我们先来分析a

char a=-1
10000000000000000000000000000001 --原码
11111111111111111111111111111110 --反码
11111111111111111111111111111111 --补码
11111111 --char类型只能存储1个字节(8个比特位)

b,c和a的补码其实一样,都是11111111,只不过一个是有符号的char,一个是无符号的char。
所以对于b来说,第一个1是符号位,而对于c来说,这8个1全都是有效数字
因为我们要以%d的形式打印,所以要对a,b,c进行整形提升

a:11111111
整形提升:11111111111111111111111111111111 --补码11111111111111111111111111111110 --反码10000000000000000000000000000001 --原码

所以a打印出来还是-1。
b与a类似,只是添加了一个有符号前缀,效果是一样的。我们来分析c

c:11111111
整形提升:00000000000000000000000011111111 --补码(原码)

因为符号位为0,所以原反补码相同,所以c打印出来就是11111111==255。

补充:
1,char到底是signed char还是unsigned char?
C语言标准没有明确的规定,取决于编译器
2,int 是默认 signed int

char类型的取值范围

有符号char

来看下面这段代码

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

运行结果如图2
图2
为什么会出现这样一个奇怪的数字呢?我们来分析一下

char a=-128
1000000000000000000000010000000 --原码
1111111111111111111111101111111 --反码
1111111111111111111111110000000 --补码
10000000 --截断
1111111111111111111111110000000 --整形提升(补码)

因为%u是打印无符号整数,所以编译器会把整型提升后的补码全部当作有效数字,那么原反补码相同,打印的就是补码。如果是打印%d,就还需要求出原码。
我们接着再来看下面这段代码

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

代码运行结果如图3
图3

char a=-128
0000000000000000000000010000000 --原码
0111111111111111111111101111111 --反码
1111111111111111111111110000000 --补码
10000000 --截断
1111111111111111111111110000000 --整形提升(补码)

我们发现,截断以后的值和-128是一样的,所以最终结果也相同。
图4
我们通过图中分析可知,有符号char类型的取值范围为-128~127,为什么没有128呢
我们再来看一个图
图5
我们发现127再加1,即01111111加1变为10000000,会被直接解读为-128,所以放128进去会被解读成一个负数。

无符号char

如图6
图6
和无符号不同的是,最高位也被当作有效数字计算,所以无符号char取值范围为0~255

有符号与无符号类型混合运算

我们还是来看下面这段代码

int main()
{int i = -20;unsigned int j = 10;printf("%d\n", i + j);return 0;
}

运行结果如图7
图7
为什么会得到这样一个结果呢?我们还是来从原反补码方向分析

int i=-20
100000000000000000010100 --原码
111111111111111111101011 --反码
111111111111111111101100 --补码
unsigned int j=10
000000000000000000001010 --原码=反码=补码
printf("%d\n", i + j)
111111111111111111101100+000000000000000000001010
=11111111111111111111111111110110 --补码11111111111111111111111111111101 --反码10000000000000000000000000000010 --原码(-10)

所以打印出来的结果为-10。

有符号无符号类型形成的bug

我们来看下面这段代码

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

最终运行结果是死循环,这是因为无符号整形i的值是恒大于0的,这样i>=o就恒成立了,最终导致陷入死循环。

再来看一段代码

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

运行结果同样是死循环,因为i是无符号char类型,取值范围为0~255,这样i<=255恒成立,最终也是进入死循环

char类型取值范围应用

我们来看这段代码

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

代码运行结果如图8
图8
我们借助图5来进行分析,来看图9
图9
求字符串长度的strlen在访问到\0停止。而\0的ascll码值为0,即访问到0为止,所以在第一个0出现前一共有128+127=255个元素,所以字符串长度为255。

浮点型在内存中的存储

浮点数家族包括: float、double、long double 类型。
浮点数表示的范围:float.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;
}

运行结果如图10
图10
我们发现运行结果和我们预期相差甚远,接下来我们来具体分析。

我们首先来看四种情况的产生环境,第一种和第四种分别是以***整形的形式存储,以整形的形式打印,以浮点型的形式存储,以浮点型的形式打印,***所打印出来的结果和我们预期基本相同,而第二种和第三种都是整形和浮点型杂糅在一起存储打印,结果和预期相差甚远,由此可见浮点型存储方式和整形存储方式肯定是有所不同的

所以想弄清楚上述代码如何运行的,我们首先要来了解浮点型的存储方式

浮点数存储规则

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
---->(-1)^S * M * 2^E
---->(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
---->M表示有效数字,大于等于1,小于2。
---->2^E表示指数位。
我们来对一个浮点数进行转换,如图11
图11
那么S,E,M在内存中具体是怎么储存的呢?
32位机器:
图12
64位机器:
图13
S占一个比特位这个比较好理解,因为S不是0就是1,所以只用一个比特位来存储即可。

而对于M,因为我们知道M是恒大于1小于2的,所以他的形式永远都是1.xxxxxxx…,所以根据IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字,可以多提高一位的精度。

至于指数E,情况就比较复杂。
首先,E为一个无符号整数(unsigned int)
这意味着,如果E为8位,它的取值范围为0 ~ 255,如果为11位,它的取值范围为0 ~ 2047。但是,我们知道,科学计数法中的E是可以出现负数的,
如图14
图14

所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127(比如要存-1,其实要存-1+127=126);对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即
10001001。

我们还是以5.5为例

1010.1 --转换为二进制
101.1=1.011*2^2
S=0 M=1.011 E=2
转换:
S=0 M=011 E=2+12732位机器存储
0100 0000 1011 0000 0000 0000 0000 0000
//40 b0 00 00(16进制存储)

浮点数取出规则

指数E从内存中取出可分为三种情况
1,E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将
有效数字M前加上第一位的1。
比如:
0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为
1.0*2^(-1),其阶码为-1+127=126,表示为
01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进
制表示形式为:

0 01111110 00000000000000000000000

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

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

下面我们在来解决一开始的那段代码。

int n = 9;float* pFloat = (float*)&n;printf("*pFloat的值为:%f\n", *pFloat);

图15

*pFloat = 9.0;printf("num的值为:%d\n", n);printf("*pFloat的值为:%f\n", *pFloat);

图16
通过以上分析就可得出编译器中得出的结果
图17

以上就是关于数据的存储的全部内容了,如有出入,欢迎指正。

相关文章:

C语言--数据的存储2

目录前言练习有符号类型与无符号类型char类型的取值范围有符号char无符号char有符号与无符号类型混合运算有符号无符号类型形成的bugchar类型取值范围应用浮点型在内存中的存储浮点数的存储浮点数存储规则浮点数取出规则前言 上篇文章我们讲解了数据类型&#xff0c;类型的基本…...

Ubuntu 安装 Qt5.7.0

下载 地址&#xff1a;https://download.qt.io/https://download.qt.io/ 文件夹说明&#xff1a; snapshots&#xff1a;预览版&#xff0c;该文件夹中包含最新的测试版本。 online&#xff1a;在线安装包。 official_releases&#xff1a;最终发布版。 new_archive&#…...

“世界”的伊利,“三难”的潘刚

&#xff08;图片来源于网络&#xff0c;侵删&#xff09; 来源 | 螳螂观察 文 | 叶小安 一棵草&#xff0c;一头牛&#xff0c;到一杯牛奶&#xff0c;乳品如何守住舌尖上的安全&#xff1f; 央视财经频道专访中&#xff0c;伊利集团董事长兼总裁潘自信满满地介绍了现代智…...

【新】华为OD机试 - 开心消消乐(Python)

开心消消乐 题目 给定一个 N 行 M 列的二维矩阵,矩阵中每个位置的数字取值为 0 或 1,矩阵示例如: 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1现需要将矩阵中所有的 1 进行反转为 0,规则如下: 当点击一个 1 时,该 1 被反转为 0,同时相邻的上、下、左、右,以及左上、左下、右上…...

山东大学2022-2023数据仓库挖掘期末考题回忆

2023.2.14 一、 1.数据预处理的过程和解决问题 2.什么是离群点&#xff0c;检测离群点的四个方法 3.数据仓库的四个特点&#xff0c;画出数据仓库结构图 4.维度归约的两个方法及区别。 二、 两个模型用来预测新冠病毒的阳性和阴性 1.分别求准确率&#xff0c;精确率&#xff0c…...

SSM整合

SSM整合 ContextLoaderListener Spring提供了监听器ContextLoaderListener&#xff0c;实现ServletContextListener接口&#xff0c;可监听 ServletContext的状态&#xff0c;在web服务器的启动&#xff0c;读取Spring的配置文件&#xff0c;创建Spring的IOC容器。 web 应用中…...

Android平台版本所对应的 API 级别

平台版本API级别版本号备注Android 1333TIRAMISU平台亮点Android 1232S_V2平台亮点31S平台亮点Android 1130R平台亮点Android 1029Q平台亮点Android 928P平台亮点Android 8.127O_MR1平台亮点Android 8.026O平台亮点Android 7.1.1Android 7.125N_MR1平台亮点Android 7.024N平台亮…...

入职字节外包一个月,我离职了

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…...

中创教育PMP分享,复盘没效果?该怎么办

复盘的清单框架 一、现在情况如何 二、当初是怎么决定的 三、让我们再审视下思考的前提 四、复盘他人 复盘没效果&#xff0c;我们可以试试下面的提问&#xff1a; 一、现在情况如何 现在做到什么程度? 当时定的目标是多少? 现在的结果和目标对比处于什么状态? 有没…...

Kubelet监控指标说明

Probe路径 含义&#xff1a;kubelet以及kubelet监控的Pod的存活性请求路径&#xff1a;“/metrics/probes”指标 名称类型含义upGauge服务是否存活prober_probe_totalCounter按结果计算容器的活动探测、就绪探测或启动探测的累计数目以及存活性结果 Metrics路径 含义&#x…...

python中的数据类型(价值6980的全能工程师课程笔记)

概述 python数据类型主要分为以下七大类: Numbers(数字) Boolean(布尔) String(字符串) List(列表) Tuple(元组) Dictionary(字典) Set(集合) Python 的七个标准数据类型中: 不可变数据类型(4 个):Number(数字)、Boolean(布尔)、String(字符串)、T…...

Tomcat 配置IPV6

文章目录一、场景二、tomcat开启ipv6三、ipv6环境配置四、访问总结一、场景 我们在linux下安装一个tomcat&#xff0c;启用ipv6的方式&#xff0c;然后在windows下用浏览器访问这个tomcat 二、tomcat开启ipv6 在server.xml配置文件的里面加上 address”[::]” &#xff0c;这…...

JavaEE——MyBatis的简单介绍和使用

MyBatis是什么 MyBatis是一个支持普通SQL查询&#xff0c;存储过程以及高级映射的持久层框架&#xff0c;他消除了几乎所有的JDBC代码和参数的手动设置以及对结果集的检索&#xff0c;使用简单的XML或注解进行配置和原始映射&#xff0c;将接口和Java的POJO映射成数据库中的记…...

主数据管理平台如何进行模型管理

企业管理主数据&#xff0c;模型管理尤为重要。在对主数据进行建模操作时&#xff0c;既要保证数据通用性、安全性&#xff0c;又要符合企业的业务需求。今天小亿带你认识一下亿信华辰睿码主数据管理平台里的主数据模型管理。 主数据模型分类 一款专业的主数据管理平台&#…...

在 Kubernetes 上运行《我的世界》

最近给小朋友装上了叨叨许久的 Minecraft&#xff08;我的世界&#xff09;&#xff0c;为了体验安装的是开源启动器 HMCL。其实这游戏我也关注比较久了&#xff0c;不过感觉太耗时间。但被小朋友拉上一起玩&#xff0c;便研究了下自建服务器。GitHub 发现已经有人做好了 Minec…...

万字长文掌握Python高并发

文章目录0 前言1 并发、并行、同步、异步、阻塞、非阻塞1.1 并发1.2 并行1.3 同步1.4 异步1.5 阻塞1.6 非阻塞2 多线程2.1 Python线程的创建方式2.1.1 方式一2.1.2 方式二 继承Thread2.1.3 通过线程池创建多线程2.2 聊聊GIL2.2.1 Python线程与操作系统线程的关系2.3 线程同步2.…...

高性能办公娱乐迷你主机——Maxtang大唐AMD5600U

今天给大家介绍一款AMD5600U迷你主机&#xff0c;说起这款处理器大家应该并不陌生&#xff0c;像联想小新、YOGA以及ThinkBook等很多款用的都是这个型号&#xff0c;不过笔记本的价格基本都在3999-4999这个价位区间&#xff0c;同样的处理器&#xff0c;笔记本卖那么贵&#xf…...

牛客教你用雇主品牌力抢人才!附6类校招玩法

最新校招数据显示&#xff0c;79%的应届生在Offer抉择时首要考量薪资福利。但谈钱多伤感情啊~牛客从100案例中挑出6种最潮的校招雇主品牌玩法&#xff0c;助力你抢人才。01、英特尔中国&#xff1a;“芯”动小镇雇主是否能让自己产生激情和热情&#xff0c;已经成为应届生选择O…...

leaflet: 鼠标mouseover显示城市信息,mouseout隐藏信息(067)

第067个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中显示城市信息,这里给marker添加鼠标事件,用到了mouseover和mouseout,用于控制信息的显示和隐藏。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码…...

docker部署springboot项目

1、创建放置项目jar包和Dockerfile的文件夹 cd usr/ mkdir reggie cd reggie/ 2、上传Dockerfile和项目jar包 Dockerfile内容如下&#xff1a; # 基础镜像使用java FROM java:8 # 作者 MAINTAINER chenxiansheng # VOLUME 指定了临时文件目录为/tmp。 # 其效果是在主机 /v…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...