一.数据类型介绍
1.1 数据的基本归类
之所以里面包含字符是因为字符在内存中存储的是字符的ASCII码值,ASCII码值是整数,所以字符类型归类到整形。
有符号位说明会把8位中的最高位当成符号位,而无符号位则是8位都是实际数值。
二.整型在内存中的存储
2.1 原码,反码,补码
2.2 大小端介绍
我们通过调试输入a,b地址来看内存的时候发现了一个现象,b应该是ff ff ff f6 ,a应该是 00 00 00 14,但在内存的表示中是倒过来的,这又是为什么呢?
int a = 0x11223344 低位放低地址处——小端字节序存储。低位放在高地址处——大端字节序存储。
2.3 练习
2.3.1
可以通过判断数值的第一位来验证大小端,这时候用数值1来进行试验。
我们如何取得第一位字节的地址呢?只需要对a的地址进行char*的解引用就行了,char是一位字节,那么char*只能访问一个字节的地址了,由于是用char*强制转换int 类型,所以接收也要用到char类型变量。
int main() { int a = 1; char* p = (char*)&a; if (*p == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
注意这样子写是错误的,已经把a的值拿出来再转换是没用的,因为那并不是把第一个字节拿出来。
2.3.2
结果是:
为什么会是这个结果呢?接下来我来为大家讲解:
所以我们又回来开始的地方进行整形提升:
2.3.3
2.3.4
接下来我们继续练习:
其实结果一样,因为截的低8位一致:但有个问题char的范围是-128-127,怎么能存下128呢?
由于-128没法计算,所以只能默认规定10000000为-128
从下面两张图可以看出,这些数都是可以轮回的,就比如11111111再加1那么就变成00000000了。
2.3.5
2.3.6
在无符号整形中,i的范围是>=0的,这样在条件中只会无限循环,因为它永远满足>=0的条件。
2.3.7
还是涉及到了之前的轮回图:
2.3.8
条件恒成立,无限死循环
三.浮点型在内存中的存储
3.1 例子
以整形形式放进去,那就以整形形式取,以浮点型形式放进去,那就以浮点数形式取。
3.2 浮点数存储规则
我们可以看到到写出二进制数时先移位成1.011,再乘以2的2次方(因为2进制移位),又因为是正数,再补上-1的0次方。
最高位存s=0;存E时为2+127——10000001,再存m-011,剩下的20位补0
以上是存储操作,接下来是取:
规则介绍完毕,现在我们回到最开始的问题:
因为是用float存储,所以接下来的二进制序列它会识别成S E M的形式,我们发现E为全0,套用如下规则:
真实情况:可以看到,这个数已经是趋近于0了,小得无法想象。
S为0 老规矩 3+127为130 ——10000010,因为是要打印整形,以n的视角看它就是补码,所以取反+1变成原码并打印。