是的,请使用
array[position]
,即使参数类型是
int *array
。你提供的另一种方式(
*array[position]
)在这种情况下实际上是无效的,因为
[]
运算符比
*
运算符具有更高的优先级,它等同于
*(array[position])
,试图取消引用
a[position]
的值,而不是其地址。
对于多维数组会更复杂一些,但你可以这样做:
int m = 10, n = 5;
int matrixOnStack[m][n];
matrixOnStack[0][0] = 0;
matrixOnStack[m-1][n-1] = 0;
int (*matrixInHeap)[n] = malloc(sizeof(int[m][n]));
matrixInHeap[0][0] = 0;
matrixInHeap[m-1][n-1] = 0;
matrixInHeap
的声明应该这样解释:指向
n
个
int
值数组的“thing”,因此
sizeof(*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
如果在函数内不需要使用变量
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
(或仅将其用作类似函数的参数)的情况下,但至少它有效。
关于可读性的最后一点:使用 malloc(sizeof(int[len]))
等同于 malloc(len * sizeof(int))
(任何告诉你不同的人都不理解 C 语言结构填充),但第一种写法让读者明显地了解我们正在谈论一个数组。对于 malloc(sizeof(int[m][n]))
和 malloc(m * n * sizeof(int))
同样适用。
void myFunction(int **matrix, ...)
并使用像matrix[i][j] = value
这样的东西? - Thi G.