[英]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.