0
#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

但:

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

6 回答 6

6

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

于 2012-05-14T12:46:15.273 回答
3

根据我的说法,每当您迭代循环时,您在循环内声明的任何变量都是该循环的本地变量。因此,在循环结束时它们会被破坏,当循环再次开始时,它们会再次被创建。所以,1.上面回答了;2.是的,这应该适用于任何大小的数组;3.不...

于 2012-05-14T12:46:42.567 回答
3

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

是的,它适用于“任何”大小的数组。如果数组更大,循环会更慢。

这是实现效果的一种非常优雅的方式。编译器将尽可能快地完成它。如果您可以编写更快的函数调用,那么编译器编写者就犯了错误。

于 2012-05-14T12:48:07.623 回答
3

之前已经回答过:

引擎盖下发生了什么?

编译器将生成与 memset 等效的代码(有关完整详细信息,请参阅来自数组 0 初始化的奇怪程序集)。

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

不超过可用堆栈大小的限制,是的。

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

我想是这样。:)

于 2012-05-14T12:51:20.460 回答
0

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

static int arr[5] = {0}; 

在这种情况下,您可以省略= { 0 },因为需要初始化静态数据,就好像在没有初始化程序的情况下所有元素都被分配了 0(或 NULL 用于指针,或 0.0 用于浮点值,递归地用于结构)。

另请注意,如果您使用初始值设定项少于数组维度指定的数量,则剩余元素将分配为零。所以

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

相当于

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

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

于 2012-05-14T12:46:37.510 回答
-2

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

Memset 示例

MemCpy 示例

因此,使用 Memset 您的代码将变为;;

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

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

编辑 对不起,感谢所有反对的选民/评论者......我更正了答案......

于 2012-05-14T12:52:57.697 回答