数组指针int temp[5] { 2, 3, 4, 5, 6 }; int (*p)[5] temp; int i; for (i 0; i 5; i) { printf(%d\n, *(*p i)); //等同 printf(%d\n, (*p)[i]); }输出p 是一个指向“包含5个int的数组”的指针temp的类型是int[5]数组类型temp的类型是int(*)[5]指向数组的指针p就是这种指针所以p指向整个数组 temp而不是第一个元素*p等价于temp数组本身解释*(*p i)*p→ 得到数组temp在表达式中退化为指向首元素的指针temp[0]*p i→ 指针向后移动 i 个元素指向temp[i]的地址所以*p i是指向数组中第 i 个元素的位置地址。*(*p i)→ 取出该地址的值等价于temp[i]数组元素指针int temp[5] { 2, 3, 4, 5, 6 }; int (*p) temp;//temp 与 temp[0] 同义 int i; for (i 0; i 5; i) { printf(%d\n, *(p i)); }输出指针变量加1即向后移动1 个位置表示指针变量指向下一个数据元素的首地址。p指向的是一个整型p1就是移动一个整型大小即移动4个字节所以p1代表的地址比p代表的地址大4。*(p i) 就是取出对应地址的数据元素的值。延申根据 ’指针1‘ 的运算原理可做以下改动int temp[5] { 2, 3, 4, 5, 6 }; int (*p)[5] temp; int i; for (i 0; i 5; i) { printf(%d\n, *(p i)); }输出p是数组指针指向长度为 5 的 int 数组p i跳过 i 个完整数组每次 1直接跳过5 个 int*(p i)解引用后得到的是第 i 个数组的首地址不是数组元素p指向的是拥有5个int元素的数组。拥有5个int元素的数组的数据大小为5*4 20 字节pi 就是 地址加上 i*20 综合扩展这里分析以下最后一个输出*(*(arr 1) - 1)int arr[3] {1, 2, 3}; // 步骤1: arr 1 // arr 是 int(*)[3] 类型加 1 跳过整个数组12 字节 // 假设 arr 起始地址为 0x1000则 arr1 0x100C // 步骤2: *(arr 1) // 解引用 int(*)[3] 得到 int[3] 类型 // 此时 *(arr1) 在概念上代表从 0x100C 开始的一个 int[3] 数组 // 但这个数组实际上并不存在越界了只是类型系统允许这样表达 // 步骤3: 数组名转换 // 当 *(arr1) 作为右值使用时它从 int[3] 转换为 int* // 转换后得到指向这个不存在的数组的首元素的指针 // 也就是指向地址 0x100C 的 int* 指针 // 步骤4: -1 // int* 指针减 1向前移动 sizeof(int) 4 字节 // 得到地址 0x100C - 4 0x1008 // 0x1008 正好是 arr[2] 的地址 // 步骤5: * 解引用 // 获取 arr[2] 的地址 对应的元素数值