【笔记】关于signed关键字的一道题

在看C语言相关书籍时候,遇到一道题,想了好久原因才豁然开朗,记录下来方便以后观看,代码如下:

int main(void)
{
	char a[1000];
	int i;
	for(i=0; i<1000; i++)
	{
		a[i] = -1 - 1;
	}
	printf("%d\n",strlen(a));

	return 0;
}

刚开始乍一看以为是1000,然后觉得不太对,再猜测是255,答案就是255,但是却没有明白其中缘由,然后看了书本的解释,第一遍好像懂了,第二遍又不会了,第三遍心中闪过某种念头,第四遍第五遍…本人愚笨,最终看了9遍才有豁然开朗的感觉。

首先明白问题是求打印的值是多少,然后看strlen(a),很明显是计算出字符串的长度。那对于一个数组来说,它的字符串长度要怎么算呢?strlen()这个函数是遇到“\0”就结束,所以目的就是:要在数组a当中从a[0]开始,一直碰到"\0"才结束计数。

接下来分析代码,重要部分是在循环里,a[0]是-1,a[1]是-2。那a[1000]是多少呢?-1000吗?很明显不是这么随意。
这里要明白一点,那就是char类型,在缺省的情况下,char是signed类型的,除非程序员声明为unsigned类型。如果是unsigned的话,它的范围就是0-255。而signed类型是-128-127。

那么以a[0] = -1,a[1] = -2这样的方式推导下去,a[127] = -128。此时已经到达了char类型的最小范围,那a[128]是多少?我在这里的时候,有了分歧,想法1是-129,想法2是127,想法3是0。
到这一步,就需要明白,数值在计算机内是以补码的形式存在的,在这道题目下,-1的补码为0xff,-2的补码为0xfe…而-128的补码为1000 0000,-129的补码是1 0111 1111。char类型数据只有8位,所以要舍弃低8位之外的数据,即变为0111 1111,是7f,也就是127,即a[128] = 127。在DEVC++中做了测试,果然如此
在这里插入图片描述

那么a[128]=127,接着推下去:a[129] = 126…又直到a[254]的时候,值为1,到a[255]时,值就变成了0。所以到此结束。a[0]-a[254]的值不为0,一共有255个数,那么遇到a[255]时候,strlen停止计数,并且不将0计算在内。

我最后反思了一下自己为什么需要看那么多遍,那就是没有很好的将strlen遇到0时候停止弄明白,我刻板的以为一定是遇到"\0",而数组的某个元素的值为0时候,没有将它反应成"\0"。在用DEVC++时候,我通过查看变量时候才意识过来。但是我在看书的时候,a[128]时候,作者写的是7f,而我没有很快反应过来7f就是127。并且作者写到i继续增加到255时候,值为-256那么补码低8为全为0,即0x00,而i增加到256时候,-257的补码是0xff,它跟-1的补码一样,所以进行了新的一轮循环。

用DEVC++时候,能够直接看到数组元素值变化过程,所以 理解比较快,而书本作者的讲解,讲的层度更深一些,难明白(根本原因是我一直没意识到"\0"),但是知识能收获更多。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值