unsigned char
无符号整型
singned char
有符号整型
举一个例子来解释这两种类型有什么区别:
#include
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d\nb=%d\nc=%d\n",a,b,c);
return 0;
}
打印结果为:
a=-1
b=-1
c=255
由此我们可以得出结论:
在VS编译器环境下char与signed char是相同的
unsigned char与char的打印方式不同
之前我们提到,整型数字在内存中存储时需要将二进制的原码转换为对应的补码
例如-1对应的二进制原码,反码,补码为
原码:10000000 00000000 00000000 00000001
反码:11111111 11111111 11111111 11111110
补码:11111111 11111111 11111111 11111111
因为char类型在内存中占用1个字节,存放4个字节的整型数字会发生截断
把数字-1放入char类型中,-1的高位3个字节的内容会被截断,只存放最后一个字节的内容
char a = -1;
signed char b = -1;
unsigned char c = -1;
这三条语句,表示a,b,c在内存中都存放着 11111111
当%d打印时,不够4个字节的数据会进行整型提升
由于char
与signed char
为有符号类型
在进行整型提升时,把在内存中存储的11111111
中的最高位当做符号位进行整型提升
11111111 11111111 11111111 11111111
打印时将补码转换为原码
10000000 00000000 00000000 00000001
打印结果都为-1
但是unsigned char
为无符号字符类型
整型提升时高位补0
00000000 00000000 00000000 11111111
正数的原反补码都相同,所以打印出255
#include
int main()
{
char a[1000] = { 0 };
int i = 0;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d\n", strlen(a));
return 0;
}
代码结果如下:
255
可能会有小伙伴有疑问
定义了大小为1000的char类型数组,并初始化每一个数组元素
为什么得到的结果是255
,而不是1000
呢?
这是因为char类型是有范围的,有符号的范围是-128 ~ 127,无符号的范围是0~255
大小为一个字节的二进制从小到大存放在char类型中一共有下面这些情况
char unsigned char
0 00000000 0
1 00000001 1
2 00000010 2
... ... ...
127 01111111 127
-128 10000000 128
-127 10000001 129
... ... ...
-2 11111110 254
-1 11111111 255
unsigned char类型在整型提升时,会在高位全部补0,从上到下依次是0~255
char类型在整型提升时,将最高位视为符号位
如果是最高位是0就补0,是1就补1,从上到下依次是0~127 ,-128~-1
for循环初始化数组石-1~-128都是正常存放,当初始化到-129时,发生了变化
-129的原码反码补码分别为:
原码:10000000 00000000 00000000 10000001
反码:11111111 11111111 11111111 01111110
补码:11111111 11111111 11111111 01111111
存放在char类型的数组中只能存放最后一个字节01111111
整型提升后
00000000 00000000 00000000 01111111
所以当存到-129时,实际存入了127,依次类推
数组中存放的数据是-1~ -128,127~0一直循环
strlen
计算数组长度时遇到\0就会停止,第一个\0之前一共有128+127=255个字节,所以打印结果为255。