假设arr是一个int型数组,为什么int (*p)[4]=arr报错initialization of ‘int (*)[4]‘ from incompatible pointer type ‘i‘
数组名在大多数情况下会退化为指向其首元素的指针。一维数组会退化指向数组第一个元素的地址,二维数组会退化指向第一行的指针。
目录
一、一维数组
1.数组名的类型
假设arr声明为:
int arr[N]; //N是数组长度,例如N=4
- 数组名 arr 在大多数情况下会退化为指针,指向数组第一个元素的地址,即 arr 的类型是 int*
- 例外情况:当 arr 与 & 或 sizeof 运算符结合时,数组名保留完整的数组类型信息。例如:
①&arr 的类型是 int (*)[N](指向长度为N的数组的指针)。
②sizeof(arr)返回整个数组的字节大小( N*sizeof(int) )。
2.int (*p)[4] 的类型
int (*)[4] 是一个指向长度为4的整型数组的指针,即:
- p的类型是 int (*p)[4]。
- p指向的是一个数组整体,而不是数组中的某个元素。
- 对 p 解引用(*p)会得到一个长度为4的整型数组(类型为int [4])。
3.错误原因分析
假设 arr 是一个普通的 int 型数组(例如 int arr[4];):
int (*p)[4]=arr; //错误!!!
- 类型不匹配:
①arr 退化为 int*(指向单个 int 元素的指针)。
②p的类型是 int (*)[4](指向长度为4的整型数组的指针)。
③int* 与 int (*)[4]是两种完全不同的指针类型,直接赋值会导致编译器报错。
- 报错信息如下:
warning: initialization of 'int (*)[4]' from incompatible pointer type 'int *' [-Wincompatible-pointer-types]
9 | int (*p)[4]=arr;
4.正确写法如下
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
// 定义一个包含4个整数的数组,并初始化
int arr[4]={1,2,3,4};
// 定义一个指向包含4个整数的数组的指针,并将数组arr的地址赋给它
int (*p)[4]=&arr;
// 使用for循环遍历数组并打印每个元素
for (int i = 0; i < 4; i++)
{
printf("%d",(*p)[i]);
}
// 返回0表示程序成功结束
return 0;
}
二、二维数组
1.二维数组实质
在C语言中,二维数组退化为指针的行为是由其底层设计决定的,目的是简化多维数组的操作并保持语法一致性。
- 二维数组 int arr[m][n] 本质上是一维数组的数组:
①它包含m个元素,每个元素本身是一个长度n的一维数组。
②内存中按 行优先 连续存储,所有元素紧密排列。
2.数组名的退化规则
在大多数表达式中,数组名会退化为指向其第一个元素的指针:
- 一维数组:int arr[5] -> arr 退化为 int*(指向 arr[0] )。
- 二维数组:int arr[3][4] -> arr 退化为 int (*)[4](指向 arr[0],即第一个长度为4的子数组)。
3.退化目的:简化多维访问
- 二维数组的每个元素是一个子数组(如 arr[0] 是 int[4])。
- 通过退化为指向子数组的指针,可以直接用指针算数访问行:(数组下标从0开始)
arr+i 指向第 i 行(即arr[i]),解引用*(arr+i)得到第 i 行的首地址。
- 这使得 arr[i][j] 的语法等价于 *(*(arr+i)+j),保持直观的多维访问。
4.示例代码:
#include <stdio.h>
int main() {
// 定义一个3行4列的二维数组
int array[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 指针ptr 指向包含4个整数的数组的,
//array 指向二维数组的第一个一维数组
int (*ptr)[4] = array;
// 遍历二维数组的每一行
for (int i = 0; i < 3; i++) {
// 遍历当前行的每一个元素
for (int j = 0; j < 4; j++) {
// ptr[i] 表示指向 array 中第 i+1 个一维数组的指针(因为数组索引从0开始),
//而 *(ptr[i] + j) 则是通过这个指针访问该一维数组中的第 j+1 个元素。
printf("array[%d][%d] = %d\n", i, j, *(ptr[i] + j));
}
}
return 0;
}

浙公网安备 33010602011771号