为什么“%s”格式说明符即使对于没有`\ 0`&的字符数组也能工作一次打印所有元素?

时间:2013-05-05 07:59:01

标签: c string null-terminated null-character

请查看以下代码:

#include<stdio.h>

int main(void)
{
    char name[7]={'E','R','I','C'};
    printf("%s",name);
}

它会输出整个name ERIC 。为什么会这样?只有当我们将字符数组%s初始化为name时, char name[7]={'E','R','I','C','\0'}; //With NULL terminator 才会起作用如下:

   char name[7]="ERIC"

我没有考虑以下内容,因为这显然假定以空字符结尾的字符数组:

{{1}}

2 个答案:

答案 0 :(得分:5)

根据the c11 specification

  

(6.7.9.21)   如果括号括起的列表中的初始值设定项少于元素或成员的初始值设定项   用于初始化已知数组的字符串文字中的聚合或更少字符   大小比数组中的元素大,其余的聚合应该是   隐式初始化与具有静态存储持续时间的对象相同。

     

(6.7.9.10)   如果未初始化具有静态或线程存储持续时间的对象   明确地说:

     

- 如果它有算术类型,则初始化为(正或无符号)零;

因此,当你初始化一个这样的数组时:

char name[7]={'E','R','I','C'};

与以下内容相同:

char name[7]={'E','R','I','C', 0, 0, 0};

所以name仍然以空值终止。

答案 1 :(得分:2)

来自C99第7.21.6.1节第8段%s说明符

  

如果不存在l length修饰符,则参数应为指向   字符类型数组的初始元素。 来自的角色   数组被写入(但不包括)终止空值   字符即可。如果指定了精度,则不超过那么多字节   写的。如果未指定精度或大于   数组的大小,数组应包含一个空字符。

因此,如果您指向使用char *打印的printf,则会打印,直到找不到\0

另外

在这种情况下,<{char name[7]={'E','R','I','C'}; `\0'终止,因为数组的长度为7,但只初始化了4个位置,这将导致其他剩余位置初始化为0.检查johnchen902的答案更多。