在C中传递multidimensional array作为函数参数
在C中,我可以传递一个multidimensional array作为一个单一的参数,当我不知道数组的维度将是什么?
此外,我的multidimensional array可能包含string以外的其他types。
你可以用任何数据types来做到这一点。 简单地说,它是一个指针指针:
typedef struct { int myint; char* mystring; } data; data** array;
但不要忘记,你仍然需要mallocvariables,它确实有点复杂:
//initialize int x,y,w,h; w = 10; //width of array h = 20; //height of array //malloc the 'y' dimension array = malloc(sizeof(data*) * h); //iterate over 'y' dimension for(y=0;y<h;y++){ //malloc the 'x' dimension array[y] = malloc(sizeof(data) * w); //iterate over the 'x' dimension for(x=0;x<w;x++){ //malloc the string in the data structure array[y][x].mystring = malloc(50); //50 chars //initialize array[y][x].myint = 6; strcpy(array[y][x].mystring, "w00t"); } }
解除分配结构的代码看起来很相似 – 不要忘了在你所有的东西上调用free()。 (另外,在强大的应用程序中,您应该检查malloc()的返回 。)
现在让我们假设你想传递给一个函数。 你仍然可以使用双指针,因为你可能想要对数据结构进行操作,而不是指向数据结构指针的指针:
int whatsMyInt(data** arrayPtr, int x, int y){ return arrayPtr[y][x].myint; }
用以下方法调用此函数
printf("My int is %d.\n", whatsMyInt(array, 2, 4));
输出:
My int is 6.
将具有数组维数的第一个元素的显式指针传递为单独的参数。 例如,要处理int的任意大小的二维数组:
void func_2d(int *p, size_t M, size_t N) { size_t i, j; ... p[i*N+j] = ...; }
这将被称为
... int arr1[10][20]; int arr2[5][80]; ... func_2d(&arr1[0][0], 10, 20); func_2d(&arr2[0][0], 5, 80);
同样的原则适用于更高维数组:
func_3d(int *p, size_t X, size_t Y, size_t Z) { size_t i, j, k; ... p[i*Y*Z+j*Z+k] = ...; ... } ... arr2[10][20][30]; ... func_3d(&arr[0][0][0], 10, 20, 30);
你可以声明你的函数为:
f(int size, int data[][size]) {...}
编译器会为你做所有的指针运算。
请注意,尺寸大小必须出现在数组本身之前 。
GNU C允许参数声明转发(如果你确实需要在数组之后传递维度):
f(int size; int data[][size], int size) {...}
第一个维度虽然也可以作为parameter passing,但对于C编译器来说是无用的(即使对于sizeof运算符,在应用于数组传递时也是如此,因为参数始终将作为指向第一个元素的指针)。
int matmax(int **p, int dim) // p- matrix , dim- dimension of the matrix { return p[0][0]; } int main() { int *u[5]; // will be a 5x5 matrix for(int i = 0; i < 5; i++) u[i] = new int[5]; u[0][0] = 1; // initialize u[0][0] - not mandatory // put data in u[][] printf("%d", matmax(u, 0)); //call to function getche(); // just to see the result }