C语言数组指针与普通指针解引用差异疑惑:为何返回数组地址?
问题解答
这是C标准明确规定的行为,并非历史遗留原因,核心差异源于数组类型的隐式转换规则,以及不同指针类型的解引用逻辑:
数组指针
p的解引用逻辑:int (*p)[10]是指向包含10个int元素的数组的指针,p = &a后,p存储的是数组a的整体地址(注:数组的整体地址和首元素地址在数值上完全相同,但二者类型不同——前者是int (*)[10],后者是int*)。
解引用p得到*p时,结果是数组a本身,类型为int[10]。根据C标准,数组类型出现在表达式中时(除非作为sizeof、&、_Alignof的操作数,或是用于初始化数组的字符串字面量),会自动隐式转换为指向数组首元素的指针,也就是int*类型,指向a[0]。所以*p最终等价于&a[0],数值上和p存储的数组地址一致,因此printf输出的地址相同。普通指针
d的解引用逻辑:d是int*类型,d = a时,数组a同样触发隐式转换,变成指向首元素a[0]的int*,所以d存储的是a[0]的地址。解引用d(*d)就是直接取a[0]的数值,也就是0。(另外注意你代码里用%p输出*d是错误的,%p用于输出指针地址,*d是整数值,应该用%d)
简言之:*p先得到数组,再转成首元素指针;d本身就是首元素指针,解引用直接取元素值。两者的差异完全是C标准对类型转换和指针解引用的规则定义导致的。
内容的提问来源于stack exchange,提问作者KRF
相关产品推荐
相关产品推荐

