数据在内存中的存储

整数在内存中的存储

  1. 原码:直接将数值按照正负数的形式翻译成二进制(正数0,负数1)
  2. 反码:原码的符号位不变,其余按位取反
  3. 补码:反码+1

数据存放内容中其实存放的时二进制的补码

大小端字节序和字节序判断

什么是大小端字节?

大端字节序存储:把一个数据的低位字节的内容存储到高地址处,把高位字节的内容存储到低地址处

也就是把高位的11存储到了低地址处

小端字节序存储:把一个数据的低位字节的内容存储到低地址处,把高位字节的内容存储到高地址处

高位 0x 11 22 33 44 低位

  1. 大小端字节序都有可能存在,而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,才是取决于指针的类型

浮点数在内存中的存储

  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

但是我们要认识的,浮点数是完全可能无法精确保存的

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值