一、数据的类型
char //字符数据类型 1个字节
short //短整型 1个字节
int //整形 4个字节
long //长整型 4个字节
long long //更长的整形 8个字节
float //单精度浮点数 4个字节
double //双精度浮点数 8个字节
二、类型的基本分类
分为整形家族、浮点数家族、构造类型、指针类型、空类型
1、整形家族
char | |
unsigned cha | |
signed char |
short | |
unsigned short [int] | |
signed short [int] |
int | |
unsigned int | |
signed int | |
long | |
unsigned long [int] | |
signed long [int] |
在上面这个表格中就是整形家族所包含的就是整形家族的成员,里面的char类型就挺有意思,众所周知char类型是字符类型,可是为什么会把它归类在整形家族里呢?那是应为char类型的字符,存储在内存里面是以ASCLL码值的形式存储的,而ASCLL码值又是整形,所以就把他归类在整形家族里面了,而每种类型又分为无符号和有符号类型。
unsigned 就是无符号类型,而signed是有符号数,拿char类型举例char的无符号数的取值范围是0-255,而有符号数是-128-127。就如下图所示
在内存中的数据是以二进制的补码进行储存的,而正数的原码、反码、补码是一样的,负数的反码是原码的按位取反,补码则是反码+1,如下图所示
所以在char类型中,它是1个字节,8个比特位,在正数的情况下,原反补一样,所以取值范围是0-255,有符号的情况下,则在127之后第128个数的第一位是1,就变成负数了,第128个数是10000000,他比较特殊,规定为-128,其他的就是正常求值,所以在有符号的情况下取值范围就是-128-127。
同理,其他类型的有符号和无符号取值范围也都是两种。一般定义变量的时候都是不写signed的,因为编译器大部分都是默认是signed的,当然也可以写。
2、浮点家族
这个家族只有float 、double两个。
3、构造类型
> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
没看错,数组类型也是构造类型,例如:arr[10]={0};这个定义的数组中,arr是数组名,【】这个就相当于解引用,而且他也是一堆数据放在这个类型中,所以他是构造类型。结构体就更是构造类型了,因为我们在定义结构体的时候,一般里面放的不止一种类型,所以他也是构造类型,枚举和联合体都是一样的。
4、指针类型
int * pi ;
char * pc ;
float* pf ;
void* pv ;
5、空类型
void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型。
三、大小端存储
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。
就像图片中所示,我们定义了一个变量a并且以16进制的形式赋值成11223344所以VS201就是小端存储模式。
四、浮点数在内存中的存储
整数就不说了,在上文中已经说过了,浮点数比较特殊,根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^s 表示符号位,当 s=0 , V 为正数;当 s=1 , V 为负数。
M 表示有效数字,大于等于 1 ,小于 2 。
2^E 表示指数位。
我们就拿: 十进制的5.0 ,写成二进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上面 V 的格式,可以得出 s=0 ,
M=1.01 , E=2 。
十进制的 -5.0 ,写成二进制是 - 101.0 ,相当于 - 1.01×2^2 。那么, s=1 , M=1.01 , E=2 。
IEEE 754 规定:
对于 32 位的浮点数,最高的 1 位是符号位 s ,接着的 8 位是指数 E ,剩下的 23 位为有效数字M,如图所示,同理64位的浮点说就是1位是 符号位 s ,接着的 11 位是指数 E ,剩下的 52 位为有效数字 M,在M位没有用完剩下的位数时,我们全部补零。