簡體   English   中英

將結構中的二維數組分配給二維數組

[英]Assign to 2D array a 2D array in a struct

我有一個 function 試圖循環遍歷結構中的二維數組:

typedef struct node
{
    int grid[3][3];
} Node;


void someFunction(Node *node) {
     int grid[3][3] = node->grid;
     //loop through
}

但是,當我嘗試編譯它時,我得到了

mp.c:42:錯誤:初始化程序無效

您不能在 C 中分配 arrays。 根本不允許。 當你寫道:

int grid[3][3] = node->grid;

您試圖從傳入的node初始化本地數組grid 如果這是允許的(實際上是不允許的),那么之后你就不需要循環了。

但是,您可以分配結構,即使它們包含 arrays,因此如果本地結構是Node ,您可以編寫:

Node local = *node;

之后,您無需遍歷 arrays 即可初始化local

您可以遍歷 arrays,一次復制一個元素:

for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
        grid[i][j] = node->grid[i][j];

您還可以使用memmove()memcpy()

int grid[3][3];

assert(sizeof(grid) == sizeof(node->grid));
memcpy(grid, node->grid, sizeof(grid));

有一次,另一個答案建議:

換行:

 int grid[3][3] = node->grid;

至:

 int **grid = node->grid;

我注意到這是行不通的——並且合理地要求解釋原因。 這需要空間和格式。

首先,編譯器說明:

warning: initialization from incompatible pointer type

那就是說'你在玩火'。

假設我們忽略了這個警告。 本地grid現在指向陣列的左上角(如果您看到 arrays 從左到右向下並穿過)。 存儲在那里的值是一個普通數字,而不是一個初始化的指針,但是當編譯器評估grid[0]時,它被迫假設會產生一個指針。 如果node->grid[0][0]包含零,您可能會因為取消引用 null 指針而獲得分段錯誤和核心轉儲(假設指針和int大小相同,這通常在 32-位系統),或其他一些未定義的行為。 如果node->grid[0][0]包含另一個值,那么行為仍然是未定義的,但不是完全可預測的。

如果你不想做拷貝,只需要一個指向結構體中數組的指針(注意:如果你給*pointer賦值,結構體中數組的內容會改變),你可以達到這個目的有兩種方式:

#include <stdio.h>

typedef struct node
{
    int grid[3][3];
} Node;


void someFunction1(Node *node) {
     int i, j;
     int (*grid)[3] = node->grid;
     for(i=0; i<3; i++){
         for(j=0; j<3; j++){
             printf("%d ", grid[i][j]);
         }
         printf("\n");
     }
}

void someFunction2(Node *node) {
     int i, j;
     int *grid = (int*) node->grid;
     for(i=0; i<3; i++){
         for(j=0; j<3; j++){
             printf("%d ", grid[i*3+j]); // i * column_number + j
         }
         printf("\n");
     }
}

int main()
{
    Node t;
    int i, *p;

    //initialization: t.grid[0][0]=0,  ..., t.grid[2][2]=8
    for(i=0, p=(int*)t.grid; i<9; p++, i++){
        *p = i;
    }

    printf("Function1:\n");
    someFunction1(&t);

    printf("Function2:\n");
    someFunction2(&t);

    return 0;
}

上面的代碼顯示了一個簡單的 function 使用指針。 它們都是安全且符合標准的。

如果要使用指向指針int**的指針,則必須以不同的方式進行,因為 arrays 是 memory 中的線性存儲(因此上面的代碼可以使用int*指向數組的開頭並操作它),但int**不是。

編輯

所以這里出現了someFunction3()

void someFunction3(Node *node)
{
    int i, j;
    int **p;

    // 3 is the row number. Ignore checking malloc failure
    p = malloc(sizeof(int)*3);
    for(i=0; i<3; i++) {
        p[i] = (int*) node->grid[i]; //assign address of each row of array to *p
    }

    for(i=0; i<3; i++) {
        for(j=0; j<3; j++) {
            printf("%d ", p[i][j]);
        }
        printf("\n");
    }

    free(p);
}

請參閱此其他線程以獲取相同的問題以及不涉及復制 memory 的答案:

創建指向二維數組的指針

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM