繁体   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