C语言之数据在内存中的存储(1),整形与大小端字节序


目录

前言

一、整形数据在内存中的存储

二、大小端字节序

三、大小端字节序的判断

四、字符型数据在内存中的存储

总结



前言

     本文主要讲述整型包括字符型是如何在内存中存储的,涉及到大小端字节序这一概念,还有如何判断大小端,希望对大家有所帮助


❤️感谢支持,点赞关注不迷路❤️


(本文内容涉及到整形提升,如不了解,主页中可查看详细,两篇结合起来看更深入)

一、整形数据在内存中的存储

我们都知道。整数的2进制表示有3种,即原码、反码、补码

     

有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表 示“负”,最高位的一位是被当做符号位,剩余的都是数值位。

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

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

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

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

为什么呢?

     

在计算机系统中,数值⼀律用补码来表示和存储。 原因在于,使用补码,可以将符号位和数值域统一处理; 同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的(都是取反加1),不需要额外的硬件电路。

(主页·位操作符有详细举例)


二、大小端字节序

运行以下代码,在vs(32位)调试窗口观察其在内存中的存储情况

#include <stdio.h>

int main()
{
	int a = 0x11223344;

	return 0;
}

内存调试窗口:

(0x0058FB3C是a在内存中的首地址)

发现:a = 0x11223344,它在内存中存储的却是 44 33 22 11,是倒着存储的。相信我们平时调试的时候肯定会有这样的疑问,这就涉及到了大小端字节序了。

什么是大小端?

其实超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下面是具体的概念:

  • 大端(存储)模式: 是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。
  • 小端(存储)模式: 是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。

解释说明:例如上面的 a = 0x11223344,我们按照数学方式读这个数时,44是不是个位和十位。它相比于前面的 112233 是不是算低位。44 就是一个低位字节内容,VS是以小端模式存储数据的,所以 44 就存储在内存的低地址处,其余的就按顺序往高处存储,这样我们看到的就是 44 33 22 11了。那么假如我们用的是大端模式存储数据的,那么我们看到的就是 11 22 33 44 ,11在内存中对应的是低地址,44 是高地址。

为什么有大小端?

为什么会有大小端模式之分呢?

    

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

     

例如:⼀个 16bit 的 short 型 x ,在内存中的地址为 0x0010,x 的值为 0x1122 ,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址处,即0x0010中,0x22放在高地址处,即0x0011中。小端模式,刚好相反。我们常用的X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。


三、大小端字节序的判断

判断大小端其实很简单,定义 int a = 1,16进制为 0x 00 00 00 01,我们只需要访问其首地址对应的字节内容即可,小端会以 0x 01 00 00 00 从低地址往高地址排放,大端会以 0x 00 00 00 01 从低地址往高地址排放。

如下,一小段代码即可:

#include <stdio.h>

int check_sys()
{
	int a = 1;

	return *(char*)(&a);
}

int main()
{
	int ret = check_sys();

	if (ret == 1)
	{
		printf("小端\n");
	}
	else if (ret == 0)
	{
		printf("大端\n");
	}

	return 0;
}

运行结果(VS):


四、字符型数据在内存中的存储

字符型其实也属于整形范畴,存储的是其ASCII码值。

我们可以先观察以下代码:

#include <stdio.h>

int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;

	printf("a=%d, b=%d, c=%d\n", a, b, c);

	return 0;
}

运行结果:

解疑:

  1. 首先我们知道,字符型变量以%d打印时是要发生整形提升的。
  2. 然后a为char类型,vs中,char类型默认为有符号字符型,也就是等同于 signed char,所以a整形提升是要看符号位的,-1的补码是11111111 11111111 11111111 11111111,a大小只有一个字节,存储时会发生截断取后8位,a其补码为11111111,整形提升后 11111111 11111111 11111111 11111111,以%d打印的是原码,再转为原码为10000000 00000000 00000000 00000001,因此打印的还是-1
  3. b与a一样,然后就是c,c是无符号字符形,c的补码还是1111111,整形提升,无符号整形提升高位补0,也就是 00000000 00000000 00000000 11111111,再转为原码,因为是无符号整形,原反补相同,所以原码还是 00000000 00000000 00000000 11111111,打印出来就是255。


在看这段代码:

#include <stdio.h>

int main()
{
	char a = -128;

	printf("%u\n", a);
	printf("%d\n", a);

	return 0;
}

运行结果:

