0
点赞
收藏
分享

微信扫一扫

8k字详解整型(int)/字符型(char)/浮点型(float)数据在内存中的存储【程序员内功修炼/C语言】

前言

1. 数据类型介绍

这里链接已介绍了基本的内置类型以及它们所占内存空间的大小

char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数

复习一下类型存在的意义:

1.1 类型的基本归类

整型:

char
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]

浮点数:

 float
 double 
 long double

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

> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union

例如

指针类型

int *pi;
char *pc;
float* pf;
void* pv;

空类型:

2. 整形在内存中的存储

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

2.1 原码、反码、补码

计算机中的整数有三种表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,正整数三码相同,所以以一代三;而负整数的三种表示方法各不相同。正负整数都以补码的形式储存在内存中,而它们实际的值由原码转换而来,所以要得到负数的值,首先要得到补码,然后再算反码,最后得到原码。

原码

反码

补码

对于整型数据来说:数据以补码的形式存放在内存中,Why?

不得不佩服早期的计算机科学家能想到用反码补码。

对于以下代码,我们查看它们在内存中的存储:

int a = 20;
int b = -10;

如果是刚学会二进制的同学,不妨将a和b的值转化为32位的二进制编码吧,它们的16进制编码分别为:0x 00 00 00 140x ff ff ff f6

一直有个疑问,为什么这里的地址是倒过来的呢?但又不是整个,而是两个一对地倒?
且看下面的讲解吧!

2.2 大小端介绍

什么是大小端:

为什么会有大端和小端呢?

2.2.1 大小端例子

int a = 0x11223344

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

2.3 练习

2.3.1

思路:

优化:

怎么只取一个字节比较呢

理清思路:

代码呈现:

//代码1
#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;
}

2.3.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;
}

先思考,再往下看
变量的类型,打印的格式?

结果:
在这里插入图片描述
a分析:

在这里插入图片描述

c分析:
在这里插入图片描述

体会

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

常见的浮点数:

3.1 举个栗子

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可以表示成下面的形式:

举例:

小结

IEEE 754规定:

IEEE 754对有效数字M和指数E,还有一些特别规定。

至于指数E,情况就比较复杂。

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

E不全为0或不全为1

E全为0

E全为1

小结

4. 取出规则

4.1 E不为全0或不为全1

4.2 E全为0

4.3 E为全1

5. 重新分析第一题

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

结果:
在这里插入图片描述

  • 对于前两行(第二行)结果
  • 对于后两行(第二行)的结果
    **补:储存M值的时:去掉小数点前的1,如果小数点位数用完了,补0**

6. 浮点数的比较

举报

相关推荐

0 条评论