MST

星途 面试题库

面试题:C语言多维数组底层存储与指针运算深度剖析

已知一个不规则的二维数组,通过指针数组实现,即`int *arr[3]`,其中`arr[0]`指向一个长度为2的`int`数组,`arr[1]`指向一个长度为3的`int`数组,`arr[2]`指向一个长度为4的`int`数组。请详细说明这种数据结构在内存中的存储布局,编写代码完成对该不规则二维数组所有元素的累加操作,并解释在指针运算过程中如何精准定位每个元素,以及与常规二维数组在存储和访问上的本质区别。
44.1万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

内存存储布局

  1. int *arr[3] 是一个指针数组,在内存中,arr 本身占据一块连续的内存空间,存放三个指针 arr[0]arr[1]arr[2]
  2. arr[0] 指向一个长度为 2 的 int 数组,这 2 个 int 类型的数据在内存中是连续存储的。
  3. arr[1] 指向一个长度为 3 的 int 数组,这 3 个 int 类型的数据在内存中是连续存储的,但与 arr[0] 指向的数组在内存位置上不一定连续。
  4. arr[2] 指向一个长度为 4 的 int 数组,这 4 个 int 类型的数据在内存中是连续存储的,但与 arr[0]arr[1] 指向的数组在内存位置上不一定连续。

代码实现累加操作

#include <stdio.h>

int main() {
    int arr1[2] = {1, 2};
    int arr2[3] = {3, 4, 5};
    int arr3[4] = {6, 7, 8, 9};
    int *arr[3] = {arr1, arr2, arr3};

    int sum = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < (i == 0? 2 : (i == 1? 3 : 4)); j++) {
            sum += arr[i][j];
        }
    }
    printf("Sum of all elements: %d\n", sum);
    return 0;
}

指针运算精准定位元素

  1. 对于 arr[i][j],首先通过 arr[i] 获取到第 i 个指针,该指针指向一个 int 数组。
  2. 然后通过 arr[i][j],相当于 *(arr[i] + j),在该指针指向的数组中偏移 jint 类型的大小,从而精准定位到具体元素。

与常规二维数组在存储和访问上的本质区别

存储区别

  1. 常规二维数组:在内存中是按行连续存储的,例如 int a[3][4],所有 12 个 int 元素在内存中是连续排列的。
  2. 指针数组实现的不规则二维数组:各个子数组在内存中不一定连续,指针数组 arr 存放的是各个子数组的起始地址。

访问区别

  1. 常规二维数组:访问元素 a[i][j] 时,计算偏移量的公式是固定的,即 i * 列数 + j,可以直接通过数组首地址加上偏移量定位到元素。
  2. 指针数组实现的不规则二维数组:访问元素 arr[i][j] 时,先通过 arr[i] 获取子数组的首地址,再在子数组内通过偏移 jint 大小来定位元素,由于每个子数组长度不同,不能像常规二维数组那样使用统一的偏移量计算公式。