【问题标题】:Allocation of 2D arrays (matrices) in C?在 C 中分配二维数组(矩阵)?
【发布时间】:2016-06-06 10:40:48
【问题描述】:

我正在研究 C,特别是使用指针创建矩阵,而让我感到困惑的一件事是,在二维数组中 matrix[i][j] 等于

*(*(matrix+i)+j) 

这是否意味着位于[3][3] 位置的元素由*(*(0+3)+3)) 给出?

更具体地说,我正在使用以下代码在 C 中编写一个矩阵:

  double** makeMatrix(unsigned int rows, unsigned int cols)
{
  unsigned int i;
  double** matrix;
  matrix = (double** ) malloc(rows * sizeof(double *));
   if (!matrix) { return NULL; }/* failed */
     for (i = 0; i < rows; i++)
     {
      matrix[i] = (double *) malloc(cols*sizeof(double));
      if (!matrix[i])
      return NULL; 
     }
return matrix;
}

因此,为数组中的每个第 i 个元素分配内存 - 这就是我们为 [i][j] 得到 ((matrix+i)+j) 的原因 - 由于每个元素都有自己的内存块这一事实?

【问题讨论】:

  • 请先在网站上搜索,然后再发布问题。 stackoverflow.com/search?q=%5Bc%5D+2d+matrices
  • 在你用傲慢的反驳爆发之前,我已经“在网站上搜索”了这个问题,但没有任何内容与我所问的具体匹配。
  • 请澄清您当时的要求(例如,数组是如何定义的?)。你的帖子有点乱,现在,不是很有用。查看此页面以了解此处使用的降价的一些介绍:stackoverflow.com/editing-help
  • 正确格式化你的队列!!
  • 代码中没有二维数组,也没有可以指向一个的数组。

标签: c arrays matrix


【解决方案1】:

在 C 中,没有“真正”意义上的多维数组(如在 LISP、C# 或 C++/CLI 中)。相反,您可以声明的是数组数组(或指针数组,其中每个指针由malloc 等分配)。例如:

int matrix[2][3];

定义两元素数组,其中每个元素的类型为三个ints的数组。

现在,当你引用一个最终的数组元素时,你需要首先去引用那个内部数组,然后去引用int对象:

int value = matrix[2][3];

相当于:

int value = (*(*(matrix + 2) + 3));

【讨论】:

  • 您所写的多维数组(在具有线性地址空间的机器中也是如此),与 OP 所要求的不同(指向数组指针数组或锯齿数组的指针)。
  • @user694733:是的,我知道,但总体思路是一样的,而且数组数组更容易解释。
  • @user694733:所以它回答了 OP 想要什么或它实现了什么。正如您自己所说:OP 实现的不是二维数组,所以我认为答案很好。虽然我不同意“没有多维数组”。这只是与int i[rows, cols];不同的写作方式。
  • 我还是称这个多维数组。只是写法不同。在长度存储在数组对象中的语言中,事情会稍微复杂一些。
  • (*(*(matrix + 2)) + 3); 应该是 *(*(matrix + 2) + 3);,否则你取消引用两次并添加 3。
【解决方案2】:

a[i]syntactic sugar*(a + i)。这意味着a[3][3] 等价于*(*(a + 3) + 3)

还有一点值得注意,3[a] 等价于*(3 + a),即*(a + 3),即a[3]

【讨论】:

  • 我知道数组是在 C 中分配的,我们返回一个指向第一个元素的指针,并添加 i 以获得第 i 个元素,但我想我不明白是你得到二维数组的时候。为什么不是*(a+i) + *(a+j)?
  • OP的代码答案是错误的!相同的语法并不意味着相同的语义。这种永恒的错误观念的问题之一就是有两种截然不同的事物具有相同的语法。
  • @Olaf 当我回答这个问题时,里面没有任何代码,已经进行了编辑。问题是“这是否意味着位于位置 [3][3] 的元素由 *(*(0+3)+3)) 给出?”
  • @AinJalut C 中实际上没有数组,只有指针。您可以将二维数组视为指向内存的指针,它保存指向内存的指针,每个内存都保存数据。
  • @Anton:所以要么你应该回滚问题(发布答案后问题不得更改)。但是,这次我强烈反对,因为原版缺少重要部分。您应该要求澄清而不是提供过早的答案。或编辑您的答案。
猜你喜欢
  • 2011-12-02
  • 1970-01-01
  • 2020-10-16
  • 2018-08-21
  • 2021-07-18
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多