MST

星途 面试题库

面试题:C语言内存地址与数组的关系及指针运算

假设有一个二维数组`int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };`,请说明数组名`arr`、`arr[0]`、`&arr[0][0]`这三者在内存地址上的联系与区别。并且使用指针运算,求出`arr[1][2]`的值,解释指针运算的原理。
42.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 内存地址联系与区别

    • arr
      • arr是二维数组名,它代表整个二维数组的首地址,其类型为int (*)[4],即指向包含4个int类型元素的数组的指针。在这个例子中,arr指向二维数组的第一行(也就是包含4个int元素的数组),其地址值与&arr[0]相同(从数值上看)。
    • arr[0]
      • arr[0]从本质上等价于*(arr + 0),它是数组arr第一行的首地址,其类型为int *,指向数组arr第一行的第一个元素arr[0][0]。所以它的地址值与&arr[0][0]相同。
    • &arr[0][0]
      • 这是数组arr首元素arr[0][0]的地址,类型为int *,它指向数组arr的第一个元素1

    总结:arr(数值上) == &arr[0]arr[0] == &arr[0][0],但它们的数据类型不同。arr是指向包含4个int元素数组的指针,arr[0]&arr[0][0]是指向int类型的指针。

  2. 使用指针运算求arr[1][2]的值及原理

    • 二维数组在内存中是按行存储的。
    • 首先,arr是二维数组名,arr[1]等价于*(arr + 1),这里arr + 1表示跳过第一行(因为arr指向的是包含4个int元素的数组,所以arr + 1会移动4 * sizeof(int)个字节),*(arr + 1)就指向了第二行的首地址。
    • 然后,arr[1][2]等价于*(*(arr + 1)+2)*(arr + 1)指向第二行首地址,*(arr + 1)+2表示在第二行首地址的基础上偏移2个int类型的位置(因为是int类型数组,每个元素占sizeof(int)字节),*(*(arr + 1)+2)就是取偏移后的地址处的值。
    • 代码示例(C语言):
#include <stdio.h>
int main() {
    int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
    int value = *(*(arr + 1)+2);
    printf("arr[1][2]的值为: %d\n", value);
    return 0;
}
  • 在上述代码中,*(*(arr + 1)+2)求出了arr[1][2]的值,通过指针运算准确地访问到了二维数组中指定位置的元素。所以arr[1][2]的值为7