面试题答案
一键面试#include <stdio.h>
void sumRows(int arr[][3], int rows) {
// arr本质是一个指向含有3个int元素的数组的指针,即 int (*)[3]
for (int i = 0; i < rows; i++) {
int sum = 0;
// 通过指针运算访问数组元素
for (int j = 0; j < 3; j++) {
sum += *(*(arr + i) + j);
}
printf("第 %d 行的和为: %d\n", i + 1, sum);
}
}
-
函数参数
arr
的类型本质:arr
参数声明为int arr[][3]
,其本质是一个指向含有3个int
元素的数组的指针,即int (*)[3]
。这是因为在C语言中,当数组作为函数参数传递时,会自动退化为指针。这里传递的二维数组的第一维大小可以省略,但第二维大小必须指定,因为编译器需要知道每个“行”有多少个元素,以便正确计算内存地址。
-
指针运算访问数组元素:
- 在函数内部,
*(arr + i)
指向第i
行的起始地址,它等价于arr[i]
。 *(*(arr + i) + j)
表示访问第i
行第j
列的元素。*(arr + i)
先找到第i
行的起始地址,然后*(arr + i) + j
表示在第i
行起始地址的基础上偏移j
个int
类型的位置,最后*(*(arr + i) + j)
取出该位置的值。这与arr[i][j]
是等价的写法,arr[i][j]
会被编译器解释为*(*(arr + i) + j)
。
- 在函数内部,
-
与多维数组内存存储方式的关联:
- C语言中多维数组在内存中是按行优先顺序存储的。例如,对于
int arr[rows][3]
,先存储第一行的3个元素,接着存储第二行的3个元素,以此类推。指针运算*(*(arr + i) + j)
利用了这种存储方式,arr + i
根据行优先存储的特点,通过偏移i
个“行”的大小(这里一个“行”大小为3 * sizeof(int)
)找到第i
行的起始地址,然后*(arr + i) + j
再在该行内偏移j
个int
大小找到具体元素,从而实现对多维数组元素的正确访问。
- C语言中多维数组在内存中是按行优先顺序存储的。例如,对于