【C语言系列】数据在内存中存储

news2025/3/25 16:07:33

数据在内存中存储

  • 一、整数在内存中的存储
  • 二、大小端字节序和字节序判断
    • 2.1什么是大小端?
    • 2.2练习
      • 2.2.1练习1
      • 2.2.2练习2
      • 2.2.3练习3
      • 2.2.4练习4
      • 2.2.5练习5
      • 2.2.6练习6
  • 三、浮点数在内存中的存储
    • 3.1练习
    • 3.2浮点数的存储
      • 3.2.1 浮点数存的过程
      • 3.2.2 浮点数取的过程
    • 3.3题目解析
  • 四、总结
    • 4.1整数在内存中的存储
    • 4.2大小端字节序
    • 4.3浮点数在内存中的存储
    • 4.4总结

一、整数在内存中的存储

整数的2进制表示方法有三种,即原码、反码和补码。
有符号整数,符号位 0 —— 正 1 —— 负,最高位为符号位
正整数的原、反、补码都相同。
负整数的三种表示方法各不相同,如下:
原码:直接被数值按照正负数的形式翻译成二进制得到的是原码。
反码:将原码的符号位不变,其他位次按位取反,就得到了反码。
补码:反码+1就得到补码。
注:对于整形来说:数据存放内存中其实存放的是二进制补码。

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

二、大小端字节序和字节序判断

当我们了解了整数在内存中存储后,我们调试看一个细节:

int main()
{
int n = 0x11223344;
return 0;
}

调试结果如下图:
在这里插入图片描述

注:
1.整数在内存中存储的是二进制的补码。
2.在调试窗口中观察内存的时候,为了方便展示,显示的是16进制的值。
3.存储的顺序是倒过来的!

进行调试后,观察上述图片我们可以看到n中的 0x11223344 这个数字是按照字节为单位,倒着存储的。这是为什么呢?

2.1什么是大小端?

x86 —— 小端模式(DSP) KEIL C51 —— 大端模式
其实超过一个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储小端字节序存储

大端字节序存储:把一个数据的低位字节的内容存储到高地址处,把高位字节的内容存储到低地址处。
小端字节序存储:把一个数据的低位字节的内容存储到低地址处,把高位字节的内容存储到高地址处。

如下图:
在这里插入图片描述
为什么有大小端模式之分?

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

2.2练习

2.2.1练习1

设计一个小程序来判断当前机器的字节序:

#include <stdio.h>
int main()
{
int n = 1;
if(*(char*) & n == 1)
	printf("小端\n");
else
	printf("大端\n");
//0x00 00 00 01
//01 00 00 00
//00 00 00 01
return 0;
}

对于if语句阔号内的解析:(把下面的A换成n即可)
在这里插入图片描述

运行结果如下图:
在这里插入图片描述

2.2.2练习2

signed char a;//有符号的;char —— 1个字节 —— 8bit位。
unsigned char b;//无符号的; 2^8 —— 256。
如果是signed char 类型,那么内存中的最高位就被当做符号位。
signed char类型的取值范围是-128~127;对于unsigned char的取值范围是 0 ~ 255。
在这里插入图片描述
代码2:

#include <stdio.h>
int main()
{
//char到底是有符号的char还是无符号的char是取决于编译器的!
//在VS上char == signed char
char a = -1;
//10000﹍﹍0001
//11111﹍﹍1110
//11111﹍﹍1111
//11111111 —— a
signed char b = -1;//整型提升
//11111111 —— b
unsigned char c = -1;
//11111111 —— c
printf("a = %d,b = %d,c = %d",a,b,c);
//-1	-1	  255
return 0;
}

运行结果如下图:
在这里插入图片描述

2.2.3练习3

代码3:

#include <stdio.h>
int main()
{
char a = -128;//1000﹍﹍10000000 —> 1111﹍﹍01111111
printf("%u\n",a);//?4294967168//—> 1111﹍﹍10000000
//%u的形式打印,是认为a中存放的是无符号数//10000000 —— a//整型提升
//a是char类型,首先要整型提升
return 0;
}

