strlen()应该在这段代码中返回什么?
#include #include #include int main(void) { char qq[] = {'a' , 'b' , 'c' , 'd'}; char qqq[] = "abcd"; printf("%d\n" , sizeof qq / sizeof qq[0]); // line A printf("%d\n" , strlen(qq)); // line B printf("%d\n" , sizeof qqq / sizeof qqq[0]); // line C printf("%d\n" , strlen(qqq)); // line D system("pause"); return 0; }
看看上面的代码。 数组qq
有四个元素,数组qqq
有五个元素,最后一个是'\0'
。 所以我理解A行打印4
和C行打印5
。 D线对我来说还可以。 据我所知,当处理字符串时, strlen(qqq)
等于"sizeof qqq / sizeof qqq[0] - 1"
。 但是B行打印15
让我感到困惑。 为什么? (我使用vs2012。)
在你的代码中
char qq[] = {'a' , 'b' , 'c' , 'd'};
qq
不能被称为字符串 ,因为它不是以空值终止的。 所以调用strlen()
wilh qq
会引发麻烦。
这里实际发生的是, strlen()
越过qq
中的最后一个有效元素来寻找终止null(实际上是缺失的),因此,冒险进入超出范围的内存,调用未定义的行为 。
解决方案:要使qq
成为字符串 ,您必须自己在初始化列表中添加null-terminator,如
char qq[] = {'a' , 'b' , 'c' , 'd', '\0'};
也就是说,正如我在评论中已经提到的,因为strlen()
返回类型是size_t
,所以应该使用%zu
格式说明符来打印结果。
只是心情较轻,回答
strlen()应该在这段代码中返回什么?
如果我说, “印度尊敬的总统的电话号码” ,从技术上讲,我可能是正确的!
值得注意的是,UB的输出,未定义。
您的字符串不是以空值终止的。 这意味着您的代码不具有确定性。 strlen()
会在遇到\0
(空字节/字符)时终止; 结果可能因顺序扫描而变化,直到遇到\0
。
strlen()
计算字符串的长度,但char qq[] = {'a' , 'b' , 'c' , 'd'};
不是字符串。 将'Non-String'
数据传递给strlen
时,会获得未定义的结果。
字符串在c
以null terminated
。
它应该是char qq[] = {'a' , 'b' , 'c' , 'd','\0'};
strlen
将继续前进,直到找到一个\0
字符,计算沿途有多少个字符。
因为qq
中没有\0
,所以strlen
会继续进入其他不相关的内存。 最终偶然遇到\0
字节。
显然是在15字节之后(或超过qq
结束的11字节)。
但它不具有确定性或保证,并且非常不安全。
strlen
很可能最终会在找到\0
字符之前尝试读取无效内存,在这种情况下你的程序会出现seg-fault。