Compact way to initialize an array of structures in C?

huangapple go评论66阅读模式
英文:

Compact way to initialize an array of structures in C?

问题

我有一种相当混乱的方法来初始化一个结构数组,希望有人可以帮助我找到一种更紧凑的方法。我的结构是:

struct Vertex_t {
  int i; /* 标签 */
  int n; /* 阶数(包含在其中的 2D 单纯形数量) */
  int r[3]; /* 顶点位置,用于绘图 */
};

我需要一堆这些结构,所以我正在准备一个数组:

struct Vertex_t v_list[VERT_MAX];

现在我需要设置最初使用的部分(这里是 4 个,但原则上会更多):

int N_t = 4;
for (i = 0; i < N_v; i++){
    v_list[i].i = i;
    v_list[i].n = 1;
}
v_list[0].r[0] = 0;
v_list[0].r[1] = 1;
v_list[0].r[2] = 0;
.../* 对于每个 i */

所以我可以循环来设置初始数字,但是对于数组 r(在这里充当 3D 矢量的角色),我必须逐个设置它们(每个 r[] 的值必须手动设置...我认为是这样的)。上面的方法可以工作,但我更愿意使用类似以下的方法:

v_list[0].r[] = {0, 1, 0};

甚至:

v_list[i] = {.i = i, .n = 1, .r = {0, 1, 0}};

但是我知道这两种方法都不起作用,因为我已经为 v_list[i] 保留了内存。

有没有人知道如何实现我想要的效果?我需要在数组中有大量的结构,并且希望能够像初始化它们一样设置它们。

英文:

I've got a rather messy way to initialize an array of structures, and I'm hoping someone can help me find a more compact method. My structure is:

struct Vertex_t {
  int i; /* Label */
  int n; /* Order (number of 2D simplicies it is contained within) */
  int r[3]; /* Position of vertex, for plotting */
}; 

And I need a bunch of these, so I'm preparing an array of them:

struct Vertex_t v_list[VERT_MAX]

So now I need to set the ones I'm initially using (4 here, but in principle, it will be more):

int N_t=4;
for (i=0;i&lt;N_v;i++){
    v_list[i].i=i;
    v_list[i].n=1;
}
v_list[0].r[0]=0;
v_list[0].r[1]=1;
v_list[0].r[2]=0;
.../* for each i*/

So I can loop through to set the initial numbers, but for the array r (playing the role of a 3D vector here), I have to set each one individually (each value of r[] must be set by hand....I think). The above works, but I'd much rather use something like

v_list[0].r[]={0,1,0};

or even

v_list[i]={.i=i,.n=1, .r={0,1,0}};

But I know neither of them works because I've already got the memory for v_list[i] reserved.

Does anyone have a way to get what I'm going for? I need a large number of structures in an array, and I'd like to set them as if I was initializing them.

答案1

得分: 2

C语言支持数组的初始化,但不支持整个数组的赋值。如果要避免逐个元素的赋值,以下是一些更好的选项:

  1. 在声明中使用真正的初始化器,而不是初始化代码:

    struct Vertex_t v_list[VERT_MAX] = {
        { .i = 0, .n = 1, .r = {0, 0, 0} },
        { .i = 1, .n = 1, .r = {1, 1, 0} },
        { .i = 2, .n = 1, .r = {0, 1, 1} },
        { .i = 3, .n = 1, .r = {1, 0, 1} }
        // 其他元素将会默认初始化
    };
    
  2. 从复合文字结构中赋值(内部的数组不会阻止这样做):

    struct Vertex_t v_list[VERT_MAX];
    
    // 可能可以使用循环:
    v_list[0] = (struct Vertex_t) { .i = 0, .n = 1, .r = {0, 0, 0} };
    v_list[1] = (struct Vertex_t) { .i = 1, .n = 1, .r = {1, 1, 0} };
    v_list[2] = (struct Vertex_t) { .i = 2, .n = 1, .r = {0, 1, 1} };
    v_list[3] = (struct Vertex_t) { .i = 3, .n = 1, .r = {1, 0, 1} };
    // v_list的其他元素不会初始化
    
  3. 使用memcpy()从复合文字中复制数组成员:

    for (i = 0; i < 4; i++) {
        v_list[i].i=i;
        v_list[i].n=1;
    }
    memcpy(v_list[0].r, (int[]) {0, 0, 0}, sizeof(v_list[0].r));
    memcpy(v_list[1].r, (int[]) {1, 1, 0}, sizeof(v_list[1].r));
    memcpy(v_list[2].r, (int[]) {0, 1, 1}, sizeof(v_list[2].r));
    memcpy(v_list[3].r, (int[]) {1, 0, 1}, sizeof(v_list[3].r));
    
  4. 类似于(3),但是从const int的本地static数组中复制,而不是从复合文字中。

英文:

> for the array r (playing the role of a 3D vector here), I have to set
> each one individually (each value of r[] must be set by hand....I
> think). The above works, but I'd much rather something like
>
> v_list[0].r[]={0,1,0};
>
> or even
>
> v_list[i]={.i=i,.n=1, .r={0,1,0}};

C has array initialization but not (whole-)array assignment. If you want to avoid individual element assignments then these are some of your better options:

  1. Use a bona fide initializer in the declaration instead of initialization code:
    struct Vertex_t v_list[VERT_MAX] = {
        { .i = 0, .n = 1, .r = {0, 0, 0} },
        { .i = 1, .n = 1, .r = {1, 1, 0} },
        { .i = 2, .n = 1, .r = {0, 1, 1} },
        { .i = 3, .n = 1, .r = {1, 0, 1} }
        // other elements will be default-initialized
    };
    
  2. Assign from compound literal structures (the array inside does not prevent this):
    struct Vertex_t v_list[VERT_MAX];
    
    // Possibly this can be looped:
    v_list[0] = (struct Vertex_t) { .i = 0, .n = 1, .r = {0, 0, 0} };
    v_list[1] = (struct Vertex_t) { .i = 1, .n = 1, .r = {1, 1, 0} };
    v_list[2] = (struct Vertex_t) { .i = 2, .n = 1, .r = {0, 1, 1} };
    v_list[3] = (struct Vertex_t) { .i = 3, .n = 1, .r = {1, 0, 1} };
    // other elements of `v_list` are not initialized
    
  3. memcpy() the array members from compound literals:
    for (i = 0; i &lt; 4; i++) {
        v_list[i].i=i;
        v_list[i].n=1;
    }
    memcpy(v_list[0].r, (int[]) {0, 0, 0}, sizeof(v_list[0].r));
    memcpy(v_list[1].r, (int[]) {1, 1, 0}, sizeof(v_list[1].r));
    memcpy(v_list[2].r, (int[]) {0, 1, 1}, sizeof(v_list[2].r));
    memcpy(v_list[3].r, (int[]) {1, 0, 1}, sizeof(v_list[3].r));
    
  4. Like (3), but copy from local static arrays of const int instead of from compound literals.

huangapple
  • 本文由 发表于 2023年4月6日 23:18:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951144.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定