矩阵作为C中函数的参数

时间:2014-05-02 09:40:46

标签: c

我陷入了困境。这不是家庭作业,我只是以简单的方式提出问题。

我需要一个矩阵打印功能,矩阵作为参数与行和列数信息一起传递。矩阵在堆栈上分配。

在下面提到的函数原型中,MAT_COL是一个编译时定义。

void matrix_print(uint8_t (*mat)[MAT_COL], int row, int col)

并将矩阵元素打印为

print mat[i_row][i_col];

如果我有多个不同大小的矩阵i,e" MAT_COL"不再可用了。

一种可能的出路是

void matrix_print(uint8_t *in_mat, int row, int col)
{
    uint8_t (*mat)[col] = in_mat;          // typecast "col" is an arg
    // access them as eariler
    print mat[i_row][i_col];
}

这种方法有什么问题吗? C 中此问题的标准解决方案是什么。

4 个答案:

答案 0 :(得分:3)

C99支持以下函数声明方式:

void matrix_print(int row, int col, uint8_t in_mat[row][col])

答案 1 :(得分:0)

我认为你可以选择一个结构来帮助你处理这个类型。 如果类型与您的设计相关,则应明确说明。

以下是Ansi-C版本,因为您将C / C ++编写为标记。 在C ++中,你可以使你的矩阵成为一个类。

typedef struct
{
    int * data;
    int IsAllocated;
    unsigned row_max;
    unsigned col_max;
} Matrix;

void Matrix_construct(Matrix * m, int cols, int rows);
void Matrix_destruct(Matrix * m, int cols, int rows);
static int Private_GetElement(Matrix * m, unsigned col, unsigned row, int * element);
void Matrix_print(Matrix * m);

void Matrix_construct(Matrix * m, int cols, int rows)
{
    m->col_max = cols;
    m->row_max = rows;
    m->data = (int*) malloc(sizeof(int) * cols * rows);
    m->IsAllocated = 1;
}

void Matrix_destruct(Matrix * m, int cols, int rows)
{
    m->col_max = 0;
    m->row_max = 0;
    if(m->IsAllocated)
    {
        free(m->data);
        m->IsAllocated = 0;
    }
}

static int Private_GetElement(Matrix * m, unsigned col, unsigned row, int * element)
{
    int e = 0;
    if(m && element && col < m->col_max && row < m->row_max && m->IsAllocated)
    {
        *element = m->data[col + row * m->col_max];
    }
    else
    {
        e |= 1;
    }
    return e;
}

void Matrix_print(Matrix * m)
{
    unsigned col, row;
    int element;
    for( col = 0; col < m->col_max; ++col)
    {
        for( row = 0; row < m->row_max; ++row)
        {
            if(!Private_GetElement(m, col, row, &element))
            {
                printf("%i", element);
            }
        }
        printf("\n");
    }
}

如果在Matrix_construct中分配不同的尺寸,打印仍然有效,因为Matrix_print使用结构中存储的最大值。

使用不同的大小会导致更改上面示例中的结构,Matrix_print仍应按预期工作。


编辑:

编辑该示例以显示变量大小的动态分配如何。

答案 2 :(得分:0)

我做了一个&#34;终极&#34;使用以下链接在gcc C11 / C99中解决此问题:

http://c-faq.com/aryptr/dynmuldimary.html

http://c-faq.com/aryptr/ary2dfunc3.html

//compile with gcc --std=c11 program.c
#include <stdio.h>
#include <stdlib.h>

#define MV(array, ncolumns, i, j) array[i * ncolumns + j]
#define MX 9
#define MY 14

void input_matrix(int row, int column, double matrix[row][column]);
void print_matrix(int row, int column, double matrix[row][column]);

int main()
{
    int i=MX, j=MY;
    printf("Generate input values and print matrices with functions fn(int w, int k, double matrix[w][k]) (in C99 and C11)\n");
    double matrix1[i][j];
    input_matrix(MX,MY,matrix1);
    printf("matrix static\n");
    print_matrix(MX,MY,matrix1);

    double **matrix2;
    matrix2=malloc(MX*sizeof(double*));
    matrix2[0] = (double *)malloc(MX*MY*sizeof(double));
    for(i = 1; i < MX; i++)
        matrix2[i] = matrix2[0]+i*MY;
    input_matrix(MX,MY,(double (*)[])(*matrix2));
    printf("matrix two times allocated one for pointers, the second for data (double (*)[])(m[0])\n");
    print_matrix(MX,MY,(double (*)[])(matrix2[0]));
    free(*matrix2);
    free(matrix2);

    double *matrix3;
    matrix3=malloc(MX*MY*sizeof(double));
    input_matrix(MX,MY,(double (*)[])matrix3);
    printf("matrix alocated as twodimensional array\n");
    print_matrix(MX,MY,(double (*)[])matrix3);
    free(matrix3);

    j=MY;
    double (*matrix4)[j];
    matrix4 = (double (*)[])malloc(MX * sizeof(*matrix4));
    input_matrix(MX,MY,matrix4);
    printf("matrix alocated as an array of pointers to arrays m = (double (*)[])malloc(MX * sizeof(*m))\n");
    print_matrix(MX,MY,matrix4);
    free(matrix4);
    printf("\nThe End!\n");
    return 0;
}

void input_matrix(int row, int column, double matrix[row][column]){
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++)
            matrix[i][j]=i+1;
    }
}

void print_matrix(int row, int column, double matrix[row][column]){
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++)
            printf("%.2lf ", matrix[i][j]);
        printf("\n");
    }
}

答案 3 :(得分:-1)

我已将您的类型转换从int更正为uint8_t,因此以下情况确实有效。

void matrix_print(uint8_t *in_mat, int row, int col)
{
    uint8_t (*mat)[col] = (uint8_t (*)[col])in_mat;
    // access them like mat[y][x];
}

但是如果你试图避免可用的类型转换(这可能是也可能不是好的做法),你可以用偏移来实现它

void matrix_print(uint8_t *in_mat, int row, int col)
{
    // access them like mat[x + y*col];
}