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

int main(int argc, const char * argv[]) {
    int i;
    char s1[100] = "Computer Programming Class";
    char s2[100] = "ECE";
    
    int length = (int)strlen(s1);
    for (i = 0; i < length; i++) {
        s2[i] = s1[length - 1 - i];
    }
    
    s2[i] = '\n';
    printf("%s", s2);
    
    return 0;
}

这是我的一项测试,我不明白为什么它会按预期工作。这是一段代码,将s1的顺序颠倒过来,存储在s2中,然后打印出来。在我看来,当 s1 向后存储时,s2 中的空字符将被覆盖,而且 s1 中的空字符永远不会被写入 s2,因为它是从最后一个字符开始的。但它打印出来就好了。为什么?

4

2 回答 2

4
  1. strlen返回字符串的长度,不包括空终止符,因此i < length在其迭代中不包括空终止符s1

  2. 当您部分初始化一个数组时,就像您char s2[100] = "ECE";对剩余元素所做的那样,已经将其初始化为零。换句话说,您对s2as long的写入length < 99保证为空终止。

于 2021-12-19T21:19:15.740 回答
2

来自 C 标准(6.7.9 初始化)

21 如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的剩余部分应隐式初始化与具有静态存储持续时间的对象相同。

10 如果具有自动存储持续时间的对象未显式初始化,则其值是不确定的。如果具有静态或线程存储持续时间的对象未显式初始化,则:

— 如果它具有指针类型,则将其初始化为空指针;

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

— 如果是聚合,则每个成员都根据这些规则(递归地)初始化,并且任何填充都被初始化为零位;

— 如果是联合,则根据这些规则(递归)初始化第一个命名成员,并将任何填充初始化为零位;

因此在这个声明中

char s2[100] = "ECE";

没有被字符串字面量的元素显式初始化的所有 96 个元素都被隐式初始化为零。

于 2021-12-19T21:46:50.667 回答