C语言-----数据在内存中的存储(1)
1.整数在内存中的存储
我们之前就了解过整数的二进制写法分别有3种,分别为原码,反码,补码。整型在内存中存储的是补码。
原码,反码,补码都有自己的符号位和数值位,符号位为1时,则表示负数,符号位为0时,则表示正数。
注意:
正数的原码,反码,补码相同。
而负数的原码,反码,补码是不一样的。
负数的原码就是将其数字转换为二进制,得到原码。
对原码除符号位外的数值位进行取反,得到反码。
反码+1 得到补码。
以上是有负数的原码得到其补码的过程。
由负数的补码得到原码也可以通过 对补码进行取反加1得到其原码。
2.大小端字节序和字节序判断
我们先看一段简单的代码
如下图
变量a原本设置的是0x11223344,可通过vs编译器调试发现,其在内存中的存储顺序恰好是反过来的。
这是为什么呢?
这就涉及到来大小端字节序的问题。
2.1 大小端的含义
首先我们要清楚当储存的数据大小超过一个字节时,其在内存中的存储顺序就有了大端字节序存储和小端字节序存储。
1.大端字节序存储:是指数据的低字节内容保存在内存中的高地址处,而高细节内容保存在内存中的低地址处。
如图,11相对于22来说,11是高字节内容,22是低字节内容。
所以将11放在低地址处,22放在放在高地址处。33和44依此类推。
2. 小端字节序存储:是指数据的低字节内容保存在内存中的低地址,而高字节内容保存在内存中的·高地址处。
如图
通过以上了解的内容可知,为什么数据在vs中调试,在内存中的存储顺序是倒过来的。
原因是vs是小端字节序存储。
2.2 判断大小端字节序
虽然我们知道了vs是小端字节序存储,那我们如何来证明呢?
我们可以通过代码来实现
int system()
{int a = 1;char* p = &a;return *p;
}
int main()
{int ret = system();if (ret == 1){printf("小端字节序存储");}else{printf("大端字节序存储");}return 0;
}
看图
如上图所示,a的16进制位分别在大端字节序和小端字节序的顺序排序。
我们又设计了一个char* p指针来存储a,所以p指向了a的第一个字节的内容,当我们对p进行解引用时,一次也只能访问一个字节,而一个字节恰好是2个16进制位。
返回*p的值,用ret来保存*p,我们就可以通过ret的值来判断大小端字节序存储了。
当返回值位1时,是小端字节序存储,返回值位0时,是大端字节序存储。
用vs运行代码
3.练习题
接着来几道练习题巩固一下知识。
练习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;
}
我们一开始看到该题可能会有点蒙,不过别慌张,我们分析下代码。
该题创建了 a,b,c 三个变量,分别是char ,signed char, unsigned char 类型。
这时很疑惑,明明是 -1 是个整型数据,却用了一个不符合整型类型的变量来存储。
但这是允许的。只不过会发生数据的截断,影响最终打印的结果。
这种题思路是一样的。
我们先以a为例
我们先把 -1 的原码写出来,为1000000000000000000000000001,
在对其取反,为 11111111111111111111111111111110,得到反码。
在对反码加1得到补码,为11111111111111111111111111111111,便是-1的补码。
我们知道整型数据在内存中是以补码的形式存储的,但是由于变量a是char类型的,所以a只能存储一个字节大小的数据,也就是8个比特位。则会发生数据的截断。
优先截断低字节的数据,这时便会截断8个比特位的内容存储到a中。
则这时a中存储的是11111111
(补充:char类型是signed类型的还是unsigned类型的是取决于编译器的,再vs中char默认为是signed char 类型的。)
最后我们要以整型打印,所以要对a进行整型提升。
(整型提升规则:有符号数据补符号位,无符号数据不0)
由于a是signed char 型,属于有符号型,则对a进行整型提升后为:
11111111111111111111111111111111
整型提升后得到的还是补码。所以我们要求出其原码。
接着对补码进行取反+1的操作的到原码:
10000000000000000000000000000001
由于是以%d的形式打印,也就是将a看作有符号数据,所以此时的最高位为符号位。
通过原码计算可知,最终a的值为 -1。
接着来分析b
由于b的类型和a在vs中的数据类型是一样的,并且赋值都为-1,所以和以上a的推算是一模一样的。
最后来分析c
一样的步骤,把 -1 的原码写出来 , 为 1000000000000000000000000001(原码)
接着对原码取反,为 11111111111111111111111111111110 (反码)
反码加1得到补码,为 11111111111111111111111111111111(补码)
也由于 c 是unsigned char 类型的,只能存储一个字节大小的数据,也就是8个比特位。
则发生截断
这时c存储的是11111111。
接着对其进行整型提升,由于c是unsigned char 类型,则此时最高位不是符号位了,所以补0.
得到 00000000000000000000000011111111 ,此时得到的也是补码。
但由于c是无符号数据,则原码,反码,补码,相同。
通过原码计算得 c为255。
运行代码
练习2
#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;
}
一开始看到这道题,是肯定会懵一下的。不过别慌张,冷静分析。
这里涉及到一个循环,后面有涉及到了一个strlen的计算,我们知道strlen计算的是 '/0' 之前的长度。而 \0 的ASCII值为0,所以计算的是0之前的长度。
遇到这种题,有一个圆形图解法。下面是char 的圆图。
如上图,我们对二进制的+1弄成一个圆,也就是循环了。
由于题目是减1,那就反过来,则0的前面就有255个,则长度就为255.
运行代码,如下图,也是255.
练习3
#include <stdio.h>
unsigned char i = 0;
int main()
{for(i = 0;i<=255;i++){printf("hello world\n");}return 0;
}
这也可以根据圆形图解法来解决,不过是unsigned char 类型的圆
由此得出 i 的 取值范围 0~255,所以 i 永远小于等于255,则循环条件恒成立,这样就会现如死循环。
练习4
#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;
}
这道题是有点复杂的,我们还是冷静分析。
线分析ptr1,如下图
由上图轻易得到ptr[-1]为4。
难点就在ptr2
我们知道数组名在大部分就是条件下是首元素地址,所以此时a是首元素地址 ,但是被强制转换成int 类型了,强制转换成 int 型后进行加1,我们知道整型加1和整数加1的道理差不多,这时加1就是跳过了1个字节。我们将数组的内容转换成16进制的形式。
上面分析得知,整型加1就是跳过一个字节,而2个16进制位就是一个字节。而a中又是int类型的,存了4个字节的数据。如下图所示
但又因为在vs中是小端字节序存储,所以我们要将ptr2还原。
还原得到 02000000。
运行代码,如下图
相关文章:

