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

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

 

reference

n.提及,谈到;参考,查阅;(引自书或诗歌的)引言,引文;

引文的作者,参考书目;(帮助或意见的)征求,征询;

(为方便查询所用的)标记,编号;推荐信,介绍信;介绍人,推荐人

adj.参考的,用于查阅的;文献索引的,参照的

v.列出……的参考书目;提及,提到;引用,参照(某书或某作者)

1.C语言的数据类型

为什么每种语言都会规定数据类型呢?

emmm,请见我的下一篇文章,嘻嘻。

(1).数据类型分类

数据类型总的来说分为两类:内置类型、自定义类型、指针类型和空类型

2.整数在内存中的存储 

存储方式:

二进制的存储的方式一共有三种,原码、反码和补码,而整数是以二进制补码的形式进行存储的。

整数又分为正数和小数,导致它们的原反补码关系不同,具体如下:

正数:

        正数的原码、反码和补码相同,原码就是指这个数的二进制形式。

负数:

  • 负数的反码就是原码的符号位变,其它位按位取反,而补码就是在反码的基础上再加1。
  • 如果反码想得到原码就是反码减一。
  • 如果补码想要得到原码,取反加一或者减一取反。
  • 原因:

原因:CPU只有加法器,面对减法时无法计算,这时就需要将正数变为负数,进行加法计算,为了使得负数的符号位和数值位可以进行统一处理,这时就需要使用补码。具体详细内容请查看我的下一篇文章:《补码的由来》

例子1:

正数和负数的补码

例子2: 

补码转到原码

常见类型的范围大小:

当我们知道了整数是如何在内存中存储的了,下面我们来讨论一下有符号类型与无符号类型的差异,以及可能会犯的错误。

整形int

整形int按符号分为无符号类型和有符号类型,无符号类型就是指最高位表示值,有符号类型就是指最高位表示正负

大小:都是4个字节

范围:有符号[-32768~32767]        无符号[0~4294967295(2^32-1)]

可见类型的数据是有范围的,如果在使用时不注意类型的范围随意使用就会造成错误,比如下面这个例子,循环结束的条件设置为大于等于,而i本身就是无符号的数字,那么循环就会以继续下去,这就是不注意不同类型的范围所造成的结果。

字符类型

同上,字符类型按符号分为无符号类型和有符号类型,无符号类型就是指最高位表示值,有符号类型就是指最高位表示正负

大小:都是1个字节

范围:有符号[-128~127]        无符号[0~255]

同样,如果不注意它的范围也会出现问题,就如下面的例子,无符号的char类型的范围是不可能大于255的。

可见,在使用超级大的数值或者无符号类型时,一定要注意类型自身的范围!!!

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

标准:

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

注:其实V   =  (−1) ^(S) * M * 2^(E)就是二进制的科学计数法。

科学计数法:

        科学计数法通常用于科学和工程领域,是一种有效的数学工具,它不仅使数值的表示更加简洁,在进行科学计算和数据分析时具有重要作用。【补充】

        科学计数法在不同进制下都有相应的表达方式,每种进制都遵循类似的结构和原则,但在具体的数字表示上会有所不同。【补充】

十进制:

  • 科学计数法是一种表示比较大的数或比较小的数的方法,它通过使用指数来简化表示。
  • 科学计数法通常以M*10^(E)的形式表示,其中M是一个在1到10之间的数,E是一个整数
  • 10又被称作基数,基数是指数部分的底数,由R表示。
  • 这种表示方法方便地表示非常大或非常的数,同时也便于进行计算和比较
  • 十进制的科学计数法是最常的一种形式。例如,光速为3 × 10^8米/秒太阳质量约为2 × 10^30千克。【补充】

二级制:

        二进制的科学计数法与十进制的类似,只是使用2作为基数。

  • V                  要存储的浮点数
  • S                  符号位浮点数的正负,S为1或0
  • M                 尾数,用二进制下科学计数法表示时的数值,大小范围:1 =< M < 2
  •                  指数,二进制下科学计数法2的次方个数
  • R                  基数,对于十进制数的基数则是10,对于二进制数的基数则是2

存储方式:

4字节:

        对于占4个字节的浮点数,32个比特位,方式如下:

8字节:

        对于占8个字节的浮点数,64个比特位,方式如下:

  • 注意因为科学计数法中的E可能为负数的,所以IEEE 754规定,存⼊内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023
  • 注意为啥加的是127和1023,因为E为负数时,2^(-127)已经非常小了接近0了,就规定把-127作为E的下限,同时128也是E的上限;对于8个字节的也同理,都是人为规定的
  • 注意存储的是M小数点后面数字,1是不存储在位里面的
  • 如果是1xx.xxxxx的情况,向前进,变成1.xxxxxxxxxxxx的形式,E为正值
  • 如果是0.xxxxxxxxx的情况,向后进位,变成1.xxxxxxxxxxxx的形式,E为负值
  • 注意真实存的不是E,存的也不是M

例子:

a.float n = 8.5;

第一步.将十进制的数字转换为二进制的数字

