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时,会获得未定义的结果。

字符串在cnull terminated

它应该是char qq[] = {'a' , 'b' , 'c' , 'd','\0'};

strlen将继续前进,直到找到一个\0字符,计算沿途有多少个字符。

因为qq中没有\0 ,所以strlen继续进入其他不相关的内存。 最终偶然遇到\0字节。

显然是在15字节之后(或超过qq结束的11字节)。
但它不具有确定性或保证,并且非常不安全。
strlen很可能最终会在找到\0字符之前尝试读取无效内存,在这种情况下你的程序会出现seg-fault。