运行结果如下图:
在这里插入图片描述
代码4:

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

运行结果如下图:
在这里插入图片描述

2.2.4练习4

代码5:

//signed short -32768 ~ 32767
//unsigned char 0 ~ 65535
#include <stdio.h>
int main()
{
char a[1000];//0 ~ 999
int i;
for(i = 0;i < 1000;i++)
{
a[i] = -1-i;
}
//-1 -2 -3 -4 ﹍﹍ -127 -128 127 126 ﹍﹍ 4 3 2 1 0 -1 -2 ﹍﹍
printf("%zd",strlen(a));//求的是字符串的长度,统计的是\0(ASCII码值是0)之前的字符个数
//255
return 0;
}

运行结果如下图:
在这里插入图片描述
在这里插入图片描述

2.2.5练习5

代码6:

#include <stdio.h>
unsigned char i = 0;//unsigned char 的取值范围是0 ~ 255
int main()
{
for(i = 0;i <= 255;i++)
{
printf("hello world\n");//死循环打印
}
return 0;
}

运行结果如下图:
在这里插入图片描述
在这里插入图片描述

代码7:

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

运行结果如下图:
在这里插入图片描述
在这里插入图片描述

2.2.6练习6

代码8:

#include <stdio.h>
//X86环境小端字节序
int main()
{
int a[4] = {1,2,3,4};//1.指针+1,取决于指针的类型;2.整数+1,就是+1。//&a —— int(*)[4]
int*ptr1 = (int*)(&a + 1);
int*ptr2 = (int*)((int)a + 1);
printf("%x,%x",ptr1[-1],*ptr2);//4	2000000
return 0;
}

在这里插入图片描述

三、浮点数在内存中的存储

浮点数:float、double、long double类型
浮点数表示的范围:float.h中定义;整数的取值范围:limits.h中定义。

3.1练习

练习代码如下:求其运行结果

#include <stdio.h>
int main()
{//说明:整数和浮点数在内存中的存储方式是不一样的。
int n = 9;
float*pFloat = (float*)&n;//int*
printf("n的值为: %d\n",n);//9
printf("*pFloat的值为: %f\n",*pFloat);//0.000000
*pFloat = 9.0;
printf("n的值为: %d\n",n);//1091567616
printf("*pFloat的值为:%f\n",*pFloat);//9.000000
return 0;
}

运行结果如下图:
在这里插入图片描述

3.2浮点数的存储

根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:
V = (-1)S * M * 2E

(-1)S表示符号位,当S = 0,V为正数;当S = 1,V为负数。
M表示有效数字,M是大于等于1,小于2的。
2E表示指数位

如下图所示:
在这里插入图片描述
注:所以浮点数的存储,其实存储的就是S,M,E相关的值。
IEEE 754规定:
对于32位的浮点数(float),最高的1位存储符号位S,接着的8位存储指数E,剩下的32位存储有效数字M。
对于64位的浮点数(double),最高的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。

3.2.1 浮点数存的过程

IEEE 754对有效数字M和指数E,还有一些特别规定:
1 <= M <2,M可写为1.xxxxxx的形式,其中xxxxxx表示小数部分。
IEEE754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分,比如:保存1.01时,只保存01,等读取时,再把第一位的1加上,这样做的目的是节省1位有效数字。

至于指数E,情况比较复杂

首先,E为一个无符号整数(unsigned int) E为8位,0 ~ 255;E为11位,0 ~ 2047。
我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023.比如,2^10的E是10,所以保存32位浮点数时,必须保存成10+127=137,即10001001。即使是浮点数也是有最大值和最小值。
E也是有最大值和最小值的, E+127 E+1023

int main()
{//5.5
float f = 5.5f;
//5.5 —> 101.1 —> 1.011*2^2 —> (-1)^0*1.011*2^2
//S = 0	M = 1.011	E = 2
//2 + 127 = 129
//01 00 0000 1011 00000000000000000000
//40 B0 00 00
return 0;
}

