C语言 数据存储 char int 数据存储 关于原码反码补码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

上图 前五个整形是整形家族,为什么char也是 因为他是字符型 字符实际存储的时候寸的是这个的ascll值 ascll值是个整数
在这里插入图片描述


除了以上两种 还有构造类型 又叫自定义类型
在这里插入图片描述
为什么又数组类型 如下代码 arr和【】的内容都可以自定义
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


在这里插入图片描述
为什么出现以上情况.(ffff 是16进制表示形式)
-10放到内存中应该先显示原码
按照数据的设置直接写出的二进制序列就是原码
原码符号位不变,其他位按位取反,得到就是反码
反码+1得到就是补码

数据在内存中以2进制的形式存储
对于整数来说
整数二进制又3中表示形式:原码 反码补码
正整数“原码 反码补码相同
负整数:原码反码 补码要进行计算

int main()
{
	int a = -10;
	//
	//1000000 00000000 00000000 00001010 原码
	//1111111 11111111 11111111 11110101  反码
	//1111111 11111111 11111111 11110110  补码
	//换算成16进制
	//fffffff6
	return 0;
}

两个十六进制数就等于八个二进制数

所以得出整数在内存存储的时候以二进制补码存储的

那么为什么存补码

在这里插入图片描述

cpu只有加法器 比如 1-1 是不行的实际上它是 1+(-1)

int main()
{
	//1+(-1)
	//000000000000000000000000001    1的原码
	//100000000000000000000000001    -1的原码
	//100000000000000000000000010     的出来-2



	//000000000000000000000000001 正数原反补相同  这是1的补码
    //111111111111111111111111111  -1补码
	//1000000000000000000000000000  相加的结果多一位。只能32为 多了一位就进上去  1就丢了所以结果全0 

	return 0;
}

在这里插入图片描述
所以出现以下情况

在这里插入图片描述

int main()
{
	int a = 10;
	int b = -10;
	//00000000000000000000001010
	//0000000a  转化为16进制


	return 0;
}

大端 小端字节序

在这里插入图片描述

11是高位 44是低位

在这里插入图片描述
所以判断这个代码是小端存储


98

在这里插入图片描述
拿第一个字节用char类型变量 然后强制类型转换为int

int main()
{
	int a = 1;
	char* pa = (char*)&a;//a放整形地址所以需要强制类型转换
	if (*pa == 1)
	{

		printf("小端字节序");
	}
	else
	{
		printf("小端字节序");
	}
	return 0;
}

写成一个函数如下

int check_sys()
{
	
		int a = 1;
		char* pa = (char*)&a;
		if (*pa == 1)
		{

			return 1;
		}
		else
		{
			return 0;
		}
		
	

}



int main()
{
	int ret = 0;
	ret = check_sys();
	if (ret == 1)
	{

		printf("小端字节序");
	}
	else
	{
		printf("小端字节序");
	}
	return 0;
}

函数还可以更简洁 如下

int check_sys()
{
	
		int a = 1;
		char* p = (char*)&a;
		return *p;//返回一表小端  0表大端
	

}



int main()
{
	int ret = 0;
	ret = check_sys();
	if (ret == 1)
	{

		printf("小端字节序");
	}
	else
	{
		printf("小端字节序");
	}
	return 0;
}

计算abc的打印结果

int main()
{
	char a = -1;
	//100000000000000000000001    原码
	//111111111111111111111110    反码
	//111111111111111111111111    -1的补码
	//11111111  因为char是一个字节  一个字节8个bit位
	//11111111111111111111111  整型提升为全1  补码形式整型提升
	//10000000000000000000001          打印原码


	signed char b = -1;
	unsigned char c = -1;
	//00000000000001111111111整形提升    c是无符号整形提升高位补0 .因为整数原反补相同
	printf("a=%d b=%d c=%d", a, b, c);
	//整型提升看的是符号位提升  打印的时候看的是原码`在这里插入代码片`
	return 0;
}//输出结果为 -1  -1 255   c是无符号整形提升高位补0 .因为整数原反补相同

在这里插入图片描述


下面程序输出的结果


int main()
{
	char a = -128;
	//10000000000000000000000010000000
	//11111111111111111111111101111111
	//11111111111111111111111110000000  补码
	//10000000  需要整型提升 char是有符号的 高位1就认为是符号位所以高位补1
	//11111111111111111111111110000000   打印是u无符号为打印 他的高位就不是符号位。相当于他是正数.所以最后结果就是这个  



	printf("%u\n", a);

	return 0;
}

**输出结果为4294967168

如果换成%d 打印结果为-128**

第三题

int main()
{
	char a = 128;
	printf("%u", a);

	return 0;
}

解析如下

int main()
{
	char a = 128;
	//00000000000000000000000010000000 原反补相同
	//10000000
	//整型提升看的是原来的类型 char是有符号位  所以高位补1
	//11111111111111111111111110000000
	//%u 打印 是无符号数  无符号数原反补相同
	printf("%u", a);

	return 0;
}//输出结果 4294967168

就上面的描述探讨下char的取值范围

一个char类型 8个bit位 存放数据可能出现的情况有以下几种
00000000 0
00000001 1
00000010 2
011111111 127
分割线 以上全为正数
10000000 -128 那么为什么
10000001 10000000 11111111 -127
.。。
11111110 11111101 10000010 -2
11111111
11111110 10000001 -1

为什么 解答如下
-128
10000000 00000000 00000000 10000000
111111111 111111111 111111111 011111111
111111111 111111111 111111111 10000000 这后8位刚好与上相同

所以得出结论 有符号的char取值范围是:-128~127取值范围
放不进去128 只是发生了截断 截断一部分值而已

第四题

int main()
{
	int i = -20;
	//100000000000000000000010100
	//111111111111111111111101011
	//111111111111111111111101100  补码
	unsigned int j = 10;

	//000000000000000000000001010
	printf("%d\n", i + j);
	//先相加再打印   
	//111111111111111111111101100  补码
	//000000000000000000000001010
	
	//111111111111111111111110110补码  因为%d打印原码再进行转换
	//111111111111111111111110101    -1得反码
	//100000000000000000000001010    取反  的原码
	//

	return 0;
}结果负10

第五题

//5
int main()
{
	unsigned int i;
	for (i = 9; i >= 0;)
	{          //i>=0恒成立 无论怎么变都死循环 。条件为假才停下来最低等于0

		printf("%u\n", i);
	}

	return 0;
}//结果死循环  unsigned永远不要定义等于0否则死循环,i-- i的值被释放成一个正整数 所以不可能是-1 所以i永远大于等于0

第六题

int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;


	}
	printf("%d", strlen(a));

	return 0;
}

在这里插入图片描述
如上分析 char类型取值范围-128到127

int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;


	}
	//-1 -2  -3 ...-127 -128 127 126 125 ...3 2 1 0  -1  -2 ..-127 -128   127
	printf("%d", strlen(a));//求a数组里的  找到\0    其实就是找0  \0的ASCII码是0

	return 0;
}
//-1一直被减,直到-128,跳到127继续被减,然后到0,而strlen遇见0就结束






拓展 129放进去会变成什么

**129相当于127加2 当你把129存进去的时候的到的是-127 不会是129 **
129 原码 存入char截断第二部
0000000000000000000010000001
10000001补码
10000000
111111111 原码
-127

在这里插入图片描述

第7题

unsigned char i = 0;
int main()
{
	for (i = 0; i < 255; i++)
	{

		printf("hello world\n");
	}


	return 0;
}//unsigned char 最大时255 所以死循环

浮点型预知

在这里插入图片描述
在这里插入图片描述
下篇讲解…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值