C语言----数据在内存中的存储

文章目录

  • 前言
  • 1.整数在内存中的存储
  • 2.大小端字节序和字节序判断
    • 2.1 什么是大小端?
    • 2.2 练习
  • 3.浮点数在内存中的存储
    • 3.1.引子
    • 3.2.浮点数的存储
    • 3.2.2 浮点数取的过程


前言

下面给大家介绍一下数据在内存中的存储,这个是一个了解c语言内部的知识点,大家可以借此机会,修炼“内功”


1.整数在内存中的存储

首先在讲解操作符是时候,给大家讲解过:
整数的存储3种形式:原码、反码和补码
有符号的整数,三种表示方法均有符号位数值位两部分,符号位都是用0表示“正”,用1表示“负”,最高位的一位是被当做符号位,剩余的都是数值位。
正整数的原、反、补码都相同。
负整数的三种表达方式各不相同。
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。

具体的示例,请前往《操作符—关于二进制的操作符》查看

2.大小端字节序和字节序判断

下面便是一个新的知识点,大小端存储问题;
引子:
大家在VS2022,调试一下下面的代码,并且打开内存窗口

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

在这里插入图片描述
我们发现,0x11223344是倒着存放的,这就是我们所说的大小端问题。

2.1 什么是大小端?

其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下面是具体的概念:
大端(存储)模式:
是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。
小端(存储)模式:
是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。
上述概念需要记住,方便分辨大小端。
在这里插入图片描述

所以vs2022的存储方式是小段存储


2.2 练习

练习1:
设计⼀个小程序来判断当前机器的字节序。

#include<stdio.h>
int test()
{int a = 1;return ((*(char*)&a));
}
int main()
{int ret = test();if (ret == 1)printf("小段存储\n");else printf("大段存储\n");return 0;
}

练习2:

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

在这里插入图片描述
在这里插入图片描述

练习3:

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

在这里插入图片描述

在这里插入图片描述
练习4:

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

在这里插入图片描述
与上面方法类似,这里不再过多阐述。
练习5:

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

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

练习5:

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

在这里插入图片描述
最后一个练习

#include <stdio.h>
//X86环境 ⼩端字节序
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;
}

在这里插入图片描述


3.浮点数在内存中的存储

3.1.引子

常见的浮点数:3.14159、1E10等,浮点数家族包括: float、double、long double 类型。
浮点数表示的范围: float.h 中定义

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

输出什么?
在这里插入图片描述

3.2.浮点数的存储

上⾯的代码中, num 和 *pFloat 在内存中明明是同⼀个数,为什么浮点数和整数的解读结果会差别这么大?
要理解这个结果,⼀定要搞懂浮点数在计算机内部的表⽰⽅法。
根据国际标准IEEE(电子和电子工程协会) 754,任意⼀个⼆进制浮点数V可以表示成下面的形式:
V = (−1) ∗ S M ∗ 2E
• (−1)S 表示符号位,当S=0,V为正数;当S=1,V为负数
• M 表⽰有效数字,M是大于等于1,小于2的
• 2E 表示指数位
举例来说:
十进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2 。

那么,按照上⾯V的格式,可以得出S=0,M=1.01,E=2。
⼗进制的-5.0,写成⼆进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。
IEEE 754规定:
对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

在这里插入图片描述

注:借用一下比特就业课的照片
3.2.1 浮点数存的过程
IEEE 754 对有效数字M和指数E,还有⼀些特别规定。
前⾯说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表示小数部分。
IEEE 754 规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保存24位有效数字。
至于指数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。

3.2.2 浮点数取的过程

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

0 01111110 00000000000000000000000

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

0 00000000 00100000000000000000000

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

0 11111111 00010000000000000000000

好了,关于浮点数的表示规则,就说到这里。


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

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

相关文章

百问网FreeRTOS学习笔记第50到56讲

