在C语言中,为何解引用数组指针后与原指针地址值相同?
问题描述
以下代码中声明了一个int类型数组a,以及一个指向整个数组的指针ap:
int main(){ int a[3] = {10, 100, 1000}; int (*ap)[] = &a; printf("%p\n", ap); printf("%p\n", *ap); printf("%d\n", **ap); return 0; }
运行后输出结果为:
0x7fff193310cc 0x7fff193310cc 10
首次打印ap显示它指向数组的起始位置,这没问题。但第二次打印解引用后的ap时,地址值与原指针相同;只有经过两次解引用后,才能得到数组第一个元素的值10。请问出现这种现象的原因是什么?
原因解析
- 指针类型是核心差异:
ap是指向整个数组的指针(类型为int (*)[]),而数组名a在多数表达式里会自动转成指向首元素的指针(int *)。虽然两者指向的内存起始地址完全一样,但语义天差地别:ap的指向对象是整个长度为3的int数组,它的步长是整个数组的大小(也就是3*sizeof(int))。- 解引用
ap得到的是数组本身,而当你用%p打印它时,数组会被隐式转换成指向首元素的指针,所以打印出的地址和ap的地址完全相同。
- 两次解引用的逻辑链:
- 第一次解引用
*ap:拿到数组对象,随即自动转为指向首元素的int*指针。 - 第二次解引用
**ap:对这个首元素指针再解引用,自然就拿到了数组第一个元素的值10。
- 第一次解引用
- 地址相同的底层逻辑:数组的起始地址和它第一个元素的起始地址本来就是同一个位置,所以不管是指向整个数组的指针,还是指向首元素的指针,打印出来的地址值肯定一样,但类型不同直接决定了后续操作的行为差异。
内容的提问来源于stack exchange,提问作者john987
相关产品推荐
相关产品推荐

