【问题标题】:How can a double pointer be used for a two dimensional matrix?双指针如何用于二维矩阵?
【发布时间】:2014-02-20 07:19:42
【问题描述】:

我正在通过实现 Conway 的生命游戏来尝试 C 语言。

我正在尝试动态构建两个网格(int 矩阵),一个用于当前网格,一个用于下一代网格,因此在确定了下一代网格后,我只需交换指针即可。

起初我绝望地尝试定义指向网格的指针,如int * grid,你不能用第二组括号下标,如[][],因为 - 显然 - 第一组括号返回一个 int。

我也尝试过int * grid[HEIGHT][WIDTH] 之类的方法,但这会给将这样的一个指针分配给另一个指针时出现问题。 (事实上​​,我不知道这在记忆中的真正作用!)

在我天真的希望中,我认为在偶然发现双指针之后可以进行以下操作。程序编译,但在指示的行上运行时失败。 (在 Windows 中,除了问题事件名称是 APPCRASH 之外,我没有得到更多详细信息。

免责声明:这不是实际程序,只是问题的概念证明。

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

int HEIGHT = 20;
int WIDTH = 20;

int ** curr_gen; // Current generation
int ** next_gen; // Next generation

/* Entry Point main */
int main(int argc, char** argv) {

    // Allocate memory for the grids
    curr_gen = malloc(sizeof (int) * WIDTH * HEIGHT);
    next_gen = malloc(sizeof (int) * WIDTH * HEIGHT);

    curr_gen[0][0] = 0; //<< PROGRAM FAILS HERE

    // Release heap resources
    free(curr_gen);
    free(next_gen);

    return 0;
}

【问题讨论】:

  • 你不能有一个链接的答案。为了处理您的案件,您需要了解内存中发生了什么
  • 术语“双指针”是模棱两可的。它可以表示指向指针的指针(some_type** 类型)或指向double 类型的指针(double*)。

标签: c pointer-to-pointer


【解决方案1】:

您可以简单地分配空间并将指针转换为定义列和行大小的类型。通过 [][] 查找指针很昂贵。并且以这种方式构建动态多维数组应该保留给 ragid 数组.. IE:仅在必要时使用它。

你可以定义一个类型:

typedef int MyArray[20][20];

然后将 malloc 指针转换为你想要的类型:

MyArray * curr_gen = (MyArray *) malloc(...);

但是,这假设您有一个常数,在编译时已知高度和宽度。如果它必须是动态的,那么一定要使用索引到指针表的方法。但请记住,实际查找的指针必须在可能导致流水线停顿和潜在缓存未命中的最后一分钟加载。让它比通过 [row * 20 + col] 自己做数学要贵 100 倍。

所以你应该问自己的真正问题是“它需要快速运行,还是我希望代码看起来‘整洁’?”

【讨论】:

  • 上面的 typedef 没有为我编译,说“错误:预期的标识符或 '(' before '[' token”。
  • 对不起 C# 太多了。试试这个: typedef int MyArray[20][20];
  • 或者对于指向所述数组的指针:typedef int (*MyArray)[20][20];
【解决方案2】:

http://c-faq.com/aryptr/dynmuldimary.html 中描述了一种常见的方法

【讨论】:

  • 我喜欢这个解决方案,虽然在使用 [0][0] 访问我的网格时我仍然遇到分段错误,但我会将其作为一个单独的问题发布。
  • 没关系,我设法解决了这个问题,所以我会接受这个答案。非常感谢。
  • 请注意,您应该在此处或此站点上发布答案的基本部分,否则您的帖子可能会被删除See the FAQ where it mentions answers that are 'barely more than a link'. 如果您愿意,您仍然可以包含链接,但只能作为“参考'。答案应该是独立的,不需要链接。
【解决方案3】:

您可以使用int* 作为我的网格类型。

通过宏定义或函数将二维位置转换为一维:

#define MATRIX2INDEX(x, y, width)  ((x) + (y) * (width))  // `width` is the max of x + 1 :)
int Matrix2Index(int x, int y, int width)
{
    return MATRIX2INDEX(x, y, width);
}

通过int*中的二维位置访问数据:

int* grid = (int*)malloc(sizeof(int) * WIDTH * HEIGHT);
grid[MATRIX2INDEX(0, 0, WIDTH)] = 0; // here: get the data you want by 2D position
free(grid); grid = NULL;

【讨论】:

  • 这是一个危险的宏。考虑一下当你为 Y 值传入类似“row + rowOffset”的东西时会发生什么。行偏移量乘以宽度。而你的破碎。每当您编写这样的宏时,您都需要明确强制操作顺序:#define MATRIX2INDEX(x, y, width) ((x) + (y)*(width))
  • 你是对的。谢谢。我对其进行了修改,并将对此更加谨慎。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2013-11-28
  • 2011-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多