簡體   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