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

问题描述 投票:0回答:3

我有一个结构,说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}}
c arrays pointers struct
3个回答
2
投票

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

您需要将数组拆分为未知大小的1D数组,并为它们使用单​​独的复合文字:

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

1
投票

首先,如果你打算指向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);

这些都不是特别好的选择,语法很混乱,容易出错。这里的语言非常缺乏。


0
投票

为了静态初始化指针,需要声明指向的实体。只有在极少数情况下,比如可能是一个在编译时知道某个地址的嵌入式系统,您是否知道要静态初始化的指针的实际值。

我看到你正在做的事情有几个问题:1)当你试图用它来声明数组的大小时,编译器无法解析n的值是什么。与C#不同,数组需要在声明中提供大小。 2)struct的“point”成员是指向指针的指针,但是你试图用数组数组初始化它。如果要指向数组数组,则只需要[0] [0]元素的地址,因此*指向不是**点。从那里你可以使用数组表示法来访问元素。

你需要做这样的事情:

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)或者作为指针转换的值,但我不建议这样做。

如果你确实需要一个可变大小的数组,那么你需要动态分配内存,然后使用从中返回的地址初始化结构中的指针。

© www.soinside.com 2019 - 2024. All rights reserved.