如何在C中创建矩阵结构?

时间:2018-07-01 15:03:21

标签: c pointers matrix struct

我是C语言的初学者,但是我目前正在尝试创建一个矩阵数据结构,该结构可用于不同的函数中,而不必显式传递列数和行数(例如:{{1} }代替matrixMult(matrix A, matrix B))。到目前为止,我的方法是声明一个结构,例如

matrixMult(A, B, rowsA, columnsA, rowsB, columnsB)

然后,为了正确分配矩阵,我尝试使用以下函数

typedef struct matrix{
    int rows;
    int columns;
    int **data;
}matrix;

(据我所知)哪个会分配包含各列的行,然后为这些列分配内存,然后再包含实际数据。

上面的代码似乎可以正常工作,但是当我尝试向矩阵中输入一些数据然后稍后将其可视化时,例如:

matrix startmatrix(matrix mat,int n_row, int n_col){
    int i=0;
    mat.rows=n_row;
    mat.columns=n_col;

    mat.data=(int **) calloc(n_row,sizeof(int *));

    for(i=0;i<n_row;i++){
        mat.data[i]=(int *) calloc(n_col,sizeof(int));
    }
    return mat;
}

它返回警告(赋值使指针从不带强制转换的整数开始)和实际矩阵中的数字4。

有人可以解释我在做什么错吗?


编辑:添加我正在使用的完整代码。到目前为止,它仅包含2个文件:mainfile.c和matrix.h。我现在也了解(谢谢!),将A=startmatrix(A,2,3); A.data[1,1]=1; printf("%d",A.data[1,1]); 传递给mat是没有用的,我应该使用startmatrix,所以我相应地编辑了代码。 到目前为止,主要文件是:

A.data[][]

这将调用文件“ matrix.h”,其中包含以下内容(到目前为止,仅以下内容)

//Mainfile.c
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"


int main(){
    matrix A=startmatrix(2,3); //2 by 3 matrix
    A.data[1][1]=1; /*testing to see if the value 1 is passed to the first cell*/

    printf("\n%d\n",A.rows); //Prints number of rows stored by A
    printf("\n%d\n",A.columns); //Prints number of cols stored by A
    printf("\n%d\n\n",A.data[1][1]);  //Is supposed to print the value stored in the first cell
    return 0;
}

到目前为止,这就是我用于此问题的全部代码,仅此而已。我正在阅读建议的答案和评论,并对其进行尝试,以查看它们是否有效。预先感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

您不能访问像这样的二维数组-C不会这样对待它,对于编译器来说,它只是一个指向整数的指针。 C也无法识别多重索引的概念(多个索引之间用逗号分隔)。

您应该使用A.data[1]访问该行,这将为您提供指向特定行的指针,然后访问其中的所需项-A.data[1][1]

答案 1 :(得分:2)

作为C语言的初学者,您应该了解并且至少在开始时避免使用复杂的指针算术。对于矩阵情况,您实际上可以做简单的事情。我随意使用assert添加了非常基本的错误检测。

首先,请尽可能使用单个指针:

typedef struct matrix{
    int rows;
    int columns;
    int *data;
}matrix;

调整您的分配过程:

matrix startmatrix(int n_row, int n_col){
    assert(n_row>0 && n_col>0);
    matrix mat;
    mat.rows=n_row;
    mat.columns=n_col;
    mat.data=calloc(n_row*n_col,sizeof(int)); /* allocate memory and clear to zero */
    return mat; /* return copy of mat */
}

此函数的原型对我来说似乎有点有趣,所以我对其进行了一些更改。它应该具有与旧版本相同的效果。

如果要充分利用结构,请使用访问器函数,而不要使用原始数组索引:

int* matrixcell(matrix mat, int column, int row){
    assert(column < mat.columns && row < mat.rows);
    return &mat.data[row*mat.columns + column]; /* pointer arithmetic */
}
/* example of using it */
*matrixcell(mat, 1, 1) = new_value;

该算法是在1D数组中浏览2D数据的一种非常基本的方法。在纸和笔上尝试一下,写出每个单元格的地址。您会发现这很有意义。