【问题标题】:Storing an array of 2d arrays in C在C中存储二维数组的数组
【发布时间】:2014-12-07 21:08:35
【问题描述】:

我正在尝试将一系列矩阵存储在一个连续的内存块中,然后检索它们。每个数组的大小相同 (n x n)。

据我了解,我需要做的是:

  1. 分配并初始化我需要存储/检索的每个数组。

  2. 分配一块大小为(# arrays) * sizeof (1 array)的连续内存块,并为块的开头分配一个指针***matrices

  3. 将每个数组复制到matrices[0]matrices[1]、...的块中

  4. 通过将matrices[0]matrices[1]、...发送到matrix_print函数来打印它们

现在,显然我误解了一些东西,因为它不起作用。这是我在崩溃之前得到的输出:

Matrix A is 16 bytes.
Matrix B is 16 bytes.
So, we will allocate 32 bytes in row_blocks.
Matrix A:
| 1  1 |
| 2  2 |
Matrix B:
| 2  2 |
|

这是我正在尝试开始工作的测试用例的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void matrix_print(int dim, int ***matrix);
void matrix_init(int dim, int matrix[dim][dim], int val);

int main(int argc, char *argv[])
{
    int dim = 2;

    int A[dim][dim], B[dim][dim];

    matrix_init(dim, A, 1);
    matrix_init(dim, B, 2);

    printf("Matrix A is %d bytes.\n", sizeof A);
    printf("Matrix B is %d bytes.\n", sizeof B);

    int ***matrices = malloc(sizeof A + sizeof B);

    printf("So, we will allocate %d bytes in matrices.\n\n",
            sizeof A + sizeof B);

    memcpy(matrices[0], A, sizeof (A));
    memcpy(matrices[1], B, sizeof (B));

    printf("Matrix A:\n");
    matrix_print(dim, &matrices[0]);
    printf("Matrix B:\n");
    matrix_print(dim, &matrices[1]);

    return 0;
}

void matrix_print(int dim, int ***matrix)
{
    for (int i = 0; i < dim; i++) {
        printf("|");
        for (int j = 0; j < dim; j++) {
            printf("%2d ", matrix[i][j]);
        }
        printf("|\n");
     }
}

void matrix_init(int dim, int matrix[dim][dim], int val)
{
    for (int i = 0; i < dim; i++) {
        for (int j = 0; j < dim; j++) {
            matrix[i][j] = val;
        }
     }
}

【问题讨论】:

    标签: c arrays matrix malloc


    【解决方案1】:

    C 中二维矩阵的乐趣!

    当您将一维数组 int[dim] 传递给函数时,它会衰减为指向其第一个元素 int *int[] 的指针,在此过程中会丢失有关其大小的信息。

    二维数组int[dim][dim] 不会衰减为双指针int **,而是衰减为指向大小为dim 的整数行的第一个元素的指针,int (*)[dim]int[][dim]。也就是说,因为对行大小恒定的多维数组进行了特殊处理;它们被实现为连续的数据块,其中常量大小用于计算索引。 (这里的常量意味着所有行和所有矩阵运算的常量;在您的情况下,此值可以是 C99 中的变量。)

    int[dim][dim] 类型的矩阵不能表示为int **,因此您应该调整矩阵数组的类型:

    int (*matrices)[dim][dim];
    
    matrices = malloc(sizeof A + sizeof B);
    

    您的打印功能的签名也发生了变化:

    void matrix_print(int dim, int matrix[dim][dim])
    {
        for (int i = 0; i < dim; i++) {
            printf("|");
            for (int j = 0; j < dim; j++) {
                printf("%2d ", matrix[i][j]);
            }
            printf("|\n");
         }
    }
    

    你这样称呼它:

    matrix_print(dim, matrices[0]);
    

    没有地址运算符&amp;

    脚注:

    • int (*x)[dim] 是一个指向长度为 dim 的整数数组的指针。 int *x[dim] 是一个长度为 dim 的数组,其中包含指向 int 的指针。

    • 我认为,这种特殊处理归功于 Fortran 存储多维数组的方式。另一方面,如果您分配了一个指针数组,则它们是int **。这样的数据结构可以保存不规则的矩阵。

    • 矩阵是具有可变长度 (VLA) 的 C99 样式数组,无法初始化,因此 malloc 必须是单独的声明和赋值。

    【讨论】:

    • 搞定了,非常感谢。实际上,我之前曾尝试过 int *matrices[dim][dim] 并感到困惑,因为它不允许 VLA。尽管 int *(matrices)[dim][dim]! 它可以与括号一起使用
    猜你喜欢
    • 1970-01-01
    • 2014-01-04
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    相关资源
    最近更新 更多