0
#include <stdio.h>

int main(void)
{

    int values[10];
    int index;

    values[0] = 197;
    values[2] = -100;
    values[5] = 350;
    values[3] = values[0]+values[5];
    values[9] = 
    values[5] / 10;
    --values[2];

    for (index = 0; index < 10; index++)
        printf ("values[%i] = %i\n", index, values[index]);

    return 0;
}

为什么我在 1、4 和 6-8 的未分配元素中有值?我没有分配任何值。当它为空时,如何使其自动分配 0?

4

4 回答 4

6

你没有分配它们,所以你只是得到那些已经在内存中的垃圾。

要进行零初始化,您可以这样做:

int values[10] = {0};

或者,使用memset.

于 2013-01-02T00:24:53.380 回答
4

在 C 中,自动变量永远不会归零。你想要的是memset()你的阵列0来避免这种情况。

于 2013-01-02T00:25:24.317 回答
3

虽然 Oli Charlesworth 的帖子展示了解决方案,但让我再多介绍一点“为什么”。对于分配在应用程序堆栈上的“自动”变量,这种未定义的值非常明显。

虽然操作系统在将程序加载到其中之前倾向于将内存归零,但 main() 并不是 C 程序实际启动的地方。实际的起始位置隐藏在一些依赖于实现的地方,使您在 main() 中的代码只是程序启动期间一系列函数调用中的最后一次调用。所有这些早期的内部调用都在堆栈中乱涂乱画,把它们的烂摊子抛在脑后。

由于每个函数调用都继承了先前调用的混乱,因此真的不知道在新调用的堆栈上会看到什么。如果堆栈增长到足够大,您最终会在未使用的内存中找到操作系统的零,这可能有助于在较大的程序中进行调试,但代码绝不能依赖这些零。

堆栈和堆(例如 malloc())内存都受未知值的影响。

于 2013-01-02T01:36:31.987 回答
3

从 C99 开始,您还可以只初始化您需要的子对象,其余的将被初始化为具有静态存储持续时间的数据(0for int):

int values[10] =
{
    [0] = 197,
    [2] = -100,
    [5] = 350,
    [3] = values[0] + values[5],
    [9] = values[5] / 10
};

以这种方式不可能/不清楚更复杂的初始化。像:

--values[2];

无法在初始化中完成,因为如果同一元素有多个初始化器,则只会使用最后一个初始化器,甚至无法评估第一个初始化器,从而导致未初始化值的递减。来自 C11 标准:

初始化应按初始化程序列表顺序进行,为特定子对象提供的每个初始化程序都将覆盖同一子对象的任何先前列出的初始化程序; 151)

151) 任何被覆盖的子对象的初始化器,因此不用于初始化该子对象可能根本不会被评估。

(我认为它应该不仅仅是一个脚注......)

但是,我认为这只是一个示例,因为这样做没有意义,您可以350 - 1在这种情况下将其初始化为。

于 2013-01-02T00:37:00.047 回答