关于unsigned,signed 数据储存的三道题详解

code1


#include <stdio.h>
#include <windows.h>
int main()
{
	char a[1000];
	int i;
	for (i = 0; i<1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a)); //strlen介绍,字符串认识,\0的认识
	return 0;
}
//首先我们需要明白char 类型的取值范围是[-128,127],strlen结束是看'\0',这里'\0'不算本身的数据。
//这里当i=0 :-1;i=1:-2...........i=-127:-128;........i=128:127;
//这里-1的原反补如下
//1000 0000 0000 0000 0000 0000 0000 0001 原
//1111 1111 1111 1111 1111 1111 1111 1110 反
//1111 1111 1111 1111 1111 1111 1111 1111 补码
//-1+-1的计算过程
//1 1111 1111 1111 1111 1111 1111 1111 1110
//通过截断 1111 1110  取原码 :1111 1101->1000 0010 =-2
//那么就针对特殊的i=127进行-1+(-127)的操作:因为这里是“系统”先进行处理之后在存入的
//-127补码1000 0001 + -1的补码 :1111 1111 = 1 1000 0000 这里就是 -128 
//-128 补码1 1000 0000 + -1的补码 :1111 1111 =1 0111 1111 这里经过截断 :0111 1111 ->127
//又因为这里符号位是正 所以补码就等于原码
//这里因为-1+(-128)本身就越界了,变成整数是很正常的 同样这就是数学家的高明之处 
//那么跟数据的存储是连续的规律 -1....-128 ..127 ...0...-128
//这里到0了就会结束 那么结果就是-1...0 中有256个元素减去0 等于 255

 

所以就有这样一副关于char的图:

 

code2

#include <stdio.h>
#include <windows.h>
int main()
{
	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);
}
//这其实一看就应该想到答案为 -10 :因为i,j的类型与初始化的值是完全匹配的,
//那么计算机肯定是得出我们想要的正确的答案 -10
//尽管我们知道 我们计算机的方式来还是计算一下
//-20 原码:1000 0000 0000 0000 0000 0000 0001 0100
//反码:1111 1111 1111 1111 1111 1111 1110 1011
//补码:1111 1111 1111 1111 1111 1111 1110 1100
//10的补码:0000 0000 0000 0000 0000 0000 0000 1010
//10的补码与-20的补码相加得:1 1111 1111 1111 1111 1111 1111 1111 0110
//取的原码 1 1000 0000 0000 0000 0000 0000 0000 1010 =-10

 

那么当我们用%u打印呢? 想必大家也应该知道了结果为:4294967286

二进制:1111 1111 1111 1111  1111 1111 1111 0110

得出结论:同样的二进制被不同类型解释的时候,它会表现出不一样的值,那么这个就是类型的价值,所以类型决定我们如何解释内存当中二进制的序列的含义

code3

#include <stdio.h>
#include <windows.h>
int main()
{
	unsigned int i;
	for (i = 0; i >= 0; i--){
		printf("%u\n", i);
	}
	system("pause");
	return 0;
}
//那么这道题的答案是什么呢?答案是死循环。
//为什么是死循环呢? 首先我们应该知道 第一次打印:0
//第二次打印0--为-1那么这里是无符号数 所以为4294967295
//二级制为:1111 1111 1111 1111 1111 1111 1111 1111
//那么-1 变成了4294967294 又继续对他减减操作 当减到0时减减 又会变成4294967294
//那么它就变成了死循环

 那么当我们for (i = 0; i >= 0; i--)改成for (i = 0; i >= 0; i++) 会怎么样呢?

其实相反的道理

它会从1加到4294967295 二级制为:1111 1111 1111 1111 1111 1111 1111 1111

当加到4294967295时在加1时

二级制会从32位多1位  二级制:1 0000 0000 0000 0000 0000 0000 0000 0000

这里会发生截断获取后32位bite位,那么结果0

又继续加到 1.......4294967295 ......0.....4294967295......

猜你喜欢

转载自blog.csdn.net/includeevey/article/details/125262823
今日推荐