文章目录
一、数据类型
1、基本的内置类型
char | 字符型 | 1 |
---|---|---|
short | 短整型 | 2 |
int | 整型 | 4 |
long | 长整型 | 4/8 |
long long | 更长的整型 | 8 |
float | 单精度浮点型 | 4 |
double | 双精度浮点型 | 8 |
2、类型基本归类
整型
char//字符存储的时候存的是Ascll码值,是整型
short
int
long
浮点型
float
double
构造类型
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
指针类型
int* pi
char* pc
float* pf
void* pv
空类型
void表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型
二、整型在内存中的存储
1、原码反码补码
计算机中的整数有三种2进制表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而对于数值位:
- 正数的原、反、补码都相同。
- 负整数的三种表示方法各不相同。
原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
可以看到a和b是以补码形式存储在内存中的,但16进制的顺序却是反的。
2、大小端
三、浮点型在内存中的存储
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;
}
如果不了解浮点数的存储,可能会觉得这串代码输出结果为
9 | 9.000000 | 9 | 9.000000
可结果真的是这样吗
num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?
要理解这个结果,就一定要搞懂浮点数在计算机内部的表示方法。
2、浮点数存储规则
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
举例来说:
十进制的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。
3、对有效数字M和指数E的特别规定
对于M:
对于E:
1)E为一个无符号整数
2)指数E从内存中取出还可以再分成三种情况:
E不全为0或不全为1
E全为0
E全为1
4、对例子的解释
了解了浮点数在内存中的存储我们就可以解释之前例子中代码的两个不一样的输出结果:
1)为什么 0x00000009 还原成浮点数,就成了 0.000000 ?
9用16进制表示为0x00000009,将 0x00000009 拆分得到
- 第一位符号位s=0
- 8位的指数 E=00000000
- 最后23位的有效数字M=000 0000 0000 0000 0000 1001
所以9可表示为:
0000 0000 0000 0000 0000 0000 0000 1001
可以看出指数E全为0,对于这种特殊情况,浮点数V可以写为:
V=(-1)^0 × 0.00000000000000000001001×2^(-126) =1.001×2^(-146)
显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。
2)浮点数9.0,如何用二进制表示?还原成十进制又是多少?
9.0表示为二进制1001.0即1.001×2^3
- s=0
- M=1.001
- E=3+127=130
第一位的符号位s=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130,即10000010。
所以,写成二进制形式为:
0 10000010 001 0000 0000 0000 0000 0000
还原为十进制结果就为 1091567616 。