MST
星途 面试题库

面试题:C语言二维数组作为函数参数的指针运算

编写一个C语言函数 `void sumRows(int arr[][3], int rows)`,该函数计算二维数组每一行元素的和,并打印出来。解释函数参数 `arr` 的类型本质是什么,在函数内部如何通过指针运算访问数组元素,以及这种指针运算与多维数组在内存中的存储方式有什么关联。
39.8万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#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);
    }
}
  1. 函数参数arr的类型本质

    • arr参数声明为int arr[][3],其本质是一个指向含有3个int元素的数组的指针,即int (*)[3]。这是因为在C语言中,当数组作为函数参数传递时,会自动退化为指针。这里传递的二维数组的第一维大小可以省略,但第二维大小必须指定,因为编译器需要知道每个“行”有多少个元素,以便正确计算内存地址。
  2. 指针运算访问数组元素

    • 在函数内部,*(arr + i)指向第i行的起始地址,它等价于arr[i]
    • *(*(arr + i) + j)表示访问第i行第j列的元素。*(arr + i)先找到第i行的起始地址,然后*(arr + i) + j表示在第i行起始地址的基础上偏移jint类型的位置,最后*(*(arr + i) + j)取出该位置的值。这与arr[i][j]是等价的写法,arr[i][j]会被编译器解释为*(*(arr + i) + j)
  3. 与多维数组内存存储方式的关联

    • C语言中多维数组在内存中是按行优先顺序存储的。例如,对于int arr[rows][3],先存储第一行的3个元素,接着存储第二行的3个元素,以此类推。指针运算*(*(arr + i) + j)利用了这种存储方式,arr + i根据行优先存储的特点,通过偏移i个“行”的大小(这里一个“行”大小为3 * sizeof(int))找到第i行的起始地址,然后*(arr + i) + j再在该行内偏移jint大小找到具体元素,从而实现对多维数组元素的正确访问。