字符数组(用sizeof和strlen计算长度的说明)
strlen(char[]):计算一个字符数组中\0之前的所有字符数量
sizeof(char[]):计算字符数组实际占用空间长度
当我们执行以下代码片段时
char arr[] = "abc";
char arr2[] = {'a','b','c'};
printf("%s\n", arr);
printf("%s\n", arr2);
输出结果为:
abc abc烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫虜恄U?
当我们在visual studio中跟踪时,会发现arr在字符串最后面添加了一个'\0',也就是说arr数组的实际长度比字面长度多了一个字节的长度,而arr2还是数组的实际长度3。
当我们修改上述代码,在arr2末尾增加一个0
char arr[] = "abc";
char arr2[] = {'a','b','c',0};
printf("%s\n", arr);
printf("%s\n", arr2);
此时运行后,结果相同。由此可以推断,'\0'和0相等,都代表字符串的结束标志
,当定义字符串数组时,实际上系统是在字符串字面量末尾增加了一个'\0',也就是int类型的0。
字符串常量系统会自动在结尾增加一个字符\0
,该结论通过以下语句就更容易理解了
printf("%s",sizeof("hello"));
输出结果为:6
当输出不带0的arr2时,当系统没遇见0时,也就是说没遇见字符串结束标志时,系统就是一直打印它后面的字符,直到遇见0字符位置为止
第一种情况
char arr[3];//定义一个数组,并开辟了3个字符空间,但是没有初始化。
strlen(arr);//结果为随机数。
解释:arr定义后但没初始化,此时3个元素都为随机值。strlen开始执行直到遇见\0为止,并返回非0字符,当超过arr的上界后,比较不会停止,会超出arr的内存空间界限向后一直比较,直到遇见\0,所以strlen返回随机值。
sizeof(arr);//结果:3
解释:sizeof只计算arr的长度,此时arr的长度是确定的,也就是3,那么sizeof为3
第二种情况
char arr[3] = {0,1};//arr数组长度确定,初始化了2个字符,第一个字符是0,也就是空字符
strlen(arr);//结果:0。
解释:strlen计算的原则是遇见0字符就返回。arr第一个字符就是0,当然返回0了。
sizeof(arr);//结果:3
解释:sizeof只计算arr的长度,此时arr的长度是确定的,无论初始化多少字符,sizeof只计算分配的空间大小,即3。
第三种情况
char arr[] = {0,1};//数组长度不固定,有初始值
strlen(arr);//结果:0。
解释:strlen计算的原则是遇见0字符就返回。arr第一个字符就是0,当然返回0了。
如果数组定义为:char arr[] = {1,2,0,3,6,9};那么结果就为2
sizeof(arr);//结果:2
解释:sizeof只计算arr的长度,此时arr的长度没有预先分配,那么数组长度就由初始化的字符决定其长度,此时有2个字符,那么结果就为2。
第四种情况
char arr[3] ="abc";//数组长度固定,并且和初始化字符串长度一致
strlen(arr);//结果:随机值。
解释:字符串字面量的实际长度是字符个数+1,但arr定义时已经把长度固定了,abc刚好放到arr中,而abc结尾的\0无处放置,被数组丢弃,当执行strlen时,它会超过数组上界,从后面的内存空间中查找\0,所以返回的是一个随机值。
sizeof(arr);//结果为3
解释:一般性的判断标准就是,只要数组的长度固定了,sizeof就返回定义时的长度,此处为3。
第五种情况
char arr[3] ="ab";//数组长度固定,并且初始化字符串长度小于数组长度
strlen(arr);//结果:2。
解释:"ab"后面包含一个\0。这三个字符都能放入数组中,strlen找到\0后,返回前面的字符长度
sizeof(arr);//结果为3
解释:一般性的判断标准就是,只要数组的长度固定了,sizeof就返回定义时的长度,此处为3。
第六种情况
char arr[] ="ab";
strlen(arr);//结果:2。
解释:"ab"后面包含一个\0。这三个字符都能放入数组中,strlen找到\0后,返回前面的字符长度
sizeof(arr);//结果为3
解释:此时的arr没有指定长度,其长度由保存的字符串长度决定,“ab”的实际长度为3,所以结果为3
结论:
strlen会超出字符数组的边界,直到找到\0字符为止,同时返回前面的字符数量
sizeof只在当前定义的数组边界范围内确定数组的长度。