解疑:

  1. 我们发现以%u(无符号整形)方式打印时,打印出的是一个非常大的数字,以%d打印还是原数值,那么为什么会这样呢
  2. 首先,a以%u打印时,还是会发生整形提升,-128有点大,我们先算出-128的原码为  10000000 00000000 00000000 10000000,取反加1算出-128的补码为 11111111 11111111 11111111 10000000,截断后 a 的补码就是10000000,以%u打印,虽然是以无符号整形打印,但是整形提升时是根据原类型进行提升的,原类型为char,有符号字符型,所以高位补符号位1,即 11111111 11111111 11111111 10000000。然后%u就发挥作用了,要把整形提升后的这个补码看成无符号整形,这时候原反补就相同,原码就是 1111111 11111111 11111111 10000000,打印出来的结果就是上图中很大的数字,我们可以借助计算器验证:
  3. 以%d打印时接着2中整形提升后的补码 11111111 11111111 11111111 10000000,这里是以%d打印,所以要看成有符号的整形,其原码就要进行取反加1,即 10000000 00000000 00000000 10000000,打印出来就是-128


再看这段代码:

#include <stdio.h>

int main()
{
	char a = 128;

	printf("%u\n", a);
	printf("%d\n", a);

	return 0;
}

运行结果:

解疑:

  1. 我们发现128的结果与-128的结果相同,这又是为什么
  2. 其实我们自己再重新算一下就会发现,a存储时补码都是 10000000,因为128与-128的补码后8位是完全相同的,截断时值就相同。算一个特殊情况,因为a的值相同,所以后续以%u或者%d打印时效果也相同。


通过以上例题,我们可以再推导一下char型变量(有符号)的存储范围为啥是 -128~127了,还有 unsigned char 为啥是 0~255

我们画图分析:

如此,我们可以画成一个圆:

这就是 char 类型为什么存储范围是-128~127,哪怕赋值的数字超过这个范围,也会被截断在这个范围内。

这就是unsigned char 存储范围为什么是0~255。

其实,signed short 和 unsigned short 类型数据也可以画圆圈表示,int也可以,这里如果感兴趣可以自己画着试试。同上即可


 

总结

        以上就是本文的全部内容,希望对你有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python极速入门笔记(三)

1. 函数 #定义函数""" def 函数名&#xff08;参数&#xff09;:...return ** """ def calc_BMI(weight,height):BMIweight/(height**2)if BMI<18.5:category"偏瘦"elif BMI<25:category"正常"elif BMI<30:catego…

红外光气体检测:1.分子振动与红外吸收、检测系统的基本模型和红外敏感元件

分子振动与红外吸收 分子偶极矩的变化频率与分子内原子振动状态有关&#xff1a;μqd&#xff0c;其中μ是偶极矩&#xff0c;q是电荷&#xff0c;d是正负电荷中心距离。 分子在…

怎样优化 PostgreSQL 中对布尔类型数据的查询?

文章目录 一、索引的合理使用1. 常规 B-tree 索引2. 部分索引 二、查询编写技巧1. 避免不必要的类型转换2. 逻辑表达式的优化 三、表结构设计1. 避免过度细分的布尔列2. 规范化与反规范化 四、数据分布与分区1. 数据分布的考虑2. 表分区 五、数据库参数调整1. 相关配置参数2. 定…

深度学习-梯度下降算法-NLP(五)

梯度下降算法 深度学习中梯度下降算法简介找极小值问题数学上求最小值梯度梯度下降算法 找极小值问题在深度学习流程中深度学习整体流程图求解损失函数的目标权重的更新 深度学习中梯度下降算法简介 找极小值问题 引子&#xff1a; 我们训练一个人工智能模型&#xff0c;简单…

记录一次Nginx的使用过程

一、Docker安装配置nginx 1.拉取镜像 docker pull nginx2.创建挂载目录 启动前需要先创建Nginx外部挂载目录文件夹 主要有三个目录 conf&#xff1a;配置文件目录log&#xff1a;日志文件目录html&#xff1a;项目文件目录&#xff08;这里可以存放web文件&#xff09; 创建挂…

【沐风老师】3DMAX建筑体块生成插件BuildingBlocks使用方法详解

BuildingBlocks建筑体块生成插件使用方法详解 听说你还在手动建配景楼&#xff1f;有了BuildingBlocks这个插件&#xff0c;一分钟搞定喔&#xff01; 3DMAX建筑体块生成插件BuildingBlocks&#xff0c;用于快速自定义街道及生成配景楼区块。 【适用版本】 3dMax2019及更高版…

鸿蒙语言基础类库:【@ohos.process (获取进程相关的信息)】

获取进程相关的信息 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。…

【专项刷题】— 位运算

常见类型介绍&#xff1a; & &#xff1a;有 0 就是 0 | &#xff1a;有 1 就是 1 ^ &#xff1a;相同为 0 &#xff0c;相异为 1 或者 无进位相加给定一个数确定它的二进制位的第x个数是0还是1&#xff1a;将一个数的二进制的第x位改成1&#xff1a;将一个数的二进制的第x…

无人机在交通管理方面的应用与潜力

