数据存储2

不知道上一篇文章大家有没有想过如何通过代码判断计算机是大端还是小端存储,还是这幅图片

假设一个变量a地址为0x11223344  

这里我们的思路是如果将这个地址的第一个字节提取出来如果是11,那么就是小端存储,如果是44,那么就为大端存储。这里我们就再举个简单的例子。假设变量的地址为0x00000001那么他的存储方式就有两种 

问题是我们应该如何拿到这个地址的第一个字节。这里我们要使用char型的指针,这里我们可以这样写

#define _CRT_SECURE_NO_WARNINGS 1//取消警告
#include<stdio.h>
int main() {
	int a = 1;
	char* p = (char*)&a;
	return 0;
}

这里a是一个Int型,但是我将他强制转换成char就可以取出他的第一个字节,那么当这个取出来的指针所解引用的值为0时

#define _CRT_SECURE_NO_WARNINGS 1//取消警告
#include<stdio.h>
int main() {
	int a = 1;
	char* p = (char*)&a;
	if (*p == 1) {
		printf("大端存储");
	}
	else {
		printf("小端存储");
	}
	return 0;
}

 现在就来看一些题目,来让大家对数据的储存有更深层次的理解

#define _CRT_SECURE_NO_WARNINGS 1//取消警告
#include<stdio.h>
int main() {
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a =%d , b=%d , c = %d", a, b, c);
	return 0;
}

大家可以看一下这段代码,看一看最后会输出什么

 这里我懒为大家解释出现这样状况的原因-1在计算机内部的补码为

11111111111111111111111111111111

但是char只有一个字节,所以他只储存了11111111,8个比特位,也就是8个1

signed表示有符号,所以b其实和a是一样的,但是c是unsigned,表示无符号虽然也是8个1,但是最高位的1是有效数字。a和b在计算机眼中认为最高位的1是符号位,代表负号,那么对于a,b来说这8个1表示出来的原码就应该为10000001,换算成十进制就是-1,正数的原码,反码,补码都相同,所以在计算机中c的原码应该为11111111,再转换成十进制为225,所以才会有以上的输出。

计算机中char 实际上是unsigned char 还是signed char 这个c语言中并没有规定,其他的数据类型均是有符号的

现在再来看一下这段代码

#define _CRT_SECURE_NO_WARNINGS 1//取消警告
#include<stdio.h>
int main() {
	char a = -128;
	printf("%u", a);
	return 0;
}

看一下这段代码会输出什么,%u代表了无符号数,大家可以先自己猜一下这段代码会输出什么

 这里我们这样思考,-128的原码为10000000000000000000000010000000

反码为11111111111111111111111101111111

补码为11111111111111111111111110000000

所以在计算机内部储存a应该为10000000

这里我们是以%u进行打印的,在输出时会把a看作一个有符号的整形,那么在内存中看到的a就会在前面不断补上符号位,最后就为11111111111111111111111111000000这里把他转换成十进制,就是以上看到的数了

以上就是一些题目,这里我来扩展一下char类型的取值范围只看二进制,char类型有8个字节,能取得数从00000000~11111111总共能去这么多数,其实char类型的取值反右有点偏向于一个环

当01111111再+1的时候就会变成-128 

最后还有一道题,希望大家能够算一下这道题

#define _CRT_SECURE_NO_WARNINGS 1//取消警告
#include<stdio.h>
int main() {
	char i = -20;
	unsigned int j = 10;
	printf("%d", i + j);
	return 0;
}

其实结果非常简单,就是-10,但是这里我什么不像之前char类型一样,是一个非常大的数字呢?

 这两个数相加,无非就是这两个数在内存中的二进制序列相加 

i的补码为11111111111111111111111111101100

j为正数,所以原码反码补码相同,为00000000000000000000000000001010

两二进制序列相加应该为111111111111111111111111111110110——补码

这里最后再转换为补码就为10000000000000000000000000001010——>-10

这篇文章就讲这么多,感觉写这种偏底层一点的文章好像看的人确实比较少,不过如果真正的想学好计算机,计算机底层的二进制不能不学,虽然看的人少,不过还是要继续写下去

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值