You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何数组指针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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:24:22