/*出处&#xff1a;https://video.100ask.net/p/t_pc/course_pc_detail/column/p_6503fadfe4b064a82f0ab191本专栏一切无特殊声明的知识转述&#xff08;源码、文字以及图表&#xff09;版权均归属于百问网&#xff0c;源码仅供学习&#xff0c;请勿用于商业用途&#xff1b;不…

GoPro相机使用的文件格式和频率

打开GoPro相机(以11为例)&#xff0c;里面是一个DCIM文件夹。 DCIM是digital camera in memory 的简写&#xff0c;即存照片的文件夹&#xff0c;常见于数码相机、手机存储卡中的文件夹名字。 正常手机拍照和视频都是保存在此文件夹的。正常建议不用删&#xff0c;因为只要拍照…

Vue3中props和emits的使用总结

Vue3中props和emits的使用介绍 1&#xff0c;看代码1.1&#xff0c;App.vue1.2&#xff0c;TodoItem.vue 2&#xff0c;总结2.1 props2.2 emits 1&#xff0c;看代码 1.1&#xff0c;App.vue <script setup> import { ref,reactive } from vue import TodoItem from ./…

用队列实现栈(C)

目录 题目&#xff1a; 解题&#xff1a; 代码讲解&#xff1a; 1.构建 2.creat 3.压栈 4.出栈 5.判空 6.释放 题目&#xff1a; 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、po…

【Linux学习】Linux 的虚拟化和容器化技术

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

如何设计一个类似Dubbo的RPC框架

首先有个注册中心,提供的服务在注册中心注册保留各个服务的信息,用zookeeper来做。然后消费者需要去注册中心拿对应的服务信息,而且每个服务可能会存在于多台机器上。接着就发起一次请求了,怎么发起?基于动态代理,面向接口获取到一个动态代理,就是接口在本地的一个代理,…

MySQL 导入库/建表时/出现乱码

问题描述&#xff1a; 新建不久的项目在使用Navicat for MySQL进行查看数据&#xff0c;发现表中注释的部分乱码&#xff0c;但是项目中获取的数据使用不会。 猜测因为是数据库编码和项目中使用的不一样&#xff0c;又因为项目的连接语句定义了需要编码&#xff0c;故项目运行…

浅述安防视频监控平台EasyCVR视频汇聚管理系统运维管理能力

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

Go 性能压测工具之wrk介绍与使用

在项目正式上线之前&#xff0c;我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug&#xff1b;压力测试&#xff08;压测&#xff09;是确保系统在高负载情况下仍能稳定运行的重要步骤。通过模拟高并发场景&#xff0c;可以评估系统的性能瓶颈、可靠…

在云端遇见雨云:一位服务器寻觅者的指南

引言&#xff1a;寻觅一座云端归宿 当我踏入数字世界的边缘&#xff0c;带着对网络的探索与期待&#xff0c;我迫切需要一座安全可靠的数字栖息地。云计算技术正如一场魔法般的变革&#xff0c;而在这片广袤的云端中&#xff0c;雨云就像是一位友善的向导&#xff0c;引领我穿越…

(C)1005 继续(3n+1)猜想

1005 继续(3n1)猜想&#xff1a; 问题描述 卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里&#xff0c;情况稍微有些复杂。 当我们验证卡拉兹猜想的时候&#xff0c;为了避免重复计算&#xff0c;可以记录下递推过程中遇到的每一个数。例如对 n3 进行验证的时候&a…

30.多个线程交替执行

线程一输出a,5次&#xff1b; 线程二输出b,5次&#xff1b; 线程三输出c,5次&#xff1b; 现在要求输出abcabcabcabcabc怎么实现&#xff1f; 采用wait和notifyAll实现 public class ThreadTest {public static void main(String[] args) {WaitNotify waitNotify new Wai…

3DGS实时高质量大规模场景渲染最新SOTA!

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

文字识别 Optical Character Recognition,OCR CTC STN

文字识别 Optical Character Recognition,OCR 自然场景文本检测识别技术综述 将图片上的文字内容,智能识别成为可编辑的文本。 场景文字识别(Scene Text Recognition,STR) OCR(Optical Character Recognition, 光学字符识别)传统上指对输入扫描文档图像进行分析处理,识…

【Java EE】Maven jar 包下载失败问题的解决方法

文章目录 1. 配置好国内的Maven源1.1配置当前项⽬setting1.2设置新项⽬的setting 2.重新下载jar包3.其他问题⭕总结 1. 配置好国内的Maven源 因为中央仓库在国外, 所以下载起来会⽐较慢, 所以咱们选择借助国内⼀些公开的远程仓库来下载资源 接下来介绍, 如何设置国内源 1.1配…

【JAVAEE学习】探究Java中多线程的使用和重点及考点

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

Java基数排序知识点(含面试大厂题和源码)

基数排序&#xff08;Radix Sort&#xff09;是一种非比较型整数排序算法&#xff0c;其原理是将整数按位数切割成不同的数字&#xff0c;然后按每个位数分别比较。它通过从最低位&#xff08;个位&#xff09;开始排序&#xff0c;然后逐渐转向最高位&#xff0c;对每一位进行…

Arcgis研究区图经纬度(南北)切换为英文字体(SN)

只在做英文论文研究区图的时候用&#xff0c;平常为了方便还是切换为中文

MySQL中 in 和 exists 区别

在MySQL中&#xff0c;IN和EXISTS都是用于在子查询中测试条件的操作符&#xff0c;但它们在处理和效率上有一些重要的区别。MySQL中的in语句是把外表和内表作hash连接&#xff0c;⽽exists语句是对外表作loop循环&#xff0c;每次loop循环再对内表进⾏查询。⼤家⼀直认为exists…

面试题:JVM 调优

一、JVM 参数设置 1. tomcat 的设置 vm 参数 修改 TOMCAT_HOME/bin/catalina.sh 文件&#xff0c;如下图 JAVA_OPTS"-Xms512m -Xmx1024m" 2. springboot 项目 jar 文件启动 通常在linux系统下直接加参数启动springboot项目 nohup java -Xms512m -Xmx1024m -jar…