3.2.2 浮点数取的过程

指数E从内存中取出还可以分成三种情况:
E不全为0或者不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或者1023),得到真实值,再将有效数字M前加上第1位的1。
E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0,xxxxxx的小数,这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号S)

3.3题目解析

代码如下:

#include <stdio.h>
int main()
{
int n = 9;
float*pFloat = (float*)&n;//int*
printf("n的值为: %d\n",n);//9
printf("*pFloat的值为: %f\n",*pFloat);//0.000000
//站在pFloat的视角,它会认为自己指向的是1个float类型的数值,当内存中的E为全0的时候,真实的E:1-127 —> -126	有效数字M,取出后不再加上第1位的1
//(-1)^0*0.0000﹍01001*2^(-126) ≈ 0
*pFloat = 9.0;
printf("n的值为: %d\n",n);//1091567616
printf("*pFloat的值为: %f\n",*pFloat);//9.000000
return 0;
}

图文解释:
在这里插入图片描述

四、总结

本文详细讨论了整数和浮点数在内存中的存储方式以及相关的字节序和浮点数表示方法。文章主要涉及了三部分内容:整数在内存中的存储,大小端字节序的判断与实现,以及浮点数在内存中的存储和转换。

4.1整数在内存中的存储

文章首先介绍了整数在内存中的存储方式。整数使用原码、反码和补码三种形式表示,其中,原码是最直接的表示方式,反码是通过对原码符号位之外的所有位取反得到的,而补码则是在反码的基础上加1得到。补码在计算机中被广泛应用,因为它不仅能有效表示正负数,还简化了加法和减法操作。计算机中所有整数的存储都是以补码的形式进行的,这样可以统一处理符号位和数值域,并且不需要额外的硬件支持,这使得计算更加高效。

4.2大小端字节序

文章进一步探讨了大小端字节序的问题。在计算机系统中,超过一个字节的数据如何存储在内存中,会受到字节序的影响。字节序分为大端和小端两种模式。在大端字节序中,数据的高位字节存储在低地址处,低位字节存储在高地址处;而在小端字节序中,低位字节存储在低地址处,高位字节存储在高地址处。这种存储顺序的差异,主要是由于计算机处理器的寄存器宽度大于一个字节,导致了如何安排多字节数据的问题。文章还通过代码示例,展示了如何判断当前系统的字节序。通过访问内存中的字节,判断数据的存储顺序,从而确定系统使用的是大端还是小端字节序。

4.3浮点数在内存中的存储

接着,文章讲解了浮点数在内存中的存储方式。浮点数采用IEEE 754标准来表示,在此标准下,浮点数由符号位、指数部分和有效数字部分组成。对于32位的浮点数(float类型),符号位占1位,指数占8位,有效数字占23位。对于64位的浮点数(double类型),符号位占1位,指数占11位,有效数字占52位。浮点数的表示使用科学计数法,其中符号位表示正负,指数部分表示数字的范围,有效数字则表示具体的数值。通过这种表示方法,浮点数能够有效表示非常大或非常小的数值,且能够处理精确的小数部分。

浮点数的存储与整数有所不同,尤其是在对存储内容的解读时,浮点数的指数和有效数字需要特殊处理。例如,当浮点数的指数部分全为0时,它表示的是接近于0的非常小的数字,而不是普通的0。对于有效数字部分,IEEE 754标准规定了它的存储方式,即默认保留第一位为1,因此只存储后续的小数部分。这些存储规则有助于节省内存空间,同时确保浮点数的精度和范围。

4.4总结

通过本篇文章,我们了解了整数和浮点数在内存中的存储原理,以及大小端字节序的差异。对于整数,补码的存储方式提供了一个简洁高效的处理方案,能够统一处理符号和数值域。大小端字节序的存在是由于处理器寄存器的宽度大于一个字节,在不同的系统中会有不同的存储顺序。浮点数的存储则遵循IEEE 754标准,通过符号位、指数和有效数字来表示浮动的数值范围。所有这些知识对于理解计算机内部的数据存储和处理方式至关重要,尤其是当我们需要优化程序或进行低级编程时。

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

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

