一、整数在内存中的存储:
1、存储方式:
以二进制的形式存储;(存储的是该数据的补码)
2、整数的原、反、补🐎:
原码——输出时以原码进行输出;(如你输入1,得先将1变成2进制就得到了原码)
补码——存储时以补码形式存储;
表示方式如下图:
最高位——>低位;
从低位开始进行二进制的转化;不足时补0;最高位则根据整数的正负号选择;
正数:原、反、补都是一样的;
负数:需要区别——>
原码:就是将负数化成二进制;最高位为1;
反码:原码的符号位不变,其他位按位取反(就是该位是0则取1,是1则取0);
补码:反码加1就是补码;
3、已知补码求原码:
给了补码求原码2个方法: 1) 补码取反加1;
2) 补码减1取反;
二、字符在内存中的存储:
1、存储方式:
也是存储的二进制但是,其中的原反补的规则遵循整数的;char型占1个字节,即8个比特位;那么排序方式就有2的8次方种即256种
存储图如下:
有2种类型 —— 有符号和无符号;(两种类型与编译器有关。)
1.有符号的:其中最高位也是表示正负;(范围:127 — -128)
2.无符号的:没有最高位的说法; (范围:0 — 255)
2、ASCII码值与字符密切的关系:
因为 根据内存中存储画的,所以都是补码的形式呈现给大家的啊;
以下时有符号char型;10000000 那里是为了不浪费,直接认为就是-128
无符号:就是到127往后走,后面的负数都变为了正数;
可以 发现0-127的ASCII码值刚好无论有无符号都是成立的;这样就保证了在各种编译器中都能使用;
3 、关于char型的使用
1)、有符号无符号,以整数形式打印
int main()
{
//VS中默认为有符号;
char a = -1;
//有符号
signed char b = -1;
//无符号
unsigned char c = -1;
printf("%d %d %d\n", a, b, c);
return 0;
}
通过整形的形式打印 a b c;
这是怎么回事;看下图,他们存储在内存中的二进制都是一样——>
但是当以整数打印时,因为整形为4个字节,所以需要整形提升;
原则:
无符号类型:前面补0
有符号类型:前面补符号位
2)、signed char :
#include<string.h>
int main()
{
int i = 0;
char arr[1000];
for (i = 0; i < 1000; i++)
{
arr[i] = -1 - i;
}
printf("%d\n", strlen(arr));
return 0;
}
计算长度 如下:
为什么呢??? 可以将其范围画成一个圆圈;他的值只能在这个圈里面旋转
当到-1到 -128后,就变成了127 一直到0,strlen计算结束;刚好为255;
三、浮点数的存储:
1、浮点数存的过程:
与整数的存储方式大不相同;我们一般先用(二进制的·)科学计数法表示;然后在进行存储;
国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:
如:5.0 的二进制为 101.0 变成 -1^0 * 1.010 * 2^2 (举例一般不会用过复杂的小数,如3.14,因为精度原因,不一定能正确的化为二进制;)
float 单精度——>32bit
dobule 双精度——>64bit
E为一个无符号整形,但是科学计数法是有负有正的,所以对于E我们会加一个中间值;
32位就是 E加127 转变为二进制 存入图中E占的内存空间;
64位就是 E加1023 转变为二进制 存入图中E占的内存空间;
M 因为默认都是由1.xxxxxx的形式,所以在存入时,将XXXXXX的部分存入M占据的内存区中,取出来时在前面添加 上 1 ;
2、浮点数取出来的过程(三种情况)
1)、E的内存区域全为0:
真实值E = 1-127(1-1023);表示0或者是无限接近 0,此时 M的默认1没有了,取出来的就是0.xxxxxxxx的形式,
2)、E的内存区域全为1:
有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s);
3)、E的内存区域不全为0或1 :
指数E的计算值减去127(或1023)得到真实值,再将有效数字M前加上第⼀位的1。(正常计算即可)
四、总结:
对于各种类型的存储有一定了解即可