整数在内存中的存储
- 原码:直接将数值按照正负数的形式翻译成二进制(正数0,负数1)
- 反码:原码的符号位不变,其余按位取反
- 补码:反码+1
数据存放内容中其实存放的时二进制的补码
大小端字节序和字节序判断
什么是大小端字节?
大端字节序存储:把一个数据的低位字节的内容存储到高地址处,把高位字节的内容存储到低地址处
也就是把高位的11存储到了低地址处
小端字节序存储:把一个数据的低位字节的内容存储到低地址处,把高位字节的内容存储到高地址处
高位 0x 11 22 33 44 低位
- 大小端字节序都有可能存在,而vs中是小端字节序存储,所以我们看到是倒着存储的值
练习
练习一
设计一个小程序来判断当前机器的字节序
将地址强制类型char*再解引用,再去判断
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int i = 1;
//0x00 00 00 01
if (*(char*)&i == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
封装成函数
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int check_sys(int i)
{
if (*(char*)&i == 1)
return 1;
else
return 0;
}
int main()
{
int i = 1;
//0x00 00 00 01
int ret = check_sys(i);
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
练习二
signed char a:有符号的
unsigned char b:无符号的
如果signed char类型,那么内存中最高位就被当做符号位
char中只存8个比特位,一个字节
10000000——-128
signed char类型取值范围是-128~127
char是有符号还是无符号,这取决于编译器
在vs上,char==signed char
只存放8个bit位
虽然类型不同,但存放的都是8个1
%d打印时,补码要转换为原码
整型打印要提升,看是不是有符号的,a和b都是signed char,所以需要补符号位
11111111——提升它
11111111 11111111 11111111 11111111——补码
再将其转化为原码就是-1
10000000 00000000 00000000 00000001
所以a和b打印出来都是-1
c是unsigned char类型
整型提升高位补0
00000000 00000000 00000000 11111111
%d是认为内存存放的是有符号数,0是正数,所以原码补码反码都相同,直接打印,打印出来255
整型提升:如果是有符号数,那高位按照符号位来提升,如果是无符号数,高位按照0来提升
练习三
%u打印,是认为打印的a是无符号数
首先写出原码
再将其转化为补码——先取反后+1
只能存放8个bit位,所以是10000000——1是符号位
计算需要整型提升,他是char类型,是有符号的,高位为符号位,所以使用1将其提升
11111111 11111111 11111111 10000000
最后使用%u打印时,%u并未将开头的1看做成符号位,它将a认为是无符号数,所以打印的是一个非常大的数4294967168
练习四
00000000 00000000 00000000 10000000——为正数,原码反码补码一样
10000000——a
整型提升
11111111 11111111 11111111 10000000——补码
打印的出来是原码,但%u认为是无符号数,所以原反补相同,打印4294967168
127+128=255
练习五
i是无符号的char类型
unsigned char的取值范围在0-255
所以for循环的条件是恒成立的,所以会造成死循环
练习六
ptr2:
内存中存放:01 00 00 00 02 00 00 00 03 00 00 00
将a转化为int类型后+1,整型+1就是+1,一个整型有四个字节,+1就只+1个字节
int向后访问四个字节,因为是小端字节序,所以访问的是0x02 00 00 00
指针+1,才是取决于指针的类型
浮点数在内存中的存储
- 范围:float.h中定义
5.5写成二进制
101.1=1.011*2^2
v=(-1)^0 * 1.011 *2^2
浮点数的存储
对32位浮点数(float),最高的1位为存储符号S,接着的8为存储指数E,剩下的23为存储有效数字M
对64位浮点数(double),最高的1位 为存储符号S,接着的11位存储指数E,剩下的52位存储有效数字M
浮点数存的过程
IEEE745对有效数字M和指数E,还有一些特别的规定
1<=M<2,也就是说M可以写成1.XXXXX的形式,其中XXXXX表示小数部分
计算机内部保存M时,默认第一位总是为1,因此可以被舍去,只保存后面的xxxx部分。比如保存1.01的时候,只保存01,读取时,再将第一位的1加上去。这样就可以节省一位有效数字
E为一个无符号整数,它的取值范围是0~255,但是在科学计数法中E是可以出现负数的。比如0.1=1*2^(-1),此时E=-1。所以IEEE745规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E这个中间数是127,对于11位的E,中间数是1023。
比如2^10的E是10,所以保存成32位浮点数是,保存成10+127=137,即10001001
例
但是我们要认识的,浮点数是完全可能无法精确保存的