C语言-----数据在内存中的存储(1)
1.整数在内存中的存储 我们之前就了解过整数的二进制写法分别有3种,分别为原码,反码,补码。整型在内存中存储的是补码。 原码,反码,补码都有自己的符号位和数值位,符号位为1时,则表示负数&…...

Ribbon有哪些负载均衡策略
负载均衡类都实现了IRule接口。 RandomRule:随机的选用一个实例 RoundRobinRule:轮询的使用实例 RetryRule:在轮询的基础上加了一个错误重试机制,在deadline时间内会不断的重试 WeightResponeTimeRule:根据权重去做…...
websocket多级nginx代理
在使用多层Nginx代理时,WebSocket的连接可能会遇到一些问题,因为WebSocket连接是持久化的,它需要Upgrade头部来确认升级到WebSocket协议。在多层代理的情况下,每层代理可能会修改或丢失这个Upgrade头部信息。 为了确保WebSocket能…...

【python从入门到精通】-- 第四战:语句汇总
🌈 个人主页:白子寰 🔥 分类专栏:python从入门到精通,魔法指针,进阶C,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~ 💡 坚持创作博文…...
【NC50937】货仓选址
题目 货仓选址 二分,前缀和,数学推导 思路 由题意可知货仓的位置是可以和商店的位置重合的。首先应该将商店的坐标从小到大排序,然后假设商店的坐标为 a i a_i ai,货仓的坐标为 x x x,货仓左侧第一家商店&#x…...
Nginx配置使用笔记
Nginx配置使用笔记 前言 官网下载压缩包https://nginx.org/ 解压完成后当前目录cmd输入nginx指令启动 访问http://localhost:80确认启动成功 1.部署前端项目 部署前端项目到路径E:\Workspaces\Vscode\app-web 2.0配置nginx.conf文件 在nginx安装的conf目录下新建一个文件夹l…...

GridLayoutManager 中的一些坑
前言 如果GridLayoutManager使用item的布局都是wrap_cotent 那么会在布局更改时会出现一些出人意料的情况。(本文完全不具备可读性和说教性,仅为博主方便查找问题) 布局item: <!--layout_item.xml--> <?xml version"1.0&qu…...

算法实验二 矩阵最小路径和 LIS
算法实验课二 矩阵最小路径和 leetcode裸题 最小路径和 给定一个包含非负整数的 *m* x *n* 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 示例 1: 输入&…...

