signed unsigned 关键字

        我们都知道,数据在计算机中是以二进制数存取的。任何数到了计算机底层都会被计算机转换为0,1.那么,负数在计算机是如何存取的呢?负号是没有办法存进计算机的。怎么办呢?做一个标记就好了。我们把数据的最高位腾出来,用来标记数据的符号。规定如下:若最高位为1,则为负数,其值为除最高位之外剩余位的值再加上一个负号,若最高位为0,则为正数,其值为除最高位之外剩余位的值。

这样,一个32位的signed int 类型的数,其值表示的范围为:-2^31~(2^31)-1。

8位的signed char 类型的数,其值表示的范围为:-2^7~(2^7-)1。

一个unsigned int 类型的数,其值表示的范围为:0~(2^32)-1。

一个unsigned char类型的数,其值表示的范围为:0~(2^8)-1。

接下来,我们看一下这个程序:

实例一:

<span style="font-size:12px;">#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	signed char arry[1000];
	for (i = 0; i < 1000;i++)
	{
		arry[i] = -i - 1;
	}
	printf("%d ", strlen(arry));
	system("pause");
	return 0;
}</span>

这个程序看起来简单,实际上很多人都会做错。我们运行一下看一下结果:


       是不是很惊讶?接下来我们分析一下程序。第一次循环时,arry[0]=-1。我们知道数据在计算机是以补码的形式存储的,正数的补码是其原码,负数的补码的求取方式是:符号位不变,其余位取反,然后加1。 

我们来求一下-1的补码,假定计算机为32位。那么

-1就是:    10000000  00000000  00000000  00000001

取反后为:11111111  1111111   11111111   11111110

加1:        11111111    11111111  11111111  11111111 

char 类型的大小为8个字节,所以-1的补码为0xff。arry[1]=-2,-2的补码为oxfe。一直循环下去,直到arry[127]=-128。我们知道,signed char 所能存取值得范围为:-128~127。所以循环到arry[128]时,arry[128]的值肯定不是-129,这时已经溢出了。  

-129的表示:10000000   00000000   00000000   10000001

取反后为:   11111111   11111111   11111111   01111110

加1:           11111111   11111111   11111111   01111111

char 类型数据只有8位,而-129需要9位才能存储下来,所以最高位被丢弃,-129的补码是0x7f。

当i 继续增加到255时,-256的补码的低8位是0.

-256在内存中的补码如下:

-256的表示:10000000    00000000    00000001      00000000

取反后:      11111111    11111111    11111110      11111111

加1:           11111111    11111111    11111111      00000000

然后当i增加到256时,-257的补码的低8全为1。

-257的表示:10000000    00000000     00000001     00000001

取反后:      11111111    11111111     11111110     11111110

加1:           11111111    11111111     11111110     11111111
-257的补码是0xff,如此又开始新的一轮循环……
        按照上面的分析,a[0]~a[254]里面的值都不为0,而a[255]的值为0.我们都知道,strlen是求求字符串长度的,并不包含‘\0’,判断字符串结束的标志是是否遇到‘\0’,如果遇到‘\0’,则该字符串结束,所以,strlen(arry)的值为255就不难理解了。
在使用char 类型时,我们也需要注意,单纯的char类型应该只用于字符型的存储和使用,而有符号和无符号的char类型只能用于数值的存取和使用。
下面i+j的值又是多少呢?
实例二:
<span style="font-size:12px;">#include<stdio.h>
int main()
{
	int i = -20;
	unsigned j = 10;
	printf("%d ", i + j);
	system("pause");
	return 0;
}</span>
结果如下:


实例三:
<span style="font-size:12px;">#include<stdio.h>
int main()
{
	unsigned i;
	for (i = 0; i >= 0; i--)

	{
		printf("%u\n ", i);
	}
	system("pause");
	return 0;
}</span>
结果如下:

分析:可以看出,程序陷入了死循环,因为i是一个无符号数,所以判断i>=0是无效的,因此程序将无止境的执行下去。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值