C语言数组指针解析:为何示例代码中(*p)[i]可打印数组?
1. 先搞懂int(*p)[10]是什么
int(*p)[10]定义的是一个数组指针——它是一个指针,专门用来指向包含10个int类型元素的数组。
这里的优先级很关键:括号()的优先级高于[],所以(*p)先确定了p是指针,后面的[10]则说明这个指针指向的对象是长度为10的int数组。别和int *p[10]搞混,后者是指针数组(10个int指针组成的数组),完全是两回事。
2. 数组指针的赋值逻辑
在你的main函数里:
int(*p)[10] = arr;
数组名arr的本质是int[10]类型(长度为10的int数组),在赋值给数组指针时,它会隐式转换为指向整个数组的指针(也就是int(*)[10]类型),所以p现在指向的是arr数组的起始地址,对应的是整个数组的内存块。
3. 拆解(*p)[i]的作用
要理解这个写法,分两步看:
*p:对数组指针p做解引用操作,得到的就是它指向的整个数组(等价于main里的arr)。(*p)[i]:对解引用得到的数组使用下标访问,和arr[i]完全等价,就是取数组的第i个元素。
为什么不能直接写p[i]?因为p是指向“长度为10的int数组”的指针,p[i]会表示从p的地址偏移i * 10 * sizeof(int)字节(也就是跳过i个完整的10元素数组),这显然不是我们要访问当前数组的元素,所以必须先解引用p得到数组本身,再用下标访问。
4. 为什么print_array能打印数组
print_array函数的参数int(*p)[10]接收了main里的数组指针p,这个指针指向的就是初始化好的arr数组。在循环中:
printf("%d ", (*p)[i]);
每次循环通过(*p)[i]取出数组的第i个元素,自然就能打印出arr里的0到9这些值。
另外,(*p)[i]也可以写成*(*p + i)——因为*p作为数组名,会隐式转换为指向数组第一个元素的指针(int*类型),*p + i就是指向第i个元素的指针,解引用后同样能得到对应元素的值,和下标写法是等价的。
内容的提问来源于stack exchange,提问作者Turing-Sheep