Apache Paimon实时数据糊介绍
Apache Paimon 是一种湖格式,可以使用 Flink 和 Spark 构建实时 数据糊 架构,用于流式和批处理操作。Paimon 创新地将湖格式和 LSM(日志结构合并树)结构相结合,将实时流式更新引入湖架构中。 Paimon 提供以下核心功能: 实时更新: 主键表支持大规模更新的写入,具有非常…...

计算机网络:数据链路层 - 可靠传输协议
计算机网络:数据链路层 - 可靠传输协议 可靠传输概念停止-等待协议 SW回退N帧协议 GBN选择重传协议 SR 可靠传输概念 如下所示,帧在传输过程中受到干扰,产生了误码。接收方的数据链路层,通过真伪中的真检验序列 FCS 字段的值&…...

苍穹外卖07(缓存菜品,SpringCache,缓存套餐,添加购物车菜品和套餐多下单,查看购物车,清除购物车,删除购物车中一个商品)
目录 一、缓存菜品 1 问题说明 2 实现思路 3 代码开发:修改DishServiceImpl 4 功能测试 二、SpringCache 1. 介绍 2. 使用语法 1 起步依赖 2 使用要求 3 常用注解 4 SpEL表达式(了解备用) 5 步骤小结 3.入门案例 1 准备环境 2 使用入门 1 引导类上加…...

C语言第三十八弹---编译和链接
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 编译和链接 1、翻译环境和运行环境 2、翻译环境 2.1、预处理(预编译) 2.2、编译 2.2.1、词法分析 2.2.2、语法分析 2.2.3、语义分…...

无人售货奶柜:开启便捷生活的新篇章
无人售货奶柜:开启便捷生活的新篇章 在这个快节奏的现代生活中,科技的革新不仅为我们带来了前所未有的便利,更在不经意间改变着我们的日常。其中,无人售货技术的出现,尤其是无人售货奶柜,已经成为我们生活…...
STM32为什么不能跑Linux?
STM32是一系列基于ARM Cortex-M微控制器的产品,它们主要用于嵌入式系统中。而Linux则是一个开源的类Unix操作系统,主要面向的是桌面电脑、服务器等资源丰富的计算机。虽然理论上可以将Linux移植到STM32上运行,但是由于两者之间存在着很多技术…...
Dubbo 3.x源码(18)—Dubbo服务引用源码(1)
基于Dubbo 3.1,详细介绍了Dubbo服务的发布与引用的源码。 此前我们学习了Dubbo的服务导出的源码,在DubboBootstrapApplicationListener#startSync方法中,在调用了exportServices方法进行服务导出之后,立即调用了referServices方法…...
设计模式:工厂模式和抽象工厂模式的区别
定义 工厂模式(Factory Pattern)通常指的是工厂方法模式(Factory Method Pattern),它定义了一个创建对象的方法,由子类决定要实例化的类。工厂方法让类的实例化推迟到子类。 抽象工厂模式(Abstract Factory Pattern)提供了一个接口,用于创建相关或依赖对象的家族,而…...
python面试题(36~50)
36、如何取一个整数的绝对值? 这可以通过abs函数来实现。 abs(2) #> 2 abs(-2) #> 2 37、如何将两个列表组合成一个元组列表? 可以使用zip函数将列表组合成一个元组列表。这不仅仅限于使用两个列表。也适合3个或更多列表的情况。 a [a,b,c] b [1,2,3] [(k,v) fo…...

Vue 样式技巧总结与整理[中级局]
SFC(单文件组件)由 3 个不同的实体组成:模板、脚本和样式。三者都很重要,但后者往往被忽视,即使它可能变得复杂,且经常导致挫折和 bug。 更好的理解可以改善代码审查并减少调试时间。 这里有 7 个奇技淫巧…...

cesium加载.tif格式文件
最近项目中有需要直接加载三方给的后缀名tif格式的文件 <script src"https://cdn.jsdelivr.net/npm/geotiff"></script> 或者 yarn add geotiff npm install geotiff 新建tifs.js import GeoTIFF, { fromBlob, fromUrl, fromArrayBuffer } from geotif…...

分布式全闪占比剧增 152%,2023 年企业存储市场报告发布
近日,IDC 发布了 2023 年度的中国存储市场报告。根据该报告,在 2023 年软件定义存储的市场占比进一步扩大,分布式全闪的增长尤其亮眼,其市场份额从 2022 年的 7% 剧增到 2023 年的 17.7%,增长了 152%。 01 中国企业存…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...

Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...