C语言进阶(一)—数据的存储

2023-09-25 14 0

文章目录

    • 一、数据类型详细介绍
    • 1.c语言的基本内置类型
    • c语言的类型:
    • 2.类型的意义:
    • 3.类型的基本分类
    • 二、整型在内存中的存储
    • 1. 数据在所开辟内存中是如何储存的呢?
    • 2.为什么内存存放的是补码?
    • 3. a,b在内存中如何存储
    • 4.大小端介绍
    • 5.大小端存在的原因
    • 6.百度2015年系统工程师笔试题:
    • 三、浮点型在内存中的存储
    • 1.浮点数表示的形式
    • 2.浮点型在内存中存放形式
    • 本章完!!

一、数据类型详细介绍

1.c语言的基本内置类型

(c语言本身就具有的类型,我们可以直接拿来使用)
在这里插入图片描述

c语言的类型:

1.内置类型

2. 自定义类型(构造类型)

在这里插入图片描述

2.类型的意义:

1.使用这个类型开辟内存空间的大小(大小决定了使用范围)

  一个整形1,只占4个字节,为了节省内存空间,我们就用int类型来存储,而没必要用long long类型。

2.如何看待内存空间的视角

  float类型占4个字节,站在float类型角度去看内存空间,存储的只能是浮点数(小数)
  int同样是4个字节,但是在int的角度看内存空间,存储的是整型。这就是视角的问题。

代码说明:

int main()
{int a = 10;float b = 10.0;return 0;
}

int和float都是4个字节,向变量a,b都放一个10;观察内存空间
   
&a在这里插入图片描述

&b在这里插入图片描述
  内存空间的存储明显不一样,在int中10以整形的方式放入内存,在float中10以浮点数的方式放入内存,这就验证了 看待不同类型的内存空间的视角也不相同。

  既然提到了类型,那么我们将类型分分类

3.类型的基本分类

(1)整形家族

在这里插入图片描述

为什么char属于整形家族呢?

  首先char是字符类型的,不好归类,同时字符在内存中是以Ascll码值存储的,Ascll码值是整数,字符存储的时候也是以整数进行存储的,所以也属于整形家族

  unsigned signed 怎么描述有符号无符号呢?

以char类型举例:

signed(有符号)在这里插入图片描述
有符号的数字,最高位为符号位。(0—正 1----负)

unsigned(无符号)
在这里插入图片描述

无符号的数字,没有符号位

11111111 对应的是255

(2)浮点型家族

在这里插入图片描述

(3)构造类型(自定义类型)

在这里插入图片描述

(4)指针类型

在这里插入图片描述

(5)空类型
在这里插入图片描述

  常用于函数,void 用于不需要返回值的函数,用于返回类型的地方
  可用于函数的参数。

 接下来重点解释整型和浮点型在内存中的存储

二、整型在内存中的存储

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

1. 数据在所开辟内存中是如何储存的呢?

比如:

int a = 20;
int b = -10;

  我们都知道a分配4个字节,那么a如何储存呢?

  这里我们就需要了解以下概念:

在这里插入图片描述
在这里插入图片描述
 通过调试,我们得知了a,b在内存中存储的内容,那么a,b是如何转换成这样的数据呢?
在这里插入图片描述

将a,b进行二进制转换,内存中存储的是补码,计算a,b的补码

在这里插入图片描述
  好的,得到补码后,内存显示的是16进制的数字,我们将补码转换为16进制,

  用到二进制转换为十六进制的规则,每4个二进制位用一个16进制的数字表示

在这里插入图片描述

在这里插入图片描述
  所以我们得到一个结论:对于整形来说,数据存放内存中其实存放的是补码。

2.为什么内存存放的是补码?

在这里插入图片描述
  这段话中的重点 :CPU只能进行加法运算
  我们用一个代码对 为什么内存存放补码 进行解释

int main()
{int a = 1;int b = -1;int c = 1 - 1;return 0}

请问在CPU只能进行加法运算的条件下,c如何计算得出结果

00000000 00000000 00000000 00000001 ----1的二进制原码

