深度剖析整型数据在内存中的存储

前言:在上一篇博客中,我们明白了整型在内存中的存储方式,并简单的介绍了整型提升,现在,我们将继续深入学习整型数据在内存中的存储。

char类型

整型提升

请看如下代码:

//  大家觉得打印结果是什么呢,或者这样写能打印吗?
	char a = 10;
	printf("a=%d", a);

运行后,控制台窗口显示结果如图:
在这里插入图片描述
看到这里,相信有的朋友会有疑问:char不是专门用来存放字符的吗,为什么会输出整型值10呢?
详解如下:
1.char类型我们可以将它看作是一种特殊的整型,占据1个字节,即8个比特位。
2.不管变量类型是什么,我们往内存中存入整型数,就是将它的2进制补码存进去,而展示出来的结果,则按照它的解读方式(%d,%u等等)来展示
3.整型在内存中以补码形式存储,输出则以原码形式

	char a = 10;
//  00000000 00000000 00000000 00001010  原码
//  00000000 00000000 00000000 00001010	 反码
//  00000000 00000000 00000000 00001010  补码
//  char占8比特位,截断—— 00001010 (10的补码的后8位)
//  输出形式是%d,占32比特位,则需整型提升,补符号位,00001010即补0
//  00000000 00000000 00000000 00001010 —补后的反码 ——符号位为0,则是正数,原反补码相同
//  读原码为10,则输出结果是10

char类型存储范围

我们知道int类型的存储范围是-2^31 ~ 2^31-1,以此类推,那么char类型的存储范围是多少呢?
在这里插入图片描述
上图皆为补码

  char类型占据8个比特位,则最大正数的补码为01111111,即127,01111111再加上1则变为10000000
  10000000开头为符号位,符号位为1则代表了它是一个负数,即-128,往后数字以此类推,构成一个循环。

所以char类型的取值范围是-2^7 ~ 2^7-1(-128 ~ 127)

unsigned char 类型存储范围

上面我们讨论了char类型的存储范围,请你来尝试求出unsigned char 类型的存储范围。

具体求法与上述大致相同,char类型占据8个比特位,01111111,即127,01111111再加上1则变为10000000
但这是无符号类型,开头并不是符号位,所以10000000我们直接读成128,则最大数为11111111,即255

所以unsigned char 类型的取值范围是0 ~ 2^8-1(0 ~ 255)
经过这两个示例,相类似的比如shortlong等整型的存储范围就都可以算一算了。

可能遇到的各种情况

做题之前,要牢记该点
不管变量类型是什么,我们往内存中存入整型数,就是将它的2进制补码存进去,而展示出来的结果,则按照它的解读方式(%d,%u等等)来展示
光说不练假把式,下面请看各种不同情况的例题

以%d,%u形式打印char类型

	char a = -128;
	char b = -128;
	printf("%d\n", a);
	printf("%u\n", b);

在这里插入图片描述
解析:

	char a = -128;
	10000000 00000000 00000000 10000000  -原码
	11111111 11111111 11111111 01111111  -反码
	11111111 11111111 11111111 10000000  -补码
	10000000 - 截断 ,补符号位1(整型提升)
	11111111 11111111 11111111 10000000  补后的补码
	11111111 11111111 11111111 01111111  反码
	10000000 00000000 00000000 10000000  原码 ——输出结果为-128
	
	char b = -128
	11111111 11111111 11111111 10000000 - -128的补码
	10000000 —  截断,补符号位1(整型提升)
	11111111 11111111 11111111 10000000   补后的补码  无符号数原反补码相同 ——输出结果为 4294967168

以%d形式打印int类型和unsigned int类型的相加值

	int i = -20;
	unsigned int j = 10;
	printf("%d\n", i + j);

输出结果:在这里插入图片描述
解析:

int类型可以存的下-20;unsigned int类型可以存的下10,单从值的角度来讲,都没有发生变化,所以可以直接相加得-10,再以有符号数打印,得出-10 。
注:感兴趣的朋友可以像上面一样将它们的原反补码写出再相加算一算。

无符号数作为循环判断条件

#include<stdio.h>
#include<stdlib.h>
int main()
{
    
    
	unsigned int i;
	for (i = 5; i >= 0; i--)
	{
    
    
		printf("%u\n", i);
		Sleep(1000);//加入Sleep函数以观察到控制台显示的变化
	}
	return 0;
}

在这里插入图片描述
我们发现结果0之后打印出来的数字都非常大,且循环没有停止。为什么呢?

0再经过i–之后变为了-1,但i是个无符号数
11111111 11111111 11111111 11111111 -1的补码
无符号数原反补码相同,所以读出4294967295,满足条件并继续循环下去。

char类型的存储大小?

#include<stdio.h>
#include<string.h>
int main()
{
	
	char a[500];
	int i = 0,ret = 0;
	for (i = 0; i < 500; i++)
	{
		a[i] = i+1;
	}
	ret = strlen(a); //strlen是计算字符串长度的,遇到'\0'停止,而'\0'的ASCII码值为0.即遇到数组元素为0时停止循环
	printf("%d", ret);
}

在这里插入图片描述

	for (i = 0; i < 500; i++)
	{
		a[i] = i+1;   // 1,2,3,4,5…………127,-128,-127,-126…………-1,0  读到0停止循环
	}
	上面我们知道char类型取值范围为-128 ~ 127,所以127后为-128(详细请看文章开头)而非128
	-128,-127…………-1,0  读到0停止,所以输出结果就是255

这里再给一个例子,尝试着自己做看看吧

	unsigned char i = 0;
	for (i = 0; i <= 255; i++)
	{
		printf("我爱中国\n");
	}

文末bb:好了,文章到此就结束了。因文章篇幅较长,博主在制作时可能有些地方出错,欢迎读者提醒,博主会第一时间更改的。如果对你有所帮助,还请给博主点一个赞。谢谢!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_73390155/article/details/129280882