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

C语言中指向数组的指针输出异常的原因探究

问题分析:数组指针的寻址与运算符优先级问题

先看你给出的代码:

#include<stdio.h>
int main() {
int (*p)[3];
int a[3]={10,11,12};
p=&a;
printf("%d\n", *p[0]);
printf("%d\n", *p[1]);
printf("%d\n", *p[2]);
return 0;
}

你发现第一个printf输出10符合预期,但后面两个输出不对,核心原因是运算符优先级和数组指针的寻址逻辑没弄明白,咱们一步步拆解:

1. 先搞懂p的类型

int (*p)[3]; 定义的是一个指向包含3个int元素的数组的指针,不是普通的int指针。也就是说,p的“步长”是一个int[3]数组的大小(通常是12字节,假设int占4字节),每次p+1都会跳过一整个3元素int数组的空间。

当你执行p=&a;时,p指向了数组a的起始地址(因为&a的类型就是int(*)[3],和p的类型完全匹配),这一步是没问题的。

2. 关键:*p[0]和*p[1]的运算逻辑

C语言里,[]运算符的优先级比*高,所以表达式会先执行[]运算:

  • 对于*p[0]:先算p[0],等价于*(p + 0),也就是p指向的那个数组(也就是a),然后*p[0]就等价于*a,也就是数组a的第一个元素a[0],所以输出10,符合预期。
  • 对于*p[1]:先算p[1],等价于*(p + 1)。因为p是指向int[3]的指针,p+1会跳过整个3元素int数组,指向a数组后面的未知内存区域。*p[1]就是取这个未知区域的第一个int值,自然不是a[1]的11了。同理*p[2]是跳过两个3元素数组的位置,取更后面的随机值。

3. 怎么修正才能输出预期的11和12?

如果要访问数组a的第2、3个元素,需要先把p解引用得到数组a(或者说数组的首地址),再用[]访问元素,也就是用(*p)[1]和(*p)[2]:

  • (*p)[1]:先执行*p得到数组a(等价于a),然后(*p)[1]就是a[1],输出11。
  • (*p)[2]同理,对应a[2],输出12。

修正后的代码如下:

#include<stdio.h>
int main() {
int (*p)[3];
int a[3]={10,11,12};
p=&a;
printf("%d\n", *p[0]); // 等价于(*p)[0],输出10
printf("%d\n", (*p)[1]); // 正确输出11
printf("%d\n", (*p)[2]); // 正确输出12
return 0;
}

内容的提问来源于stack exchange,提问作者Kawsar Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:22:32