前言:在上一篇博客中,我们明白了整型在内存中的存储方式,并简单的介绍了整型提升,现在,我们将继续深入学习整型数据在内存中的存储。
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)
经过这两个示例,相类似的比如short,long等整型的存储范围就都可以算一算了。
可能遇到的各种情况
做题之前,要牢记该点
不管变量类型是什么,我们往内存中存入整型数,就是将它的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:好了,文章到此就结束了。因文章篇幅较长,博主在制作时可能有些地方出错,欢迎读者提醒,博主会第一时间更改的。如果对你有所帮助,还请给博主点一个赞。谢谢!