将动态3D矩阵传递给

时间:2017-11-18 19:03:17

标签: c arrays multidimensional-array dynamic-arrays

我有一些我可以访问的3D矩阵数据:data[x][y][z]

每个维度的大小仅在运行时才知道。

我通过使用(byte (*)[Y][Z]) malloc(…)转换malloc来获取此数据。

当我调用这个函数时,我知道矩阵的维数,但不是在编译时。因此,我不知道如何在函数中声明我收到这样的矩阵...

函数声明中此数据的参数类型是什么?

function(byte (*matrix)[][]) // doesn't work

2 个答案:

答案 0 :(得分:1)

使用以下函数声明函数:

function(size_t Y, size_t Z, byte matrix[][Y][Z])…

并将其命名为:

function(Y, Z, matrix);

C支持可变长度数组(根据版本可选或需要,但支持在现代编译器中很常见),但被调用函数不会自动知道维度。您必须以某种方式将它们传递给函数,并且在其声明中,函数必须声明维度。

请注意,尺寸通常可以是表达式;它们不一定是传递的确切参数。例如,您可以这样做:

function(size_t Y, byte matrix[][2*Y][3*Y])…
例如,

matrix[something][20][30]为10时声明一个Y的函数。

答案 1 :(得分:1)

以下是一些用于说明3D数组传递的代码。 3D阵列是方形矩阵的数组,它们将被相乘以产生最终结果。代码可能不是最有效的代码,但它确实说明传递3D VLA值并不是很难。

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

static void mat_copy(int x, int y, const int src[x][y], int dst[x][y]);
static void mat_list_multiply(int x, int y, const int matlist[*][*][*], int result[*][*]);
static void mat_multiply(int x, int y, int z, const int mat1[*][*], const int mat2[*][*], int result[*][*]);
static void mat_print(const char *tag, int m, int n, const int matrix[*][*]);

int main(void)
{
    int matrices[][4][4] =
    {
        //random -n 48 -- -99 99 | commalist -n 4 -B 12 -b '{ ' -T ' },' -R -W 4
        {
            {   63,  -61,   36,  -27, },
            {   37,  -86,   44,  -14, },
            {   57,   10,   74,   23, },
            {  -74,  -52,  -87,   53, },
        },
        {
            {  -34,   89,  -71,   34, },
            {  -68,  -44,  -89,  -95, },
            {   -4,  -44,    2,   80, },
            {   66,  -33,  -19,  -65, },
        },
        {
            {  -64,   11,   54,   20, },
            {   -7,   75,   -7,  -98, },
            {   52,   48,  -96,   76, },
            {  -38,  -46,  -85,    4, },
        },
    };
    enum { NUM_MATRICES = sizeof(matrices) / sizeof(matrices[0]) };
    int result[4][4];
    mat_list_multiply(3, 4, matrices, result);
    for (int i = 0; i < NUM_MATRICES; i++)
    {
        char name[16];
        snprintf(name, sizeof(name), "%s[%d]", "matrices", i);
        mat_print(name, 4, 4, matrices[i]);
    }
    mat_print("result", 4, 4, result);
    return 0;
}

static void mat_copy(int x, int y, const int src[x][y], int dst[x][y])
{
    memmove(dst, src, x * y * sizeof(src[0][0]));   // sizeof(src) is not OK
}

static void mat_list_multiply(int x, int y, const int matlist[x][y][y], int result[y][y])
{
    int product[y][y];
    mat_copy(y, y, matlist[0], product);
    for (int i = 1; i < x; i++)
    {
        mat_multiply(y, y, y, product, matlist[i], result);
        if (i != x-1)
            mat_copy(y, y, result, product);
    }
}

static void mat_multiply(int x, int y, int z, const int mat1[x][y], const int mat2[y][z], int result[x][z])
{
    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < z; j++)
        {
            result[i][j] = 0;
            for (int k = 0; k < y; k++)
                 result[i][j] += mat1[i][k] * mat2[k][j];
        }
    }
}

static void mat_print(const char *tag, int m, int n, const int matrix[m][n])
{
    printf("%s (%dx%d):\n", tag, m, n);
    for (int i = 0; i < m; i++)
    {
        const char *pad = "";
        for (int j = 0; j < n; j++)
        {
            printf("%s%8d", pad, matrix[i][j]);
            pad = " ";
        }
        putchar('\n');
    }
}

输出:

matrices[0] (4x4):
      63      -61       36      -27
      37      -86       44      -14
      57       10       74       23
     -74      -52      -87       53
matrices[1] (4x4):
     -34       89      -71       34
     -68      -44      -89      -95
      -4      -44        2       80
      66      -33      -19      -65
matrices[2] (4x4):
     -64       11       54       20
      -7       75       -7      -98
      52       48      -96       76
     -38      -46      -85        4
result (4x4):
 -455910    66386 -1265422  -575600
 -509373    79435 -1545267   -14906
 -392428  -468852   -38119  -464008
  137791   727227   393114  1044774