目录
好久不见大家,就快开学了或者很多小伙伴们已经开学了,之前说到,变量是一个盒子,盒子里面装的是变量,那么接下来我们来讲盒子是怎么装数据的,也就是C语言数据存储方式。
C语言数据类型
C语言内置类型
char
| 字符型 |
short | 短整型 |
int | 整型 |
long | 长整型 |
long long | 更长的整型 |
float | 单精度浮点型 |
double | 双精度浮点型 |
类型意义
不同类型的变量向内存空间申请的大小是不同的,类型的使用范围也是不同的,也存在类型储存数据方式的不同
类型基本分类
我们根据类型的特点,可以分为一下几种
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)
为什么将这些归类为整形类,下面将会讲解
2.浮点型类
float
double
3.自定义类型
数组类型
结构体类型 struct
枚举类型 enum
联合体类型 union
4.指针类型
指针类型很多,并且有很多比较复杂的指针,这里列举几个比较简单的常用的指针
char* ptr_char
int* ptr_int
void* ptr
void*类型的指针可以接受所有类型的指针,并且void*通常是配合char*使用的,因为char*可以控制一个字节的大小
5.空类型
空类型void比较特别,通常用来代表函数返回值类型,代表函数没有返回值
数据存储方式
前面说了这么多,接下来讲一下今天的重要内容,数据存储的方式,char在整形类的原因就是因为存储方式和整形的一致的
整形的存储方式
在学习整形的存储方式之前,我们得先了解计算机整数的三种表达方式原码,补码和反码
共同点
三种表示方法都有符号位和数值位,符号位为一代表为负数,符号位为0为正数,对于无符号数和正数,三种码是一样的,但是对于负整数是不一样的
原码
直接根据数据打印的值翻译成二进制,并且符号位为1得到
反码
将原码除符号位的其他位按位取反得到
补码
将反码加一得到
补码的作用
在内存中,整形存储的是他的补码,并且用运算符进行操作的对象也是补码,也就是拿出变量中的补码来进行运算
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理; 同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程 是相同的,不需要额外的硬件电路。
补码的存储方式
数据在内存中存储的是补码,所以数据的存储方式其实就是补码的存储的形式
那我们来看看数据的存储方式吧
我们可以发现0x12345678在内存中是按照78 56 34 12存储的, 这个时候就需要介绍大小端字节序
大小端字节序
大小端字节序,可以看出,数据是按照字节顺序存储的,一个数都是有高字节和低字节
在内存中从左到右地址逐渐升高
我们可以发现地址的从高到底和数据的字节从高到低是相反的
大端存储模式
小端存储模式
大小端存在的意义
#include <stdio.h>
int test()
{
int i = 1;
char* ptr_c = (char*)&i; //char*的指针可以访问一个字节的大小
return *ptr_c;
}
int main()
{
int ret = test();
if (ret == 1) //当*ptr_c为1时说明第一个字节存储的是1,为小端
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
浮点型的数据存储方式
浮点数的数据存储方式和整型的数据存储差别很大,我们用一个程序来证明
#include <stdio.h>
int main()
{
int n = 9;
float* ptr_f = (float*)&n;
printf("n的值为:%d\n", n);
printf("浮点型的值为:%f\n", *ptr_f);
*ptr_f = 9.0f;
printf("num的值为:%d\n", n);
printf("浮点型的值为:%f\n", *ptr_f);
return 0;
}
我们可以看到,以浮点型和整型形式打印的值差别很大,那么浮点型的数据存储方式到底是什么呢
浮点数存储规则
根据国际标准IEEE(电气和电子工程协会)754规定,浮点数的存储方式遵循一下规则,任何一个一个二进制的浮点数都能变成以下形式
对于浮点数5.0,二进制的形式是101.0,按照规则后表示为
(-1)^0*1.01*2^2,S为0,M为1.01,E为2
因为M始终大于1小于2,所以M为1.********形式的,所以将可以将1去掉,只存储********部分
指数E
指数E本身是一个无符号数,但是根据浮点数存储规则是有符号数,以八位为例,E的值为0-255,但是E需要表示-128-127,这个时候需要一个中间值127来做到,每个浮点数的E都要加上127再转换成二进制位存储,64位则是1023,E的值存在两种特殊情况,E全为0,和E全为1
E全为0
当e全为0时,这是的M舍弃第一位的小数,而是还原成以0开头的小数,这是代表一个很小的数
E全为1
这时如果M的有效数字全为0,代表一个无穷大的数,符号位决定正负
今天的博客就分享到这