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

*p与p[1]的区别是什么?malloc动态内存分配相关疑问

关于C语言指针与数组下标等价性的问题

先修正你代码里的小错误(p[1]=20缺少分号),完整代码如下:

void main()
{
    int *p, n=5;
    p=(int*)malloc(5*sizeof(int));

    p[0]=10;
    //  or *p=10;
    p[1]=20;
    //  or *(p+1)=20;
}

下面针对你的问题逐一解答:

为什么p[1]和*(p+1)等价?

这是C语言的核心语法规则——数组下标运算符[]本质就是指针偏移后解引用的语法糖。C标准明确规定:对于任意表达式E1和E2,E1[E2]完全等价于*(E1 + E2)。这里的E1既可以是数组名,也可以是指针变量。当p是指向连续内存起始地址的指针时,p[1]就等于先把p向后偏移1个int的长度(指针类型会自动计算偏移步长,int*的步长是sizeof(int)),再通过*解引用访问该地址的内容,也就是*(p+1)。

既然能用p[1],*运算符还有什么用?

*是解引用运算符,它是访问指针指向内存的基础操作,[]只是基于它的简化写法,它的不可替代性体现在:

  • 简洁访问指针当前指向的元素:*p等价于p[0],但写法更直接,尤其是在处理单个指针指向的变量时。
  • 适配非数组场景:如果指针只是指向单个独立变量(比如int a=5; int* p=&a;),用*p访问变量内容是符合语义的写法,虽然p[0]语法上能运行,但完全不符合代码可读性要求。
  • 支持灵活的指针操作:像*(p++)这种先解引用再移动指针的操作,用下标语法根本无法直接实现,必须依赖*运算符才能完成。

malloc分配的数组和指针p是同名的吗?

完全不是。malloc只是在堆上申请了一块连续内存,返回的是这块内存的起始地址,p仅仅是一个指向该地址的指针变量:

  • 数组名不是变量,不能被赋值(比如int arr[5]; arr = p;是非法的),但p作为指针变量,可以随时被重新赋值,指向其他内存地址。
  • 这块malloc分配的内存本身没有名字,你只能通过p(或其他指向它的指针)来访问。之所以能用数组下标操作p,只是因为它指向了连续内存,但本质上p还是指针,不是数组。

内容的提问来源于stack exchange,提问作者Jiden Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:01:16