void process_array(int rows, int cols, int (*arr)[cols]) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// 使用指针算法访问元素
printf("%d ", *(*(arr + i) + j));
}
printf("\n");
}
}
在函数void process_array(int rows, int cols, int (*arr)[cols])
中,参数arr
是一个指向数组的指针,它指向一个包含cols
个整数的数组。更具体地说,arr
是一个行指针,它指向二维数组的第一行。
在这个函数中,arr
表示的是二维数组第一行的首元素的地址。在C语言中,数组名本身就是一个指向数组首元素的指针,而对于二维数组,数组名指向的是第一行的首地址。因此,arr
指向的是arr[0][0]
的地址。
在函数内部,通过arr
加上偏移量可以访问二维数组的其他元素。例如,*(arr + i)
表示第i
行的首地址,*(*(arr + i) + j)
表示第i
行第j
列的元素的值。这里的指针算术是基于数组的行优先存储顺序。
在C语言中,当您想要传递一个二维数组作为函数参数时,您需要指定数组的列数,因为它决定了指针的步长(即指针每增加1时,实际跳过的内存字节数)。这是因为数组在内存中是连续存储的,而且C语言中的数组访问需要知道数组元素的类型和大小,以便正确地进行指针运算。
参数写成int (*arr)[cols]
的形式是因为:
*arr
表示arr
是一个指针。(*arr)[cols]
表示arr
指向的是一个有cols
个元素的数组。
这种写法定义了一个指向有cols
个整数的数组的指针。这样,在函数内部,当您对arr
进行指针运算时,编译器知道每次移动arr
时需要跳过cols
个整数的大小。
必须带着[cols]
的原因是:
- 对于二维数组,每一行的元素数量(列数)是固定的,因此在函数原型中需要指定列数,以便编译器能够正确地计算数组元素的地址。
- 如果省略了
[cols]
,那么arr
就只是一个指向int
的指针,而不是指向一个数组的指针。这意味着在函数内部,您将无法通过arr
来正确地访问二维数组的其他行,因为编译器不知道每一行有多少个元素。
例如,如果您有一个int arr[3][4]
的二维数组,您可以将其传递给process_array
函数,因为函数的参数类型与数组的第二维大小相匹配。如果您尝试传递一个int arr[3][5]
的数组给同一个函数,编译器将会报错,因为数组的第二维大小与函数参数不匹配。
总结来说,[cols]
是必须的,因为它确保了函数能够接受正确大小的二维数组,并且在函数内部能够正确地进行指针运算。