signed char 和unsigned char 区别

一:signed char unsigned char 的取值范围

Charint 一样,都有有符号和无符号之说。即unsigned charsigned char

1.C语言中我们用的char默认到底是有符号还是无符号的呢

对于不同的教材会有不同的答案,其实有无符号都是自己电脑的编译器决定的。(注意:我的电脑默认是有符号的,以下实例都是按我的电脑默认的程序)

2. (有)无符号 char类型的取值范围

我们知道char类型所占据的空间内存一般是1个字节(8位),signed charunsigned char当然也是占1个字节8个位数。但是和int类型一样,它们的取值范围是有区别的。

Unsigned char类型的取值范围是:0~255

Signed char类型的取值范围是:-128~127

二:signed char 和 unsigned char 的溢出问题

其值在范围内时,会被正常处理,但是超过范围就会发生我们所说的溢出。但是要注意的是,在范围之内也并不意味着它就是可打印的字符。

1. 来看一下unsigned char类型的溢出问题

关于上界溢出

十进制

二进制

254

1111 1110

254

255

1111 1111

255

256

257

关于下界溢出

十进制

二进制

2

0000 0010

2

1

0000 0001

1

0

0000 0000

0

-1

-2

我们已经说过了unsigned char 的取值范围是0~255,通过上述两个表格:

在上界中254255都能正常表示,那256257它们不在计算机分配的范围之内,它们是溢出了,那问号处的值应该怎么表示呢?

同样的,在下界中,012都在范围之内,能正常表示,-1-2很明显溢出越界了,那怎么表示呢?

2.再来看一下signed char类型的溢出问题

关于上界溢出

十进制

二进制

126

0111 1110

126

127

0111 1111

127

128

129

关于下界溢出

十进制

二进制(补码形式)

-127

1000 0001

-127

-128

1000 0000

-128

-129

-130

我们也已经知道了signed char的取值范围是:-128~127.

在上界中,126127在范围之内,都能正常显示值。但是128129呢?

在下界中,-127-128在范围之内,都能正常显示值。但是-129-130呢?

三:signed char 溢出的表示

1.程序实例验证一下signed char中溢出的数字的值(求signed char溢出中的问题)


1
2
3
4
5
6
# include  <stdio.h>
main()
{
     signed char a= 126 ,b= 127 ,c= 128 ,d= 129 ;
     printf( "a=%d\nb=%d\nc=%d\nd=%d\n" ,a,b,c,d);
}


174922885.png


1
2
3
4
5
6
# include  <stdio.h>
main()
{
     signed char a=- 127 ,b=- 128 ,c=- 129 ,d=- 130 ;
     printf( "a=%d\nb=%d\nc=%d\nd=%d\n" ,a,b,c,d);
}


174940112.png

从上述两个程序中,我们不难得出以下结论的表格数据。

2.给出signed char溢出问题表格的答案:

关于上界溢出

十进制

二进制

126

0..0 0111 1110

126

127

0..0 0111 1111

127

128

1..1 1000 0000

-128

129

1..1 1000 0001

-127

关于下界溢出

十进制

二进制(补码形式)

-127

1..1 1000 0001

-127

-128

1..1 1000 0000

-128

-129

0..0 0111 1111

127

-130

0..0 0111 1110

126

注:0..0 表示2401..1表示241

3.解析

从上述两个表格中可以看到,不管是否超过上下届,不管是负数还是正数,每增加(减少)一个单位,就直接在二进制表示的最后一位上加(减)1个单位。

并且相加和相减时,都先不看前24位,如果倒数第8位变为1则前面24位全部设置为1,该数被解释为负数;如果倒数第8位变为0,则前面24位全部设置为0,该数被解释为正数

我们来分别看看。

1126127

126127是范围之内的数字,他们的值是遵从规则的。所以他们的值也是126127,并没有越界。

2128

从程序实验和上表的结论中,我们得出了128的值竟然是-128.128这个数字是越界的数字,是127+1

这时会在127的最后8位上加1,也就是在0..0 0111 1111的后80111 1111上加1,变为1000 0000。倒数第8位变成了1,所以前24个位也全部变为1,所以该数被表示为负数。它的值为 -1*2^7+0=-128

根据负数的值在计算机中是以补码的形式存储的理论,也就是说1000 0000是补码,即:-128在计算机中是以1000 0000存储的,-128的原码是1000 0000(补码)减1,再取反,结果还是1000 0000(原码)。

3129

129128的取值也是一样的道理。129127+2或者128+1,抛开前24位不说,它的二进制为1000 0001,倒数第8位为1,所以前24位也为1,并且为负数。所以它的值表示为: -1*2^7+1=-127.

根据负数的值在计算机中是以补码的形式存储的理论,1000 0001是补码,即:-127在计算机中是以1000 0001存储的,-127的原码是1000 0001(补码)减1,再取反,结果是0111 1111(原码)。

4-127-128

这两个数字都是在范围之内 没有什么可说的了吧,并且它们的二进制形式也刚刚讲过了。

5-129

-129-128-1所得,所以-128的最后8位是1000 0000,减去1变为0111 1111,前面24位全部置位0,且该数被解释为正数,其值为2^0+2^1+2^2+2^3+2^4+2^5+2^6=2^71=127

6-130

-127的最后8位是1000 0001,减去3变为0111 1110,前面24位全部保持0,且该数被解释为正数,其值为2^1+2^2+2^3+2^4+2^5+2^61=126

四:unsigned char 溢出的表示

看了上述的讲解 ,我相信读者一定对unsigned char也明白了,无符号无非就是取值范围不一样而已。不过我们还是来一起看一下。总觉得不放心 呵呵

1.程序实例验证一下unsigned char中溢出的数字的值(求unsigned char溢出中的问题)


1
2
3
4
5
6
# include  <stdio.h>
main()
{
     unsigned char a= 254 ,b= 255 ,c= 256 ,d= 257 ;
     printf( "a=%u\nb=%u\nc=%u\nd=%u\n" ,a,b,c,d);
}


174958991.png


1
2
3
4
5
6
# include  <stdio.h>
main()
{
     unsigned char a= 1 ,b= 0 ,c=- 1 ,d=- 2 ;
     printf( "a=%u\nb=%u\nc=%u\nd=%u\n" ,a,b,c,d);
}


175014280.png

从上述两个程序中,我们不难得出以下结论的表格数据。

2.给出unsigned char溢出问题表格的答案:

关于上界溢出

十进制

二进制

254

0..0 1111 1110

254

255

0..0 1111 1111

255

256

0..0 0000 0001

0

257

0..0 0000 0001

1

关于下界溢出

十进制

二进制

2

0..0 0000 0010

2

1

0..0 0000 0001

1

0

0..0 0000 0000

0

-1

0..0 1111 1111

255

-2

0..0 1111 1110

254

注:0..0 表示2401..1表示241

3.解析

其实和有符号基本相同,唯一的差别就是,前面的24位一直都是0,并且该数永远都是正数。我们说几个吧。

比如256256=255+1所得,2550..0 1111 1111,然后加1,虽然255的全码都是1,再加1貌似没法加了,但是我们仍可将1111 1111前面一位加1,最后得到0001 0000 0000,之后我们就只看后8位即可,所以256的值是0.

比如-1-1=0-1所得,0000 00001相当于减去0000 0001,虽然0的全码是0…0 0000 0000,似乎往上也没法借位,但是我们仍可将0000 0000前面一位加上1,看做0001 0000 0000减去0000 0000 0001,最后得到0000 1111 1111,我们直接最后8为即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值