繁体   English   中英

静态如何将2D数组初始化为指向指针的指针?

[英]How static initialize a 2D array to a pointer to pointers?

我有一个结构,例如foo ,看起来像这样,

struct foo {
    size_t n;
    size_t **point;
};

结构中还有其他成员,它们对问题并不重要。 现在,我想静态初始化结构。

int main(void)
{
    struct foo *bar = &(struct foo){
                       .n=4,
    /* ERROR HERE */   .point=(size_t[][n]){ {1, 2, 3, 4}, {5, 6, 7, 8}}
    };
    return 0;
}

指示的行中有两个问题。 首先,可以理解的是,编译器无法识别n ,并且有什么办法可以在不创建变量的情况下做类似的事情? 其次,最重要的是,我意识到我不知道如何创建2D数组并将其静态分配给指针。 请帮忙。 我尝试了以下变体,但没有任何效果。

/* Variation 1 */   .point=(size_t[][4]){ {1, 2, 3, 4}, {5, 6, 7, 8}}
/* Variation 2 */   .point=(size_t**)(size_t[][4]){ {1, 2, 3, 4}, {5, 6, 7, 8}}
/* Variation 3 */   .point=&(size_t[][4]){ {1, 2, 3, 4}, {5, 6, 7, 8}}

请注意,从技术上讲,这不是2D数组,而是指针到指针的数组。 但是由于复合文字不能具有可变长度的数组类型,而且似乎也不想使用硬编码维,因此这可能是唯一的方法。

您需要将数组拆分为未知大小的一维数组,并为其使用单独的复合文字:

struct foo * bar = &(struct foo){
    .n = 4,
    .point = (size_t*[]){
        (size_t[]){1, 2, 3, 4}, 
        (size_t[]){5, 6, 7, 8}
    }
};

首先, size_t **point仅在您打算指向size_t*数组时才有意义。 这里似乎不是这种情况,因此您需要将类型更改为2D数组或数组指针。

下一个问题是C在这里相当麻烦-坦率地说,您不能有一个“静态动态”数组,它必须是。 您可以拥有:

#define N 4

struct foo {
  size_t n;
  size_t (*point)[N]; // pointer to first array of an array of size_t[4]
};

struct foo bar = 
{
  .n=N,
  .point= (size_t[][N]){ {1, 2, 3, 4}, {5, 6, 7, 8} }
};

...
bar.point[x][y] = ...; // access element of the 2D array

或者,也可以是指针数组形式的灵活数组成员,如下所示:

struct foo {
  size_t n;
  size_t* point[];
};

const size_t n = 4;
struct foo* bar = malloc ( sizeof(*bar) + sizeof (size_t*[n]) );
bar->n = n;
bar->point[0] = (size_t []) { 1, 2, ... /* any number of elements*/ };
bar->point[1] = ...
...
bar->point[0][0] = 0; // access element in the lookup-table
...
free(bar);

这些都不是特别好的替代方法,语法混乱且容易出错。 这里根本缺少语言。

为了静态地初始化指针,需要声明要指向的实体。 仅在极少数情况下,例如可能在嵌入式系统中您在编译时就知道某物的地址,才知道要静态初始化的指针的实际值。

我在做的事情有两个问题:1)编译器在尝试使用n声明数组大小时无法解析n的值。 与C#不同,数组需要在声明中提供大小。 2)结构的“ point”成员是一个指向指针的指针,但是您尝试使用数组数组对其进行初始化。 如果要指向数组数组,则只需要[0] [0]元素的地址,因此* point不需要* point。 从那里,您可以使用数组符号来访问元素。

您需要执行以下操作:

struct foo
{
    size_t n;
    size_t *point;
};


size_t values[2][4] = {{1,2,3,4}, {5,6,7,8}};

struct foo bar = 
{
    4,
    &values
}

然后,您可以通过以下方式访问数组:

size_t kk;
kk = bar.point[ii][jj];

如果您确实需要指向指针的指针,则初始化值将必须是地址引用(&name)或被转换为指针的值,但是我不建议这样做。

如果确实需要为数组提供可变大小,则需要动态分配内存,然后使用从该数组返回的地址初始化结构体中的指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM