C中结构数组的静态初始化

Jos*_*rty 7 c arrays struct initialization

我有一个关于C语言中结构数组初始化的问题.谷歌搜索告诉我很多人都有非常相似的问题,但它们并不完全相同.

基本上,我有一个全局的结构类型"memPermissions"如下所示.在程序执行时,该数组需要将所有"address"和"ownerId"字段初始化为-1.

typedef struct memPermissions {
    int address;
    int ownerId;
} *test;
Run Code Online (Sandbox Code Playgroud)

问题是数组的大小是使用#define,所以我不能简单地去:

#define numBoxes 5

struct memPermissions memPermissions[numBoxes] = {
{-1, -1},
...
{-1, -1}
};
Run Code Online (Sandbox Code Playgroud)

我试过了:

struct memPermissions memPermissions[numBoxes] = {-1, -1};
Run Code Online (Sandbox Code Playgroud)

但自然这只是初始化了第一个元素.(其余的被设置为0).跳到脑海的唯一解决方案是在某个地方用一个简单的循环初始化它,但由于这个代码运行的地方的性质,我真的希望这不是我唯一的选择.

有没有办法在没有循环的情况下初始化这个结构数组的所有元素?

干杯, - 乔什

Jon*_*ler 8

C99标准添加了各种有用的方法来初始化结构,但没有提供重复运算符(Fortran已经永远存在 - 但也许这就是它没有被添加的原因).

如果您使用的是最新版本的GCC,并且可以使用非便携式扩展,那么GCC会提供扩展.在GCC 8.1.0手册(§6.27指定初始化程序)中,它说:

要将一系列元素初始化为相同的值,请写入'[first ... last] = value'.这是一个GNU扩展.例如,

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
Run Code Online (Sandbox Code Playgroud)

如果其中的值具有副作用,则副作用将仅发生一次,而不是由范围初始值设定项对每个初始化字段发生.

所以,在你的例子中使用它:

struct memPermissions memPermissions[numBoxes] =
{
    [0..numBoxes-1] = {-1, -1},    // GCC extension
};
Run Code Online (Sandbox Code Playgroud)

我希望这是C标准; 它会非常有用!


如果不使用该编程器或其他类似的编译器特定机制,您唯一的选择就是循环.对于具有许多字段的复杂初始化程序,并非所有相同的值,您可以使用:

#include <string.h>
#include "memperm.h"  // Header declaring your types and variables

static int initialized = 0;
// -2 so the initialization isn't uniform and memset() is not an option
static const struct memPermissions initPermissions = { -1, -2 };
struct memPermissions memPermissions[numBoxes];

void initialize_permissions(void)
{
    if (initialized == 0)
    {
        for (int i = 0; i < numBoxes; i++)
            memmove(&memPermissions[i], &initPermissions, sizeof(initPermissions));
        initialized = 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以memcpy()在这里使用- 两个变量没有重叠的危险.

现在你只需要确保initialize_permissions()在使用数组之前调用它 - 最好只使用一次.可能还有编译器特定的机制来允许这种情况.

您可以在initialize_permissions()函数中使用局部变量来代替初始化的静态常量变量 - 只需确保每次调用函数时编译器都不会初始化它.

如果您有C99编译器,则可以使用复合文字代替常量:

void initialize_permissions(void)
{
    if (initialized == 0)
    {
        for (int i = 0; i < numBoxes; i++)
            memmove(&memPermissions[i],&(struct memPermissions){ -1, -2 },
                    sizeof(memPermissions[0]));
        initialized = 1;
    }
}
Run Code Online (Sandbox Code Playgroud)


Fre*_*Foo 0

唯一想到的解决方案是在某处用一个简单的循环来初始化它

恐怕这是该语言中唯一的可能性。在 C 中,您可以显式初始化每个元素、初始化为全零或不初始化。

0但是,您可以通过将其用于当前服务的目的来回避该问题-1

  • 在我的例子中,这个问题的最佳解决方法是使用结构中初始化为 0 的第三个字段。不幸的是,我无法使用这两个现有字段中的任何一个,因为 0 是它们稍后在程序执行中可能设置的值。然而,由于你的回答让我走上了解决这个问题的轨道,所以我接受了它。谢谢! (2认同)