看这个题之前,先来回忆一下strlen函数的工作机制:
strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,每碰到一个非’\0’的字符,计数器的值加1,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值(长度不包含’\0’)。
#include <stdio.h>int main()
{char a[1000];int i;for(i=0; i<1000; i++){a[i] = -1-i;}printf("%d",strlen(a));return 0;
}
第一眼看到题目是不是觉得太简单了一点,有一种把1000脱口而出的欲望,这么简单我会出给你?想太多了吧!
且不说这儿数组的类型是char,就算它的类型是int,程序就会输出1000?想想上面对strlen的定义是怎么说的?遇到’\0’才结束统计,你能保证数组后面的空间第一个字符就存储的是’\0’吗?不能吧!因此不要轻易给出答案。
运行后,输出的答案是这样的,是不是有点讶异,整个人突然懵了?大大的问号突然充斥着你。
分析一下,这个题其实无非也就以下几个考点:
1、负数在内存中的存储方式;
2、char型数据占空间大小;
3、0其实就是’\0’
4、strlen函数什么时候结束统计;
负数在内存中是以其补码存储的,那么问题又来了,什么是补码?正数的补码是其原码,负数的补码是其原码取反加1,连原码都不知道的可以去看看补补了。
因为a[i] = -1 - i; 而-1 - i的值一定是负数,本来也没什么,但你要知道我们的数组元素是char型的,那么它就只占一个字节,即8个bit,所以,当-1 - i的值小到-129时,a[i]里面存的值就不是我们想象的值了,而当 -1 - i的值小到-256时,a[i]里面存的值会吓你一跳。看看下面这张图:
可以看见当i = 255时,a[i] = 0,而我们知道0其实就是’\0’,因为’\0’的ASCII是0,而strlen函数是遇到’\0’停止统计的,且不统计’\0’,也就是说它只统计a[255]前面的元素个数,而我们知道数组下标是从0开始的,所以a[255]前面的元素个数为255个,那么输出为255就很好解释了。
这个题仔细分析其实很简单,但是一不小心就上当了,因此,我们在看待问题是一定要考虑全面,不要轻易下结论。