数组名的地址

理解 int *ptr = (int *)(&a + 1); 需要掌握几个关键概念,我来一步步解释:

1. &a 的含义

  • a 是数组名,类型是 int[5](包含5个整数的数组)
  • &a 的类型是 int (*)[5](指向"包含5个整数的数组"的指针)
  • 虽然 &aa 的内存地址值相同(都指向数组开头),但指针类型不同,这决定了指针运算的行为不同

2. 指针运算 &a + 1

  • 指针运算的步长取决于指针指向的类型大小
  • &a 的类型是 int (*)[5],指向的是整个数组(大小为 5 * sizeof(int) = 20字节)
  • &a + 1
    在内存上跳过整个数组的大小(20字节)
    指向数组末尾的下一个内存位置(即 a[4] 之后的位置)
内存示意图:
[ a[0] ][ a[1] ][ a[2] ][ a[3] ][ a[4] ] [ 下一个位置 ]
 0x1000 0x1004 0x1008 0x100C 0x1010     0x1014
   ↑             ↑             ↑          ↑
   &a           a+1          &a+4       &a+1

3. 类型转换 (int *)

  • &a + 1 的类型仍是 int (*)[5](数组指针)
  • (int *) 强制转换
    将其转换为普通整型指针 int*
  • 现在 ptr 是一个指向整数的指针,但指向的是数组外的内存地址

4. 最终结果

int *ptr = (int *)(&a + 1);
  • ptr 指向数组结束后的第一个内存位置
  • 但类型是 int*(而非数组指针),后续可按整型指针进行运算

结合代码验证:

printf("%d %d\n", *(a+1), *(ptr-1));
  • *(a+1)

    • a 是数组首元素地址(类型 int*
    • a+1 前进 sizeof(int) = 4字节 → 指向 a[1]
    • 值 = 2
  • *(ptr-1)

    • ptr 类型是 int*,指向数组结束后的位置
    • ptr-1 后退 sizeof(int) = 4字节 → 指向 a[4]
    • 值 = 5

输出:2 5


关键区别总结:

表达式 类型 增加1的步长 指向位置
a int* 4字节 首元素地址
&a int(*)[5] 20字节(整个数组) 数组地址(值同a
&a+1 int(*)[5] 20字节 数组结束后的位置
(int*)(&a+1) int* 4字节 同上(但类型改变)

这个操作展示了C语言指针运算的类型敏感性:相同的地址值,不同的指针类型,会导致完全不同的算术运算结果。

posted @ 2025-07-02 21:09  f-52Hertz  阅读(30)  评论(0)    收藏  举报