【问题标题】:How to create a matrix structure in C?如何在C中创建矩阵结构?
【发布时间】:2018-12-09 23:44:53
【问题描述】:

我是 C 的初学者,但我目前正在尝试创建一个矩阵数据结构,该结构可以在不同的函数中使用,而不必显式传递列数和行数(例如: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;
}

哪个(据我理解)分配包含列的行,然后为列分配内存,然后包含实际数据。

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

A=startmatrix(A,2,3);
A.data[1,1]=1;
printf("%d",A.data[1,1]);

它返回一个警告(赋值使指针从没有强制转换的整数)和实际矩阵中的数字 4。

谁能解释一下我做错了什么?


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

//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;
}

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

#include <stdlib.h>

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

matrix startmatrix(int n_row, int n_col){
    matrix mat;
    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;
}

到目前为止,这就是我用于这个问题的所有代码,不多也不少。我正在阅读建议的答案和 cmets 并尝试它们,看看它们是否有效。提前感谢您的帮助。

【问题讨论】:

  • 您应该了解如何使用 typedef 和 VLA,以轻松访问分配的内存区域作为任何维度的二维数组。
  • 你真的不需要startmatrix() 的第一个参数——行数和列数就足够了。您需要定义一个本地 matrix 变量,以便您可以返回它,但这不是一个大问题。
  • 这个answer 应该适合这里。它回答了你的问题
  • 我会比 Basile Starynkevitch 更进一步,并建议类似于 this 的内容。它不仅允许任何大小的矩形二维矩阵,它还允许您创建引用相同实际数据(行向量、列向量、对角线、子矩阵)的不同矩阵,并且只要您随时丢弃每个矩阵使用它们,数据使用的内存会为您管理。
  • A.data[1,1] 发生了什么? 1,1 是 comma expression,它没有“第 1 行,第 1 列”的含义。所以,即使它看起来有效,也是完全错误的。

标签: c pointers matrix struct


【解决方案1】:

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

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

【讨论】:

  • 谢谢,这可能是正确的做事方式;但我对其进行了测试,不幸的是现在程序在尝试将变量分配给矩阵结构时崩溃了。我认为 startmatrix 函数有错误,但我不确定在哪里。
  • @guscomm:这可能意味着你有一个单独的问题,现在通过修复第一个问题暴露出来。如果没有显示第二个问题的代码,那么任何人都无能为力。
【解决方案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 数据的一种非常基本的方法。在笔和纸上试一试,写下每个单元格的地址。你会发现这是有道理的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 2017-04-28
    • 1970-01-01
    • 2019-10-10
    • 2018-06-08
    • 2023-04-07
    相关资源
    最近更新 更多