是的,请使用array[position]
,即使参数类型是int *array
. 在这种情况下,您给 ( *array[position]
) 的替代方案实际上是无效的,因为[]
运算符优先于*
运算符,使其等效于*(array[position])
which 试图取消引用 的值a[position]
,而不是它的地址。
对于多维数组,它变得有点复杂,但你可以这样做:
int m = 10, n = 5;
int matrixOnStack[m][n];
matrixOnStack[0][0] = 0; // OK
matrixOnStack[m-1][n-1] = 0; // OK
// matrixOnStack[10][5] = 0; // Not OK. Compiler may not complain
// but nearby data structures might.
int (*matrixInHeap)[n] = malloc(sizeof(int[m][n]));
matrixInHeap[0][0] = 0; // OK
matrixInHeap[m-1][n-1] = 0; // OK
// matrixInHeap[10][5] = 0; // Not OK. coloring outside the lines again.
matrixInHeap
应该解释声明的方式是指向的“事物”matrixInHeap
是一个值数组n
int
,sosizeof(*matrixInHeap) == n * sizeof(int)
或矩阵中整行的大小。matrixInHeap[2][4]
之所以有效,是因为matrixInHeap[2]
将地址推进matrixInHeap
,2 * sizeof(*matrixInHeap)
这会跳过整整两行n
整数,从而产生第三行的地址,然后最终[4]
选择第三行中的第五个元素。(请记住,数组索引从 0 开始,而不是 1)
当指向正常的多维 c 数组时,您可以使用相同的类型(假设您已经知道大小):
int (*matrixPointer)[n] = matrixOnStack || matrixInHeap;
现在假设您想要一个将这些可变大小矩阵之一作为参数的函数。当变量较早声明时,该类型具有有关大小的一些信息(堆栈示例中的两个维度,以及堆示例中的最后一个维度n
)。因此,函数定义中的参数类型将需要该n
值,我们实际上可以这样做,只要我们将其作为单独的参数包含在内,像这样定义函数:
void fillWithZeros(int m, int n, int (*matrix)[n]) {
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
matrix[i][j] = 0;
}
如果我们不需要m
函数内部的值,我们可以完全忽略它,只要我们保留n
:
bool isZeroAtLocation(int n, int (*matrix)[n], int i, int j) {
return matrix[i][j] == 0;
}
然后我们在调用函数时只包含大小:
fillWithZeros(m, n, matrixPointer);
assert(isZeroAtLocation(n, matrixPointer, 0, 0));
可能感觉有点像我们正在让编译器为它工作,特别是在我们根本不在n
函数体内使用(或仅作为类似函数的参数)的情况下,但至少它可以工作。
关于可读性的最后一点: usingmalloc(sizeof(int[len]))
等效于malloc(len * sizeof(int))
(并且任何告诉您否则不理解 c 中的结构填充的人),但是第一种编写方式使读者很明显我们正在谈论数组。malloc(sizeof(int[m][n]))
和也是如此malloc(m * n * sizeof(int))
。