简体   繁体   English

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

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

I have a structure, say foo that looks like this, 我有一个结构,例如foo ,看起来像这样,

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

There are other members in the structure they are not important to the question. 结构中还有其他成员,它们对问题并不重要。 Now, I want to static initialize the structure. 现在,我想静态初始化结构。

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;
}

There are two problem in the line indicated. 指示的行中有两个问题。 First, understandably the compiler doesn't recognise n and is there any way I can do something similar without creating a variable before? 首先,可以理解的是,编译器无法识别n ,并且有什么办法可以在不创建变量的情况下做类似的事情? Secondly, and most importantly, I realized that I have no idea how to create a 2D array and assign it to a pointer to pointers statically. 其次,最重要的是,我意识到我不知道如何创建2D数组并将其静态分配给指针。 Please help. 请帮忙。 I tried the following variations but nothing worked. 我尝试了以下变体,但没有任何效果。

/* 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}}

Note that this isn't technically 2D array, but a pointer-to-pointer array. 请注意,从技术上讲,这不是2D数组,而是指针到指针的数组。 But since compound literals cannot have variable length array type, and it doesn't seem that you want to use hardcoded dimensions, this may be the only way to go. 但是由于复合文字不能具有可变长度的数组类型,而且似乎也不想使用硬编码维,因此这可能是唯一的方法。

You'll need to split your arrays to 1D arrays of unknown size and use separate compound literals for them: 您需要将数组拆分为未知大小的一维数组,并为其使用单独的复合文字:

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

First of all size_t **point only makes sense if you intend to point at an array of size_t* . 首先, size_t **point仅在您打算指向size_t*数组时才有意义。 That doesn't seem to be the case here, so you need to change the type to a 2D array, or an array pointer. 这里似乎不是这种情况,因此您需要将类型更改为2D数组或数组指针。

Next problem is that C is rather cumbersome here - bluntly put, you can't have a "static dynamic" array, it must be either. 下一个问题是C在这里相当麻烦-坦率地说,您不能有一个“静态动态”数组,它必须是。 You can either have this: 您可以拥有:

#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

or alternatively perhaps a flexible array member in the form of an array of pointers, like this: 或者,也可以是指针数组形式的灵活数组成员,如下所示:

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);

None of these are particularly good alternatives, the syntax is messy and error prone. 这些都不是特别好的替代方法,语法混乱且容易出错。 The language is simply severely lacking here. 这里根本缺少语言。

In order to initialize a pointer statically, the entities you are pointing to need to have been declared. 为了静态地初始化指针,需要声明要指向的实体。 Only in rare cases, like maybe an embedded system where you know the address of something at compile time, would you know the actual value of the pointer to be initialized statically. 仅在极少数情况下,例如可能在嵌入式系统中您在编译时就知道某物的地址,才知道要静态初始化的指针的实际值。

I see a couple problems with what you're doing: 1) The compiler can't resolve what the value of n is at the time you are trying to use it to declare the size of your array. 我在做的事情有两个问题:1)编译器在尝试使用n声明数组大小时无法解析n的值。 Arrays need to have a size supplied in their declaration, unlike C#. 与C#不同,数组需要在声明中提供大小。 2) The "point" member of the struct is a pointer to pointers, but you're trying to initialize it with an array of arrays. 2)结构的“ point”成员是一个指向指针的指针,但是您尝试使用数组数组对其进行初始化。 If you want to point to an array of arrays, you only need the address of the [0][0] element, so *point not **point. 如果要指向数组数组,则只需要[0] [0]元素的地址,因此* point不需要* point。 From there you can use array notation to access the elements. 从那里,您可以使用数组符号来访问元素。

You need to do something like this: 您需要执行以下操作:

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
}

Then you can access the array by: 然后,您可以通过以下方式访问数组:

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

If you truly need pointers to pointers, then the initialization values will have to either be address references (&name) or values that are being cast as pointers, but I don't suggest doing that. 如果您确实需要指向指针的指针,则初始化值将必须是地址引用(&name)或被转换为指针的值,但是我不建议这样做。

If you truly need a variable size for your array, then you'll need to allocate memory dynamically and then initialize the pointer in the struct with the address returned from that. 如果确实需要为数组提供可变大小,则需要动态分配内存,然后使用从该数组返回的地址初始化结构体中的指针。

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

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