当被问到时,C在运行时初始化并重新初始化数组为零

时间:2012-05-14 12:42:38

标签: c arrays loops initialization runtime

#include <stdio.h>

int main(void) {
    for (int i = 0; i < 5; i++) {
        int arr[5] = {0};
        // arr gets zeroed at runtime, and on every loop iteration!
        printf("%d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]);
        // overwrite arr with non-zero crap!
        arr[0] = 3;
        arr[1] = 5;
        arr[2] = 2;
        arr[3] = 4;
        arr[4] = 1;
    }
    return 0;
}

显然这有效:

> gcc -Wall -Wextra -pedantic -std=c99 -o test test.c;./test
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

可是:

  • 引擎盖下发生了什么?
  • 这是否可以保证适用于任何规模的数组?
  • 我是否找到了在循环的每次迭代中将数组归零的最优雅方法?

6 个答案:

答案 0 :(得分:6)

您正在每次迭代时创建 数组,因此无需重新初始化。

答案 1 :(得分:3)

根据我的意思,无论何时迭代循环,然后在循环中声明的任何变量都是该循环的本地变量。所以在循环结束时它们会被破坏,当循环再次启动时,它们将再次被创建。 所以, 1.上面回答; 2.是的,这适用于任何大小的数组; 3.不......

答案 2 :(得分:3)

变量arr在循环的每次迭代中创建并初始化,因为这就是你所写的。在您的示例中,代码执行类似于memset()的操作,以将数组设置为零,但可能更高效和内联。你也可以写一个非零的初始化器。

是的,它适用于“任何”大小的数组。如果数组较大,则循环速度较慢。

实现这种效果是一种非常优雅的方式。编译器会尽快完成。如果你可以编写一个更快的函数调用,那么编译器编写者已经搞砸了。

答案 3 :(得分:3)

之前已经回答过:

  

引擎盖下发生了什么?

编译器将生成与memset等效的代码(有关详细信息,请参阅Strange assembly from array 0-initialization)。

  

这是否可以保证适用于任何大小的数组?

最多可用堆栈大小的限制,是的。

  

我是否找到了在循环的每次迭代中将数组归零的最优雅方法?

我猜是这样的。 :)

答案 4 :(得分:0)

是的,C标准保证在每次循环迭代时你的数组元素都归零。如果您只希望在第一次迭代时对它们进行零处理,请将该数组设为静态,即使用

static int arr[5] = {0}; 

在这种情况下,你可以省略= { 0 },因为需要初始化静态数据,好像所有元素在没有初始值设定项时被赋值为0(或者指针为NULL,浮点值为0.0) ,递归地为结构)。

另请注意,如果使用 less 初始值设定项而不是数组维度指定的值,则会为其余元素分配零。所以

int arr[5] = {42, 0xdead};

相当于

int arr[5] = {42, 0xdead, 0, 0, 0};

并使用单个0只是此规则的一个特例。

答案 5 :(得分:-2)

不忽略代码的逻辑错误(在每次迭代时重新初始化)我建议您在分配数组的所有元素时使用memcpy或memset。这是经过试验和测试的方法,幸运的是几乎所有编译器实现中的魅力。

Memset Example

MemCpy Example

所以,使用Memset你的代码将成为;;

int a[5]; 
memset(a,0,<number of bytes to be set to> sizeof(int)*5); 

请阅读文档,了解它为什么快,你会喜欢......

修改 对不起,感谢所有下来的选民/评论员......我纠正了答案......