C:如何将指针转换为多维数组来访问它

C:如何将指针转换为多维数组来访问它,c,C,我有一个函数调用,如: int Filter(short* array, short nNumRow, short nNumCol) 但在它里面,我想这样处理数组: array[y][x] = xx; 我试图通过声明一个数组来解决这个问题 short help[nNumRow][nNumCol]; help = array; 但这不是那样的。如何在不更改函数参数列表的情况下处理该问题(此*数组是我无法更改的不同函数的结果)?最好的当然是不需要(内存的)拷贝。 也许另一个选择是 array

我有一个函数调用,如:

int Filter(short* array, short nNumRow, short nNumCol)
但在它里面,我想这样处理数组:

array[y][x] = xx;
我试图通过声明一个数组来解决这个问题

short help[nNumRow][nNumCol];
help = array;
但这不是那样的。如何在不更改函数参数列表的情况下处理该问题(此*数组是我无法更改的不同函数的结果)?最好的当然是不需要(内存的)拷贝。 也许另一个选择是

 array[y*nNumCol + x] = xx;
但我不喜欢这种计算。那么如何做到最好呢?
谢谢

这不是最有效的方法,但您可以在函数内创建二维数组并将原始数组复制到其中:

#包括
int筛选器(短*数组、短nNumRow、短nNumCol){
短arr[nNumRow][nNumCol];
memcpy(arr,array,nNumRow*nNumCol*sizeof(short));
对于(int i=0;i
看到它在这里运行:

如何在不更改函数参数列表的情况下处理该问题

如果您不能做到这一点,那么您就只能使用“mangled array”
array[y*nNumCol+x]
表示法(这是旧式的,但在其他方面还可以)

最好且正确的解决方案是将函数更改为:

int Filter (short nNumRow, short nNumCol, short array[nNumRow][nNumCol])
{
   ...
   array[x][y] = something;
}

最后一种方法是在函数内部进行脏指针转换,我不推荐这种方法,除非您正在维护一些无法更改的旧垃圾。编写这样的代码需要您确切地知道自己在做什么,因为如果实际数据的类型或对齐方式不匹配,您将得到非常奇怪的bug。就C语言而言,下面的代码是安全的,但并不漂亮:

// BAD CODE, avoid this solution

#include <stdio.h>

int Filter (short* array, short nNumRow, short nNumCol)
{
  short(*array2D)[nNumCol];            // pointer to array of type short[nNumCol]
  array2D = (short(*)[nNumCol])array;  // dirty pointer conversion

  for(int i=0; i<nNumRow; i++)
  {
    for(int j=0; j<nNumCol; j++)
    {
      printf("%d ", array2D[i][j]);
    }
    printf("\n");
  }

  return 0;
}

int main (void) 
{
  short array[2][2] = { {1,2}, {3,4} };

  Filter((void*)array, 2, 2);
}
//错误代码,请避免使用此解决方案
#包括
int筛选器(短*数组、短nNumRow、短nNumCol)
{
short(*array2D)[nNumCol];//指向short[nNumCol]类型数组的指针
array2D=(短(*)[nNumCol])数组;//脏指针转换
对于(int i=0;i来说,最好的(最佳)方法是您自己的解决方案:

array[y*nNumCol + x] = xx;
出于“美观”的原因,您可以使用类似宏的函数来访问该数据:

#define arrElement(array,x,y) ((array)[(y)*nNumCol + (x)]]))
如果只需要将此技巧应用于一个数组,则可以简化宏:

#define arrElement(x,y) (array[(y)*nNumCol + (x)]]))
#define arrElement(x,y,nNumCol) (array[(y)*(nNumCol) + (x)]]))
如果在函数调用之前数组的大小未知,则需要为宏增加一些复杂性:

#define arrElement(x,y) (array[(y)*nNumCol + (x)]]))
#define arrElement(x,y,nNumCol) (array[(y)*(nNumCol) + (x)]]))

注意:我并没有将上面的语句完全发到文本中,但我在过去几次成功地使用了这个技巧



只有当数组始终具有相同的大小时,才能使用指针类型(根据您的问题)。否则,您必须在运行时动态定义指针类型,这介于困难和不可能之间



明智的做法是将数组大小也传递给函数,并检查坐标是否确实落在数组内。否则,您可能会遇到未定义的行为,访问定义范围之外的数据。

所以您是说您希望将函数参数声明为
short*array
,但使用
array[m][n]
'在函数定义中?你能为你的函数提供一个输入示例吗?如果我理解正确,你可以使用memcpy来完成你想做的工作。我同意你的第一种方法是最好的,并且符合规则,但不是要求的。数组是一些现有代码的结果,我无法更改。第二次检查的问题可能你真的需要为array2D花费内存,不是吗?@Arno
array2D
只是一个指针,所以它只需要典型指针的内存。在这种情况下,它可能适合CPU寄存器。@Arno不,你不能用C按值传递数组。在第一个例子中,
短数组[nNumRow][nNumCol
“衰减”在第二个示例中,
short(*array2D)[nNumCol];
也只是一个数组指针。你们都是对的,读得不够仔细。谢谢!我想我自己无法管理这个“脏”指针转换。“否则,您将不得不在运行时动态定义指针类型,这介于困难和不可能之间”。呃,这并不是那么困难。给定数组
int-array[x][y]
,指向这样一个数组的指针是
int(*ptr)[x][y]
。不过为了方便访问,您应该删除内部维度:
int(*ptr)[y]
。就是这样。@Lundin:如果数组的大小在设计时已知,那就很好了。我记得我尝试过用只有在运行时才知道的大小定义数组(即变量/随机x和y),编译器拒绝了我的尝试。抱歉,但是你的C语言知识已经过时20年了。语言在1999年发生了变化。是时候研究C99版本和可变长度数组了。同样抱歉,但这是汽车工业中使用的,以确保刹车和其他东西始终按预期工作。OTOH,我说的好uld了解这条新闻:D Tnx为提醒。不,根据MISRA-C:2012,汽车行业主要使用C99或C11。他们落后了,直到2010年前后才愿意使用C99,就像我一样。