c - 为什么这个非空终止字符串被正确打印

标签 c string initialization c-strings

昨天,我进行了单元测试。其中一个程序是复制字符串并在没有字符串函数的情况下找出它的长度。这是我写的代码:

#include <stdio.h>

int main(){
    char str1[100], str2[100] = {'a'};

    printf("Enter a string\n");
    fgets(str1, sizeof(str1), stdin);

    int i;
    for(i = 0; str1[i] != '\0'; i++){
        str2[i] = str1[i];
    }   

    str2[i] = '\0';

    printf("Copied string = %s", str2);

    printf("Length of string = %d", i-1);
}

我有一个相当惊人的观察!即使注释的 str2[i] = '\0',该字符串也会正确打印,即在初始化中没有额外的 'a',这不应该是据我所知被覆盖了。

在评论 str2[i] = '\0' 之后,我希望看到这个输出:

test
Copied string = testaaaaaaaaaaaaaaaaaaaaaaaaaaa....
Length of string = 4

这是输出:

test
Copied string = test
Length of string = 4

str2 是如何正确打印的?是不是编译器识别了字符串的复制并默默地添加了空终止?我使用的是 gcc,但 clang 也产生类似的输出。

最佳答案

str2[100] = {'a'}; 不会用 100 个重复的 a 填充 str2。它只是将 str[0] 设置为 'a',其余设置为零。

早在 C89:

3.5.7 Initialization

...

Semantics

...

If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant. If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate./65/

...

If there are fewer initializers in a list than there are members of an aggregate, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

关于c - 为什么这个非空终止字符串被正确打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55487736/

相关文章:

python - 向后循环python字符串的最佳方法

c - 初始化一个二维字符串数组并打印

c++ - 这段代码在 ISO C++ 中合法吗?

有人可以解释为什么 GMP mpz_sizeinbase 会返回 1 太大吗?

c - 我不知道这个程序有什么问题。它应该在c中将二进制转换为十进制

c - 如何使用libbmp读取光栅?

c++ - 列表初始化(使用花括号)有什么好处?

c - 如何避免 linux 设备驱动程序中的 copy_from_user 和 copy_to_user

c++ - 计算字符串中偶数偶数元音和辅音的程序

c# - 使用 C# 格式化字符串