深度剖析数据在内存中的存储 —— 上

数据类型的介绍

前面我们已经学了很多的数据类型:现在我们对它们进行一个整体的分类

整型家族
char
unsigned char
signed char
short
unsigned short
signed short
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]

浮点数家族

float //4个字节
double // 8个字节

构造类型

数组类型
结构体类型 struct
枚举类型 enum
联合类型 union

指针类型

int* pi;
char* pc;
float* pf;
void* pv;

空类型

void 表示空类型
通常应用于函数的返回类型、函数的参数、指针类型

类型的意义:

使用这个类型开辟的内存空间的大小。
如何看待内存空间的视角

整型在内存中的存储

我们之前讲过一个变量的创建是要在内存里开辟空间的。空间的大小是根据不同的类型而决定的。

那么数据在内存中的存储是怎么样的?

原码、反码、补码

计算机中的整数由三种2进制的表示方法,即原码、反码和补码。
原码:把原来的数据转换成2进制数。
反码:把原码按位取反。(符号位不变)
补码:补码+1。
整数的原反补相同
int a = 20;
20的原码 32位二进制数表示,因为是int类型。

例子:

int a = 10;
//00000000 00000000 00000000 00001010 - 原码
//00000000 00000000 00000000 00001010 - 反码
//00000000 00000000 00000000 00001010 - 补码
int b = -10
//10000000 00000000 00000000 00001010 - 原码
//111111111 111111111 111111111 11110101 - 反码
//111111111 111111111 111111111 11110110 - 补码

在计算机中的内存里存放的是数据的补码。这个是非常重要的,一定要记住。

大小端的存储

大端模式:把数据的低位存储到高地址处,高位存储到低地址处。
小端模式:把数据的低位存储到低地址处,高位存储到高地址处。
``

我们来看一下小端存储的样式。这里到底是大端模式还是小端模式完全由计算机决定。
通过代码来验证该编译器是什么类型的存储

#include <stdio.h>
int check_sys()
{
	 int i = 1;
	 return (*(char *)&i);
}
int main()
{
 	int ret = check_sys();
 	if(ret == 1)
	 {
 	printf("小端\n");
	 }
	 else
	 {
	 printf("大端\n");
	 }
	 return 0;
}

如果是小端存储返回一,大端存储返回零。
visual studio 2022 的运行结果为:
小端存储的验证
接下来我们看一些练习:

#include <stdio.h>
int main()
{
	char a = -1;
	//10000000000000000000000000000001 - 原码
	//11111111111111111111111111111110 - 反码
	//11111111111111111111111111111111 - 补码
	//11111111 - 截断
	// 要打印整型提升
	//11111111111111111111111111111111 - 补码
	//11111111111111111111111111111110 - 反码
	//10000000000000000000000000000001 - 原码
	//a = -1
	signed char b = -1;
	//11111111111111111111111111111111 - 补码
	//11111111111111111111111111111110 - 反码
	//10000000000000000000000000000001 - 原码
	//b = -1
	unsigned char c = -1;
	//11111111111111111111111111111111
	//发生截断
	//11111111
	//无符号整型提升直接补0
	//00000000000000000000000011111111
	//c = 255
	printf("a = %d,b = %d,c = %d\n", a, b, c);
	return 0;
}
#include <stdio.h>
int main()
{
	char a = -128;
	100000000000000000000000100000000
	111111111111111111111111011111111
	111111111111111111111111100000000
	截断
	10000000 - a

	printf("%u\n", a);
	无符号整数打印,整型提升,按a 的类型进行整型提升
	111111111111111111111111110000000 
	无符号数的原反补都相同,按无符号打印时直接把内存中的补码按无符号打印
	也就是把111111111111111111111111100000000这一串二进制序列按原码输出
	return 0;
}

#include <stdio.h>
int main()
{
	char a = 128;
	//00000000000000000000000010000000
	//正数原反补都相同
	//00000000000000000000000010000000
	//10000000 - a
	printf("%u\n", a);
	//11111111111111111111111110000000
	//把这串二进制序列按无符位输出,也就是说把11111111111111111111111110000000
	//这一串按原码输出(无符号数的原反补都相同)
	return 0;
}

好的这部分内容就讲到这里。我们下期见。``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值