为何数组指针q与*q的printf地址输出相同?需用**q访问元素?
理解
int *与int (*)[]的差异 测试代码
#include <stdio.h> int main() { int a[3] = {1,2,3}; int *p = a; printf("address of a: %p\n", &a); printf("\naddress of a[0]: %p\n", &a[0]); printf("\nvalue of p: %p\n", p); printf("\nvalue of *p: %d\n", *p); printf("\nvalue of a[1]: %d\n", *(p + 1)); puts("\n\n-------------------\n\n"); int b[3] = {1,2,3}; int (*q)[3] = &b; printf("address of b: %p\n", &b); printf("\naddress of b[0]: %p\n", &b[0]); printf("\nvalue of q: %p\n", q); printf("\nvalue of *q: %p\n", *q); }
核心差异解析
1. int *p = a;的本质
数组名a在绝大多数场景下会隐式转换为指向数组首元素的指针,也就是int*类型。所以:
p存储的是a[0]的地址,和&a[0]的数值完全一致- 对
p解引用*p,直接访问a[0]的内存空间,因此能拿到数值1 p+1会按照int的字节大小(通常4字节)偏移,指向a[1],所以*(p+1)就是a[1]的值2
2. int (*q)[3] = &b;的本质
int (*q)[3]是指向长度为3的int数组的指针类型,和普通int*是完全不同的类型:
&b取的是整个数组的地址,这个地址的数值和&b[0](首元素地址)完全相同,但类型是int(*)[3],而非int*q存储的是整个数组的地址,对q解引用*q,得到的是数组b本身。而数组名又会隐式转换为指向首元素的指针,所以*q的数值等于&b[0],但类型变成了int*- 要访问
b[0],需要对*q(首元素指针)再解引用一次,也就是**q,才能拿到b[0]的数值1
3. 地址数值相同但类型不同的关键
虽然&b、&b[0]、q、*q的地址输出数值一致,但它们的类型决定了解引用行为:
int*类型指针,解引用直接访问int大小的内存int(*)[3]类型指针,解引用得到整个数组,需再隐式转为int*后才能访问单个元素
内容的提问来源于stack exchange,提问作者Talete
相关产品推荐
相关产品推荐

