我有一个函数试图循环结构中的2D数组:
typedef struct node
{
int grid[3][3];
} Node;
void someFunction(Node *node) {
int grid[3][3] = node->grid;
//loop through
}
当我尝试编译时,我得到了一个
mp.c:42:错误:初始化程序无效
答案 0 :(得分:11)
您无法在C中分配数组。这是不允许的。当你写道:
int grid[3][3] = node->grid;
您试图从传入的grid
初始化本地数组node
。如果允许(不是这样),那么之后就不需要循环了。
你可以分配结构,即使它们包含数组,所以如果本地结构是Node
,你可以写:
Node local = *node;
之后您无需循环遍历数组以初始化local
。
您可以遍历数组,一次复制一个元素:
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
现在指向数组的左上角(如果您看到数组从左到右逐渐增长)。存储在那里的值是一个普通数字,而不是一个初始化的指针,但是当编译器评估grid[0]
时,它被强制假设会产生一个指针。如果node->grid[0][0]
包含零,则可能会出现分段错误和核心转储以取消引用空指针(假设指针和int
的大小相同,这通常适用于32位系统),或其他一些未定义的行为。如果node->grid[0][0]
包含另一个值,那么行为仍未定义,但不太可预测。
答案 1 :(得分:1)
如果你不想复制,只需要一个指向结构中数组的指针(注意:如果你将值赋给*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;
}
上面的代码显示了一个使用指针的简单函数。它们都是安全且符合标准的。
如果你想使用指向int**
的指针,你将不得不以不同的方式使用它,因为,数组是内存中的线性存储(所以上面的代码可以使用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);
}
答案 2 :(得分:0)
请参阅此另一个主题以获取相同问题以及不涉及复制内存的答案: