在2D矩阵的上下文中,C与**和& **之间的差异

时间:2016-02-22 05:32:12

标签: c pointers matrix

我正在做家庭作业,用动态分配的2d数组进行矩阵乘法。我编写了以下函数来加载矩阵:

void loadMatrix(FILE* fp, int** matrix, int rowSize, int colSize) {

    for (int i = 0; i < rowSize; i++) {
        for (int j = 0; j < colSize; j++) {
            fscanf(fp, "%d", &matrix[i][j]);
        }
    }
}

我将矩阵声明为全局变量,如下所示:

int **a;

然后按如下方式初始化并加载它:

// allocate memory for the array rows
a = (int **) malloc(m * sizeof(int*));

// allocate memory for array columns
for (int i = 0; i < m; i++) {
    a[i] = malloc(k * sizeof(int));
}

loadMatrix(fp, a, m, k);

一切都按预期工作,但教师提供的功能签名如下:

void loadMatrix(FILE*, int ***, int, int);

我尝试使用该签名,并使用&amp;传递矩阵的地址,并删除&amp;从我的loadMatrix函数,认为输出应该是相同的,但使用***不能按预期工作。我错过了什么?如果有三指针,那么使用三指针的优势是什么?

1 个答案:

答案 0 :(得分:1)

您的代码存在以下问题:

  • 您不是在分配2D数组,而是在整个堆中分割基于指针的指针查找表。这种做法很普遍,但做法很差:没有理由将您的2D阵列分割并在多个地方分配。代码变得复杂,程序变慢,没有任何好处。

  • 没有理由将矩阵声明为全局变量。

  • 在C中永远没有理由拥有3级间接。这被称为&#34;三星编程&#34;并且是程序设计根本缺陷的一个标志。不幸的是,这意味着您的老师不是C知识的可靠来源。

相反,您应该分配2D数组:

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

void loadMatrix(FILE* fp, int rowSize, int colSize, int matrix[rowSize][colSize]) 
{
    for (int i = 0; i < rowSize; i++) {
        for (int j = 0; j < colSize; j++) {
            fscanf(fp, "%d", &matrix[i][j]);
        }
    }
}


int main (void)
{
  const int ROWS = 4;
  const int COLS = 5;
  int (*matrix)[ROWS][COLS]; // array pointer to variable-length array

  matrix = malloc( sizeof(int[ROWS][COLS]) );
  if(matrix == NULL)
  {
    // error handling
  }

  FILE* fp = ...;
  loadMatrix(fp, ROWS, COLS, *matrix); // contents of what the pointer points at is the array

  free(matrix);
}

为了完全理解上述内容,我建议研究可变长度数组以及数组如何衰变为指向第一个元素的指针。