10000000 00000000 00000000 00000001 ---- -1的二进制原码

如果按照原码直接相加

那么我们会得到-2的结果

请问1-1=-2吗?结果当然是错误的!!!

但是转换补码形式

01111111 11111111 11111111 11111111 —1的补码

11111111 11111111 11111111 11111111 — -1的补码

相加的结果

10000000 0000000 0000000 0000000 (c的补码)

整型只能存储32bit位,前面的1舍去

c是一个整型,只能存32个bit位,所以补码就为全0

c的结果为0;结果正确!!!

通过举这个1-1的反例 我们得知为什么内存中存储的是整形的二进制补码。

  重新回到前头

3. a,b在内存中如何存储

在这里插入图片描述

  我们可以看到a,b分别存储的是补码,但是顺序不对劲,这又是为什么?

4.大小端介绍

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

在这里插入图片描述

5.大小端存在的原因

  为什么有大小端之分呢?

在这里插入图片描述
  了解了大小端的概念,那我们应该就知道我们的机器使用的是小端字节序存储方式,所以才会出现倒着存的现象。

  借着这个机会,了解一下大小端的知识

6.百度2015年系统工程师笔试题:

  请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序

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

  由于篇幅有限,在下一次的博客中将会讲解大小端整型内存存放的练习题。博客入口:C语言进阶(二)— 整型存放练习

  好了,到此我们就知道了整型在内存中是如何存储的,那么浮点型的数据在内存中是如何存储的?

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

1.浮点数表示的形式

在这里插入图片描述

举例来说:
 十进制的 5.0 ,写成二进制是 101.0,相当于 1.01 * 2 ^ 2 .按照上面v的表达形式,可以得出
  S=0;
  M=1.01;
  E=2;

2.浮点型在内存中存放形式

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

对于有效数字M存放在内存是还有以下具体规定:

前面说过 1.0 <= M < 2.0, M可以写成 1.xxxxx 的形式,其中 xxxx 是小数部分

在这里插入图片描述
  以上面的 5. 0 为例,表示成 1.01 * 2 ^ 2,有效数字为 1.01 ,其中由于所有的有效数字整数部分都为1,所以为了节省有效数字,只将小数点后面的 01 放入内存中。

M的取出

  当然,把有效数字从内存中取出时,记得取出的是有效数字的小数位,还要自动在小数位前补1.

至于指数E,情况就更加复杂

E在内存中存放

在这里插入图片描述

以8位的E举例子

以十进制的 0.5 举例子

0.5转换成二进制为 0.1

0.1

1.0 * 2 ^ (-1)

此时E为-1,为负数,但是E为一个无符号整数。

  所以我们将E存入内存时就需要借助一个中间数,对于 8 位的E,这个中间数是 127 ,所以实际在内存中存放的 E= -1 + 127 = 126.

E从内存中取出

在这里插入图片描述
  E不全为 0 或不全为 1 ,为正常的情况,只需将 E - 127 ,即可得到真实的E。

  E全为 0 时,当真 E + 127 = 0 ,则真实的 E = - 127,一个数字的 - 127 次方约等于 0 ,所以我们得到的是一个无限接近于 0 的数字(几乎不存在),所以 IEE754 规定了, E = 1 - 127 或者 E = 1 - 1023 即为真实值,有效数字不加上第一位的1,直接以 +/- 0.xxxx * 2^(-126) 为结果。

  E全为1,结果为 +/- 1.xxxx * 2 ^ (128),一个表示正负无穷大的数字.

  整型和浮点型在内存中的存放就说到这里,希望大家能够多多练习,熟悉掌握这两种类型在内存中的存放规则。

谢谢欣赏!!!!

本章完!!

C语言进阶(二)——整形存放练习已更新

代码编程
赞赏

相关文章

动态改变shape color
一张图看懂阿里云网络产品[一]网络产品概览
bug人生–CF的那段时光
地图常见操作总结
西门子医疗创新产品与解决方案亮相第31届国际医疗仪器设备展览会
WebView详解:Android和Js交互