4
#include <stdio.h>

int main(void) {
    int memo[1000];
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

我认为一切都应该初始化为0,但事实并非如此。这有什么原因吗?非常感谢你的帮助。

4

3 回答 3

4

在函数体中使用自动存储在本地定义的对象在 C 中未初始化。值可以是任何值,包括某些体系结构上的陷阱值,这些值仅通过读取它们就会导致未定义的行为。

您可以将此数组初始化为int memo[1000] = { 0 };. 第一个元素显式初始化为0,所有其余元素也将初始化为 ,0因为缺少初始化程序的任何元素都将设置为0

为了完整起见,int memo[1000] = { 42 };将其第一个元素设置为42,并将所有其余元素设置为0。类似地,C99 初始值设定项int memo[1000] = { [42] = 1 };将其第 43 个元素设置为1,所有其他元素设置为0

于 2021-04-25T17:38:30.123 回答
3

在 C 中,当你这样做时

int memo[1000];

你在内存中分配了 1000 个小点。这些点目前可能已经或可能不保存一些垃圾数据。因此,初始化所有变量通常被认为是一种好习惯。这将使调试更容易。

您可以将上面的行替换为,

int memo[1000] = {0};

将数组的每个元素初始化为0;

编辑:正如这里的其他答案所讨论的那样,您所经历的行为肯定有更深层次的原因。但是,如果您是 C 或一般编程的初学者。这足以让您开始使用带有初始化的数组,而不会被更复杂的细节所淹没。如果您更高级,请遵循其他答案。

于 2021-04-25T17:41:39.440 回答
1

来自 C 标准(6.7.9 初始化)

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

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

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

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

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

19 ...所有未显式初始化的子对象都应隐式初始化,与具有静态存储持续时间的对象相同。

因此在这个程序中

#include <stdio.h>

int main(void) {
    int memo[1000];
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

该数组memo具有自动存储持续时间,并且根据 C 标准提供的报价,其元素具有不确定的值。

你可以像这样声明数组

    int memo[1000] = { 0 };

在这种情况下,数组的第一个元素显式初始化为 0,所有其他元素也隐式初始化为 0。

您可以选择要显式初始化的数组的任何元素,例如

    int memo[1000] = { [999] = 0 };

如果你会写

#include <stdio.h>

int memo[1000];

int main(void) {
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

或者

#include <stdio.h>

int main(void) {
    static int memo[1000];
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

然后数组的元素将被初始化为零,因为在文件范围内或使用存储说明符声明的变量static具有静态存储持续时间。

于 2021-04-25T18:11:33.343 回答