strlen给出了意想不到的输出C.

voi*_*oid -4 c string

这是我的示例代码.

#include <stdio.h>
#include <string.h>

int main() {
    char a[3] = { 'H', 'E', 'L', 'L', 'O', '\0' };
    printf("Length is %zd ", strlen(a));
}
Run Code Online (Sandbox Code Playgroud)

我知道这会产生以下警告!

test.c:5:26: warning: excess elements in array initializer
 char a[3] = {'H','E','L','L','O','\0'};
Run Code Online (Sandbox Code Playgroud)

现在我的问题是,如果我指定大小为a[6]或大于我的输出的实际大小.

对于 char a[100] = {'H','E','L','L','O','\0'};

输出:

Length is 5
Run Code Online (Sandbox Code Playgroud)

对于 char a[10] = {'H','E','L','L','O','\0'};

输出:

Length is 5
Run Code Online (Sandbox Code Playgroud)

对于任何等于或大于数组大小的东西,我都得到正确的输出.

但是当我给出比实际尺寸更小的东西时,我总是得到 6作为输出.

char a[5] = {'H','E','L','L','O','\0'};或为a[4]a[3]或或a[2]它总是

Length is 6

虽然为

char a[1] = {'H','E','L','L','O','\0'};
Run Code Online (Sandbox Code Playgroud)

它是Length is 1.

这是什么原因?欢迎任何详细的解释.

Sto*_*ica 7

仅仅因为你给了一个包含6个字符的初始值设定项,并不意味着这些字符实际存储在那些小数组的任何地方.

过多的初始化器被丢弃.如果你不知道自己在做什么,可以回来让你的程序变得格格不入.

让我们考虑a两个字符有空间的情况.编译器知道这一点,所以它像这样初始化它:

| 'H' | 'e' |
Run Code Online (Sandbox Code Playgroud)

而已.虽然它是一个完全有效的字符数组,但它不是一个有效的C字符串.因为数组没有\0终止.将此数组提供给需要C字符串的库函数后,您无法保证任何内容.它使整个程序的行为不确定.

但实际上,strlen只会访问超出您定义的数组范围的内存.不告诉它可以找到那里,或者即使它会不断找到\0并返回.

  • @AnttiHaapala,确定有,这是一个约束违规,编译**必须**打印诊断.标准中的文本是*否初始化程序应尝试为未初始化的实体中包含的对象提供值.* (2认同)