先介绍一下小数怎么转二进制,如下

        我们都知道整数每一位的权重是从2的0次方依次增加,那么浮点后面的数每一位的权重以2的-1次方依次递减,那么,0.5用二进制表示为0.1,0.25就是0.01等等。

8 = 1000,0.5=1 ,那么8.5 = 1000.1【转换就是整数小数都转】

第二步.用二进制下的科学计数法表示

1000.1 = 1.0001 * 2^(3)

【1000.1小数点往左移3位也就是2的3次方】

第三步.存储

此时,S = 0;E为3,加上127,转二进制是1000 0010;M存小数点后面二进制数就是0001

就是:0 10000010 00010000000000000000000

注意0001是从前往后存,存完后剩余位置的补0!!!!!!!!!!

b.float b = - 5.0

【负数去掉负号按照正数计算,将S赋1就可】

第一步.将十进制的数字转换为二进制的数字

5 = 0011,0 = 0,5.0 = 11.0

第二步.用二进制下的科学计数法表示

11.0= 1.10 * 2^(1)

第三步.存储

此时,S = 1;E为1,加上127,转二进制就是1000 0001;M存小数点后面二进制数就是0

就是:1 10000001 000000000000000000000000

特殊情况

上面我们讨论的都是E+127不全为0或不全为1的情况,下面我们讨论两种特殊的情况 。

c.E+127全为0

  • E+127全为0的时候,E=1-127,说明2^(E)这个数字是一个接近于0很小的数
  • 那么就规定小数点左边为0,不进行+1的操作。

d.E+127全为1

  • E+127全为1说明这个数值很大,2^(E)很大,十进制数字就是无穷大

4.大小端字节序

当超过1个比特位,有多个比特位时,我们就会考虑这么多的位的存放顺序,哪个位在前?哪个位在后?那么就规定出了一套存序法则,就是大小端字节序,大小端字节序是指的数据在内存中存储的方式不同。

首先在这之前,我们先给大家普及一个数字的低位高位知识:

        比如一个十进制数字1234,这里的4就是个位,3就是十位,2就是百位,1就是千位,那么个位就是低位,依次向前十百千,千就是最高位,那么对应的一个二进制数101,1就是个位,0就是2位,1就是4位;

        你猜我为啥和你说这些?就是因为大小端字节序的存储就是按照数字的低位存在高地址位和低地址位来划分的,下面我就为大家介绍大小端字节序。


大端字节序

定义:

        大端字节序存储是指将数据的低位存储在高地址处,而将数据的高位存储在低地址处

大端字节序

小端字节序

定义:

        大端字节序存储是指将数据的低位存储在低地址处,而将数据的高位存储在高地址处

小端字节序

例子

判断大小端字节序(VS的环境)

#include<stdio.h>
int main()
{int a = 1;//思路:要判断大小端只需要看它的低地址处存的是低位还是高位,地址是低地址内存单元的地址//那么拿出它的地址访问一个字节是1则为小端字节序,0则是大端字节序int b = *(char*)&a;if (b == 1)printf("小段字节序\n");if (b == 0)printf("大端字节序\n");return 0;
}


本章内容结束,下章见,拜拜!!!

http://www.lryc.cn/news/322302.html

相关文章:

  • 管理公司员工上网行为的软件都有哪些?
  • 手撕C语言题典——逆序输出
  • 如果保障服务器的安全
  • 【SQL】1280. 学生们参加各科测试的次数 (笛卡尔积)
  • 高企认定中科技成果转化是什么呢?
  • 第十二届蓝桥杯省赛CC++ 研究生组-货物摆放
  • 基于SpringBoot的学生成绩管理系统
  • 旅游管理系统 |基于springboot框架+ Mysql+Java+Tomcat的旅游管理系统设计与实现(可运行源码+数据库+设计文档)
  • SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)
  • GAMES104-现代游戏引擎 1
  • idea 开发serlvet篮球秩序册管理系统idea开发mysql数据库web结构计算机java编程layUI框架开发
  • 【深度学习】NestedTensors
  • 【网络】负载均衡
  • dataGridView 绑定List 显示内容不刷新
  • VR历史建筑漫游介绍|虚拟现实体验店|VR设备购买
  • Linux查看硬件型号详细信息
  • 【鸿蒙HarmonyOS开发笔记】通知模块之发布基础类型通知,内含如何将图片变成PixelMap对象
  • 外包干了1个月,技术明显进步。。。
  • 鸿蒙开发实战:【Faultloggerd部件】
  • 蓝桥杯刷题|03普及-真题
  • 【动态三维重建】Deformable 3D Gaussians 可变形3D GS用于单目动态场景重建(CVPR 2024)
  • 智能驾驶域控制器行业介绍
  • [数据集][目标检测]焊接件表面缺陷检测数据集VOC+YOLO格式2292张10类别
  • 微信小程序的页面制作---常用组件及其属性
  • 什么样的网站不适合使用WordPress?
  • vulhub中GitLab 任意文件读取漏洞复现(CVE-2016-9086)
  • 【爬虫】web自动化和接口自动化
  • 哔哩哔哩后端Java一面
  • Vue.js前端开发零基础教学(二)
  • Bert模型输出:last_hidden_state转换为pooler_output