【数据存储:揭开内存中数据存储的神秘面纱】

news/2024/11/14 15:03:16/

f28427f853824a7b950775feed6fa991.jpeg

 本节重点 -- 重中之重

  1. 数据类型详细介绍
  2. 整形在内存中的存储:原码、反码、补码
  3. 大小端字节序介绍及判断
  4. 浮点型在内存中的存储解析

143e95913df1464284c45be43d0d0276.jpeg

准备好了,开始啰,在小小的花园里面......最近被这个歌曲洗脑,但是我们并不是要唱歌,而是要学技术啦,哈哈哈,正片开始。

数据类型介绍

  • char        //字符数据类型  1字节
  • short       //短整型  2字节
  • int         //整形 4字节
  • long        //长整型 4/8字节
  • long long   //更长的整形 8字节
  • float       //单精度浮点数 4字节
  • double      //双精度浮点数 8字节
  • //C语言有没有字符串类型?没有,但是可以用字符数组存储字符串

a1b7ba98e0094e49b1f1a157f3c8e2b8.png

类型的意义:

  1. 使用这个类型开辟内存空间的大小(大小决定了使用范围)。
  2. 如何看待内存空间的视角。

类型的基本归类

整形家族:

69ef0155956649939323ecffcc737faf.png

浮点数家族:

09727015422a43a78c48b0746515bc92.png构造类型:

a300d87e4d0f4ace94453d647b1c43c8.png

指针类型:

c8e86d8f699e42e0891a454152c3dbe8.png

空类型:

768f93387c154ebfa82b51da20eaa3f9.png

 

 5653c72e1c4f4e6394e945859736f4ec.jpeg

 ac37a48c319f4923971f33a91c924848.jpeg

整形在内存中的存储

        一个变量的创建是要在内存中开辟空间的,而空间的大小是根据不同的类型而决定的。

那么数据在所开辟内存中到底是如何存储的?

比如:

int a = 10;//创建一个变量a,由于是int类型,需要向内存开辟四个字节的空间
int b = -10;//创建一个变量b,由于是int类型,需要向内存开辟四个字节的空间
  • 我们知道为 a 和 b 分配四个字节的空间。
  • 那是如何存储的呢?
  • 接下来听我一一道来。

原码、反码、补码

计算机中的整数有三种2进制表示方法,即原码、反码和补码。

三种表示方法均有符号位数值位两部分,符号位都是用0表示“正”,用1表示“负”。

c5ca48dd8407496d9f5bfc26f9b831a1.png

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

5a1f5d7d18d04b7bbe3a03c508e1781d.png

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

why?

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

10c1475d0c684ebe828e766a5e4ffad4.png

b06a6d5469744f4d96f9b6d3b1d4926c.jpeg

83b7cc28d45b4cc1b4da92a543287229.png

  • 我们可以看到对于a和b分别存储的是补码。但是我们发现顺序有点不对劲。
  • 这是又为什么?

大小端介绍

什么是大端小端:

  • 大端(存储)模式:是指数据的低权值位保存在内存的高地址中,而数据的高权值位,保存在内存的低地址中。
  • 小端(存储)模式:是指数据的低权值位保存在内存的低地址中,而数据的高权值位,保存在内存的高地址中。

为什么有大端和小端:

  • 为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8 bit的char之外,还有16 bit的short 型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32 位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
  • 例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为 权值高的字节, 0x22为权值低的字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式 还是小端模式。

52ac4b5869bc4599b7df38b35d4d52ff.jpeg

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

#include <stdio.h>
//方法一:
int CheckSystem1()
{int i = 1;return (*(char*)&i);
}
//方法二:
int CheckSystem2()
{union{int i;char c;}un;un.i = 1;return un.c;
}int main()
{int ret = CheckSystem1();if (ret == 1){printf("小端\n");}else{printf("大端\n");}return 0;
}

f045ead2d8c84c52a42667d0f386b9fc.png

4ec7ceeb7ae64816a08728252778d8bf.jpeg

c126fe98a6d64d4abc8e9ad05af16216.png

七个小练习 - 巩固知识

demo1

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

5b1a0a6b333c4120a6e9d9f303a8fdf2.png

demo2

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

f1abf551dfa845559ff2949717ff213f.png

demo3

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

9715f266dfd9438d804d5d80fdda5c0d.png

demo4

#include<stdio.h>
int main()
{int i = -20;unsigned  int  j = 10;printf("%d\n", i + j);return 0;
}

3386d7e1aab3401db7959bd45b51b657.png

demo5

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

876535838dd94a9f80c49e1e1a8738b1.png

demo6

#include<stdio.h>
#include<string.h>
int main()
{char a[1000];int i;for (i = 0; i < 1000; i++){a[i] = -1 - i;}printf("%d", strlen(a));return 0;
}

 24128c3454104440ac3d87269cc9fa7a.png

demo7

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

5fe866a965ba4455890717430b579d35.png

50bd97e5c64648728ae1a90ccc691c2f.jpeg

 浮点型在内存中的存储

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

