您的位置:首页 > 编程语言 > C语言/C++

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

2021-04-15 11:53 871 查看


文章目录

[/ul]


一、数据类型详细介绍

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语言进阶(二)——整形存放练习已更新

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: