一:数据类型基本归类
整形家族
浮点型家族
构造类型
指针类型
.
有符号与无符号的区别
- 整型有无符号(unsigned)和有符号(signed)两种类型,在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类型的话就需要在类型前加上unsigned。
- 无符号整型和有符号整型的区别就是无符号类型可以存放的正数范围比有符号整型中的范围大一倍,因为有符号类型将最高位储存符号,而无符号类型全都储存数字。
- 注:浮点型float和double总是带符号的。
二:整形在内存中的存储
我们知道变量的创建是要在内存开辟空间的,而空间的大小是根据不同的类型决定的。
接下来我们谈谈数据在开辟内存中到底是如何存储的?
原码反码补码
- 计算机有符号数的三种表示方式:原码反码补码。
- 原码反码补码均有符号位与数值位两部分。
- 符号位就是原码反码补码最前面的那个数,如果是0就表示“正”,如果是1就表示“负”。而数值位三种表示方法各不相同。
原码:二进制序列就是原码
反码:原码符号位不变,其它位取反就是反码
补码:反码+1就是补码
注:正数的原码反码补码都相同!
1的原码反码补码
原码:00000000 00000000 00000000 00000001
反码:00000000 00000000 00000000 00000001
补码:00000000 00000000 00000000 00000001
而负数则与之不同
-1的原码反码补码
原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
对于整形来说:数据存放中其实统一存放的是补码。
为什么?
- 使用补码可以将符号位和数值统一处理
- 加法和减法也可以统一处理(CPU只要加法器)
- 补码与原码相互转换,其运算过程是相同的,不需要额为的硬件电路
如果使用原码进行运算。
而当使用补码进行运算时!
既然我们已经知道内存存储的是补码,接下来我们来看看数值在内存中的存储。
a在内存中存储的不应该是吗?
00 00 00 14
为什么,这里打印的地址顺序不对呢?
其实这是因为数据在电脑中存储存在大小端模式!
大端小端
- 大端(存储)模式:指数据的低位保存在内存的高地址中。而数据的高位,保存在内存的低地址中;
- 小端(存储)模式:指数据的低位保存在内存的低地址中。而数据的高位,保存在内存的高地址中;
大小端判断
设:ret=1
补码:00 00 00 01
大端:00 00 00 01
小端:01 00 00 00
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int ret = 1;
char*p =(char*)&ret;
if (*p == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
浮点型在内存中的存储
浮点型:两种
float型:大小为4Byte
double型:大小为8Byte
#include<stdio.h>
int main()
{
int a = 9;
float* p = (float*)&a;
printf("%d\n", a); //以整型的视角存储
printf("%f\n", *p); //以浮点数的视角读取
*p = 9.0; //以浮点型的视角存储
printf("%d\n", a); //以整型的视角读取
printf("%f\n", *p);
return 0;
}
通过上面的程序我们知道,即使浮点数与整数在内存存储的是同一个数,但是其解读起来可能却是不一样的。
这是因为浮点数与整数的存储是有区别的!!!
float型
- float型是遵循IEEE R32.24规范,包含三个主要成分:即1位符号位、8位阶码、23位尾数
- 计算方式:是先用科学计数法表示出该数的二进制,然后计算出阶码值,最后把尾数 补足23位,依此存储
三个主要成分是:
符号位:Sign(1bit):表示浮点数是正数还是负数。0表示正数,1表示负数
阶码:Exponent(8bits):指数部分。类似于科学技术法中的M*10N中的N,只不过这里是以2为底数而不是10。需要注意的是,这部分中是以27-1即127,也即01111111代表2^0,转换时需要根据127作偏移调整。
尾数:Mantissa(23bits):基数部分。浮点数具体数值的实际表示。
转换过程
double型
- double型跟float型计算方式类似,不过区别在于double型遵循IEEE R64.53规范
- double的符号位是1位,阶码为11位,尾数为52位