相关文章

【中文翻译】第12章-The Algorithmic Foundations of Differential Privacy

由于GitHub项目仅翻译到前5章&#xff0c;我们从第6章开始通过大语言模型翻译&#xff0c;并导出markdown格式。 大模型难免存在错漏&#xff0c;请读者指正。 教材原文地址&#xff1a;https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf 12 其他模型 到目前为止&…

图解模糊推理过程(超详细步骤)

我们前面已经讨论了三角形、梯形、高斯型、S型、Z型、Π型6种隶属函数&#xff0c;下一步进入模糊推理阶段。 有关六种隶属函数的特点在“Pi型隶属函数&#xff08;Π-shaped Membership Function&#xff09;的详细介绍及python示例”都有详细讲解&#xff1a;https://lzm07.b…

datawhale组队学习-大语言模型-task5:主流模型架构及新型架构

目录 5.3 主流架构 5.3.1 编码器-解码器架构 5.3.2 因果解码器架构 5.3.3 前缀解码器架构 5.4 长上下文模型 5.4.1 扩展位置编码 5.4.2 调整上下文窗口 5.4.3 长文本数据 5.5 新型模型架构 5.5.1 参数化状态空间模型 5.5.2 状态空间模型变种 5.3 主流架构 在预训…

RAG 架构地基工程-Retrieval 模块的系统设计分享

目录 一、知识注入的关键前奏——RAG 系统中的检索综述 &#xff08;一&#xff09;模块定位&#xff1a;连接语言模型与知识世界的桥梁 &#xff08;二&#xff09;核心任务&#xff1a;四大关键问题的协调解法 &#xff08;三&#xff09;系统特征&#xff1a;性能、精度…

(C语言)习题练习 sizeof 和 strlen

sizeof 上习题&#xff0c;不知道大家发现与上一张的习题在哪里不一样嘛&#xff1f; int main() {char arr[] "abcdef";printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr 0));printf("%zd\n", sizeof(*arr));printf(&…

Unity Animation的其中一种运用方式

Animation是Unity的旧的动画系统&#xff0c;先说目的&#xff0c;其使用是为了在UI中播放动效&#xff0c;并且在动效播放结束后接自定义事件而设计的 设计的关键点在于&#xff0c;这个脚本不是通过Animation直接播放动画片段&#xff0c;而是通过修改AnimationState的nor…

框架的CVE漏洞利用 php类 java类 手工操作和自动化操作蓝队分析漏洞利用的流量特征

前言 php重要框架和基本的识别特征 php的主要是 tp框架 和 laravel 当然还有 yii等 tp的主要特征 1\报错信息&#xff1a; 2、图标 3、请求头 Laravel特征 1、报错信息 2、请求头 php框架CVE利用 lavarvel 工具 https://github.com/zhzyker/CVE-2021-3129 https://git…

【算法day19】括号生成——数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

括号生成 https://leetcode.cn/problems/generate-parentheses/description/ 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 左括号数必须大于右括号数&#xff0c;且小于等于n class Solution { publ…

Qt5.15.2实现Qt for WebAssembly与示例

目录 1.什么是Qt for WebAssembly&#xff1f; 1.1 什么是 WebAssembly&#xff1f; 1.2 WebAssembly 的优势 1.3 什么是 Qt for WebAssembly&#xff1f; 1.4 Qt for WebAssembly 的特点 1.5 编译过程 1.6 运行时环境 注意&#xff01;&#xff01;&#xff01;注意&am…

好吧好吧,看一下达梦的模式与用户的关系

单凭个人感觉&#xff0c;模式在达梦中属于逻辑对象合集&#xff0c;回头再看资料 应该是一个用户可以对应多个模式 问题来了&#xff0c;模式的ID和用户的ID一样吗&#xff1f; 不一样 SELECT USER_ID,USERNAME FROM DBA_USERS WHERE USERNAMETEST1; SELECT ID AS SCHID, NA…