随着智能化和数字化技术的发展&#xff0c;无人机已经成为智慧交通管理体系中的重要一环。无人机能够搭载各种专业设备&#xff0c;如超清摄像头、红外热成像摄像头、目标跟踪器等&#xff0c;从而完成多任务的数据采集和快速机动的任务执行。这些数据通过无线传输实时回传&…

RxJava学习记录

文章目录 1. 总览1.1 基本原理1.2 导入包和依赖 2. 操作符2.1 创建操作符2.2 转换操作符2.3 组合操作符2.4 功能操作符 1. 总览 1.1 基本原理 参考文献 构建流&#xff1a;每一步操作都会生成一个新的Observable节点(没错&#xff0c;包括ObserveOn和SubscribeOn线程变换操作…

YOLOv10改进 | 主干篇 | 低照度增强网络PE-YOLO改进主干(改进暗光条件下的物体检测模型)

一、本文介绍 本文给大家带来的改进机制是低照度图像增强网络PE-YOLO中的PENet&#xff0c;PENet通过拉普拉斯金字塔将图像分解成多个分辨率的组件&#xff0c;增强图像细节和低频信息。它包括一个细节处理模块&#xff08;DPM&#xff09;&#xff0c;用于通过上下文分支和边…

【安全设备】日志审计

一、什么是日志审计 日志审计是一站式的日志数据管理平台&#xff0c;主要致力于提供事前预警、事后审计的安全能力&#xff0c; 通过对日志数据的全面采集、解析和深度的关联分析&#xff0c;及时发现各种安全威胁和异常行为事件。日志审计是指通过集中采集信息系统中的各类信…

Chain-of-Verification Reduces Hallucination in Lagrge Language Models阅读笔记

来来来&#xff0c;继续读文章了&#xff0c;今天这个是meta的研究员们做的一个关于如何减少LLM得出幻觉信息的工作&#xff0c;23年底发表。文章链接&#xff1a;https://arxiv.org/abs/2309.11495 首先&#xff0c;这个工作所面向的LLM的问答任务&#xff0c;是list-based q…

怎样优化 PostgreSQL 中对日期时间范围的模糊查询?

文章目录 一、问题分析&#xff08;一&#xff09;索引未有效利用&#xff08;二&#xff09;日期时间格式不统一&#xff08;三&#xff09;复杂的查询条件 二、优化策略&#xff08;一&#xff09;使用合适的索引&#xff08;二&#xff09;规范日期时间格式&#xff08;三&a…

前沿重器[53] | 聊聊搜索系统6:精排

前沿重器 栏目主要给大家分享各种大厂、顶会的论文和分享&#xff0c;从中抽取关键精华的部分和大家分享&#xff0c;和大家一起把握前沿技术。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。&#xff08;算起来&#xff0c;专项启动已经…

IDEA启动tomcat之后控制台出现中文乱码问题

方法1&#xff1a; 第一步&#xff1a;file--setting--Editor--File Encodings 注意页面中全部改为UTF-8&#xff0c;然后apply再ok 第二步&#xff1a;Run--Edit Configuration&#xff0c;将VM options输入以下值&#xff1a; -Dfile.encodingUTF-8 还是一样先apply再ok …

视频图文理解关联技术与创业团队(二)

上一篇&#xff1a;google gemini1.5 flash视频图文理解能力初探&#xff08;一&#xff09;提到了gemini 1.5 flash 可以对视频进行理解以及分析&#xff0c;但是整体在检索任务上效果不佳。 这几天参加了人工智能大会 网上收集&#xff0c;看一看有相似能力的一些技术点、创…

生物素化果胶粒子包裹药物阿霉素;DOX/Bio-PEC

生物素化果胶粒子包裹药物阿霉素&#xff08;DOX/Bio-PEC&#xff09;是一种新型的药物载体系统&#xff0c;结合了生物素和果胶多糖的优势&#xff0c;旨在提高药物的靶向性和控释性能。以下是对该系统的详细解析&#xff1a; 一、生物素化果胶粒子的制备 原理与步骤&#xff…

独立开发者系列(22)——API调试工具apifox的使用

接口的逻辑已经实现&#xff0c;需要对外发布接口&#xff0c;而发布接口的时候&#xff0c;我们需要能自己简单调试接口。当然&#xff0c;其实自己也可以写简单的代码调试自己的接口&#xff0c;因为其实就是简单的request请求或者curl库读取&#xff0c;调整请求方式get或者…

甄选范文“论区块链技术及应用”,软考高级论文,系统架构设计师论文

论文真题 区块链作为一种分布式记账技术,目前已经被应用到了资产管理、物联网、医疗管理、政务监管等多个领域。从网络层面来讲,区块链是一个对等网络(Peer to Peer, P2P),网络中的节点地位对等,每个节点都保存完整的账本数据,系统的运行不依赖中心化节点,因此避免了中…