b0e364f0e4f04c378829c5a2806ecb67.png

 f2f81ad1679048d198033a88a7831697.png

467e1aa35a594df3a9ecc7a057497430.png

 

浮点数存储的例子:

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

输出结果是什么呢?

2b9a4169cb3149ff85cc0deeda42d33e.png

7a602536e0c646fb8c5975db50bf2029.jpeg

 

 

 

 

 

Why?Why?Why?

  • num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
  • 要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。

5445a0c186ba4383bee9385e34c2ab40.png

 

IEEE 754规定:

2daa7e3f0ccc42f8bc420f6ba2cca5c3.png

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,情况就比较复杂。

8eb847cbd52e439fb013fdeaa5b16d2c.png

指数E从内存中取出还可以再分成三种情况:

one:

8c98a1f9bb3146a39fe1dd190bb0cbd2.png

 再看一个加强知识理解

80f7bbecfdf842fc9c86de6b12eb574a.png

two:265b2da19bec414892c8b6c01eada6a4.png

three:

eb169965d1ff4816b1ee077d1269d522.png

5da31a90f41d48928b036c37781f5fae.jpeg

知识讲解完毕,再解释前面的题目: 

5722ad7ed16d4cfa86e292acbc5eb4bd.png

0be9e8515b864988b0ca8871d83f87d6.jpeg

 

 


http://www.ppmy.cn/news/246226.html

相关文章

联想笔记本thinkpad外放没有声音,插耳机有声音?怎么解决?

问题描述&#xff1a;我用的笔记本是联想thinkpad E570c&#xff0c;重装了一次系统后&#xff0c;外放就没有声音了&#xff0c;可是插上耳机就有。在我检查了声卡驱动是正常的情况下&#xff0c;一度以为是自己的音箱坏了&#xff0c;就在最近找到了解决方法。 解决方法&…

linux内核无法识别声卡,伪输出,检测不到集成声卡

鼓捣了一天 配置&#xff1a;win10 ubuntu 18.04 ; 拯救者y7000p 我第一次装ubuntu完全没问题&#xff0c;后来因为显卡驱动问题重装了ubuntu&#xff0c; 一开机就出现没有声音的情况&#xff0c;非常不方便&#xff0c;百度出了一些解决方案&#xff0c;改了一些config&…

win10网络重置后果很严重(联想电脑)

1.win的网络重置功能。 2.重置后是这样的 &#xff0c;啥都没有&#xff0c;更别说联网了。 我不知道是不是只有联想才会这样。 本来在网络连接有好动东西&#xff0c;现在啥都没有&#xff0c;看了好多博客&#xff0c;都没有解决问题&#xff0c;好多人都重装系统了。 3.如果…

联想ThinkPad声音扬声器正常但是不能发出声音,插入耳机有声音

1.检查是否是静音操作&#xff0c;细节往往不被人所注意。 2.检查声卡的驱动是否正常。 3.在联想的官网按照自己的电脑型号&#xff0c;下载安装一个热键驱动。 参考&#xff1a;https://blog.csdn.net/qq_44752641/article/details/105602244 补充&#xff1a;在安装了一个…

Tomcat优化及Nginx、tomcat动静分离配置

Tomcat优化及Nginx、tomcat动静分离配置 一、Tomcat优化1、操作系统优化&#xff08;内核参数优化&#xff09;2、Tomacat配置文件优化3、Java虚拟机&#xff08;JVM&#xff09;调优 二、Nginx、tomcat动静分离配置(七层代理)三、四层代理 一、Tomcat优化 Tomcat默认安装下的…

联想T430i笔记本电脑无声音

联想T430i笔记本电脑无声音的解决办法 一、电脑情况&#xff1a; 1.操作系统&#xff1a;Windows7。 2.电脑硬件(喇叭、线路)无问题&#xff0c;可以发声。 3.声卡驱动已启动。 4.测试立体音提示“其他应用程序正在使用此设备.请关闭任何正在向此设备播放音频的设备,然后重试…

(首个填坑)联想拯救者Y7000(自带win10 home) 安装Ubuntu16.04.6 + NVIDIA GTX1650驱动

0. 摘要 由于NVIDIA的GTX1650显卡刚推出不久, 就我所知, 目前没有关于在Ubuntu上成功安装GTX1650显卡驱动教程, 所以我在安装GTX1650显卡驱动的过程中走了很多弯路, 同时也学会了很多的知识, 所以在此博客分享我的经验.第一部分主要讲了Ubuntu16.04系统的安装, BIOS设置和分区…

联想小新Win11系统屏幕和声音间歇性卡顿解决方案

相信很多人在微软发布win11时就加入了windows体验计划&#xff0c;本人是在去年夏天的时候刚出这项计划就体验了win11&#xff0c;整体来说没有win10舒服&#xff0c;尤其是流畅度方面&#xff0c;但是既然已经更新了就不想再退到win10&#xff0c;因为这涉及到个人的工作环境问…