【问题标题】:Convert pointer to two dimensional array将指针转换为二维数组
【发布时间】:2017-01-17 15:39:16
【问题描述】:

给定的是这个函数

void printMatrix(int *m, int ze, int sp)

现在 *m 应该是一个二维数组(或者更像是一个指向二维数组的指针)。

那么我怎样才能将这个*m 用作m[][] 呢?

【问题讨论】:

  • 你能展示一个初始化将被传递给m的值的例子吗?目前尚不清楚您是创建了一个实际的二维数组并严重强制将其解释为一维数组,还是您实际上有一个想要处理为二维数组的一维数组。
  • 你能改变函数签名吗?如果是这样,请使用 VLA。

标签: c arrays pointers multidimensional-array


【解决方案1】:

可变长度数组可以在这里为您提供帮助:

int (*p)[sp] = (void*) m;

现在您可以通过p[i][j] 访问元素。

See it live on Coliru

关于严格的别名规则的明确定义:它是有效的,因为mp 都指向兼容的类型。

【讨论】:

  • 会不会违反严格的别名规则?
  • @EugeneSh。根据我在 cppreference 上的发现,它是有效的。也许我稍后会深入研究该标准的副本。
  • 是的,看起来不错。 p 是一个指向整数数组的指针(尽管语法可能令人困惑),它肯定与指向整数数组的指针兼容 :) Update No..wait。有点不对劲……让我消化一下……
  • 是的,没关系,抱歉 :) 我怀疑p[i] 会指向什么。显然它会指向ith“行”*(p + sp*sizeof(int))
  • int(*)[n]int* 不是兼容的类型,这不是可以的原因。但我相信一个指向类型的指针总是可以转换为一个指向类型的数组指针,而不会违反严格的别名。 “一个对象的存储值只能由具有以下类型之一的左值表达式访问:” /--/ “在其成员中包含上述类型之一的聚合或联合类型”。 int 数组是一个聚合,它在其成员中包含 int。
【解决方案2】:

您不能,因为m 只能取消引用一次。但是如果你知道数组的维度,你可以计算一维索引为

element[i][j]=m[i * width + j];

【讨论】:

  • 实际上,element[i][j]=m[i * width + j]; 的计算更有意义
  • 感谢你们! :)
  • 为什么不简单地使用 memcpy 以便最佳地利用数据缓存?此代码可能会也可能不会这样做。
  • @Lundin 我认为= 在这里表示“表示为”,而不是实际复制到新数组。
  • 哦……对了,@Quentin,这就是这里的意思。
【解决方案3】:

如果m 确实是一个指向二维矩阵的指针,您可以这样声明参数:

void printMatrix(int rows, int cols, int m[rows][cols]) {
    ...
}

【讨论】:

    【解决方案4】:

    您将不得不假设它是一个所谓的“错位”数组。在这种情况下,您可以创建一个新数组作为 VLA:

    void printMatrix(int *m, int ze, int sp)
    {
      int array[ze][sp];
      memcpy(array, m, sizeof(int[ze][sp]));
    }
    

    或者作为一个动态分配的二维数组:

    void printMatrix(int *m, int ze, int sp)
    {
      size_t size = sizeof(int[ze][sp]);
      int (*array)[sp] = malloc(size);
      memcpy(array, m, size);
      ...
    }
    

    然而,将int* 转换为数组指针类型是有问题的做法,这将导致指针别名问题。最好的当然是您可以重写函数原型以正确使用二维数组。

    【讨论】:

    • 好的,这也是一个很好的答案(并且似乎与我的主题最合适)。谢谢,我也试试
    • 你如何定义“错位数组”?隐藏在指向其第一个元素的指针后面的多维数组?
    • @Quentin 是的,类似的东西经常用于较旧的 C 程序中,因为它们没有指向 VLA 的指针。通常你会做int* array = malloc(x*y*sizeof(int))
    • 谢谢,Google 在这方面没有帮助 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 2013-05-01
    • 2019-01-23
    相关资源
    最近更新 更多