HOW - DP 动态规划系列(三)(含01背包问题)

目录 一、01背包问题最直接的暴力解法动态规划解法 二、完全背包 通过几个算法的学习&#xff0c;理解和掌握动态规划来解决背包问题。 一、01背包问题 对于面试的话&#xff0c;掌握01背包和完全背包就够用了&#xff0c;最多可以再来一个多重背包。 如果这几种背包分不清&…

在linux服务器部署Heygem

前言&#xff1a; Heygem官方文档上提供了基于windwos系统的安装方案。在实际使用过程中个人电脑的配置可能不够。这个时候如果服务器配置够的话&#xff0c;可以尝试在服务器上装一下。但是服务器一般都是linux系统的&#xff0c;于是这篇教程就出现了… 可行性分析 通读安装…

图书管理系统系统-Java、SpringBoot、Vue和MySQL开发的图书馆管理系统

「springboot、vue图书馆管理系统.zip」 链接&#xff1a;https://pan.quark.cn/s/5a929a7e9450 分享一个图书管理系统&#xff0c;Java、SpringBoot、Vue和MySQL开发的图书馆管理系统 以下是对文本内容的总结&#xff1a; 项目概述 项目名称与背景&#xff1a; 项目概述 项…

[c语言日寄]数据输入

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

字节DAPO算法:改进DeepSeek的GRPO算法-解锁大规模LLM强化学习的新篇章(代码实现)

DAPO算法&#xff1a;解锁大规模LLM强化学习的新篇章 近年来&#xff0c;大规模语言模型&#xff08;LLM&#xff09;在推理任务上的表现令人瞩目&#xff0c;尤其是在数学竞赛&#xff08;如AIME&#xff09;和编程任务中&#xff0c;强化学习&#xff08;RL&#xff09;成为…

计算机操作系统(四) 操作系统的结构与系统调用

计算机操作系统&#xff08;四&#xff09; 操作系统的结构与系统调用 前言一、操作系统的结构1.1 简单结构1.2 模块化结构1.3 分层化结构1.4 微内核结构1.5 外核结构 二、系统调用1.1 系统调用的基本概念1.2 系统调用的类型 总结&#xff08;核心概念速记&#xff09;&#xf…

DeepSeek技术架构解析:MoE混合专家模型

一、前言 2025年初&#xff0c;DeepSeek V3以557万美元的研发成本&#xff08;仅为GPT-4的1/14&#xff09;和开源模型第一的排名&#xff0c;在全球AI领域掀起波澜。其核心创新之一——混合专家模型&#xff08;Mixture of Experts, MoE&#xff09;的优化设计&#xff0c;不…

【正点原子】AI人工智能深度学习(RV1126/RK3568/RK3588)-第1期 准备篇

1.1SDK编译后的目录 1、真正的根文件系统镜像存放目录 2、非必须&#xff0c;负责系统升级等&#xff0c;kerneldtbramdisk组成的根文件系统 1.2文件系统分区 1.3开机自启动 1.6设置静态ip地址 1.8RKMedia框架/编译测试SDK自带RKMedia例程 出厂系统以下内容都是默认…

靶场(十五)---小白心得思路分析---LaVita

启程&#xff1a; 扫描端口&#xff0c;发现开放22&#xff0c;80端口&#xff0c;发现ws.css可能存在exp&#xff0c;经查发现无可利用的exp PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.4p1 Debian 5deb11u2 (protocol 2.0) | ssh-hostkey: | 3072 c9…

【AI大模型】DeepSeek + 通义万相高效制作AI视频实战详解

目录 一、前言 二、AI视频概述 2.1 什么是AI视频 2.2 AI视频核心特点 2.3 AI视频应用场景 三、通义万相介绍 3.1 通义万相概述 3.1.1 什么是通义万相 3.2 通义万相核心特点 3.3 通义万相技术特点 3.4 通义万相应用场景 四、DeepSeek 通义万相制作AI视频流程 4.1 D…