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

关于C语言中静态与动态数组指针算术访问机制的疑问

关于C语言中静态与动态数组指针算术访问机制的疑问

嘿,这个问题问到点子上了,很多刚啃C语言指针的朋友都会在这儿绕晕,我给你掰开揉碎讲清楚:

首先得把**静态数组名a和指针变量b**的本质差异搞透,这是解开疑惑的核心:

  • 静态数组的名字a,它不是一个变量,而是编译阶段就确定好的地址常量。说白了,编译器在编译代码时,直接把a替换成了数组首元素的内存地址,这个值是固定死的——你甚至没法写a = a + 1,这在C里是非法的,因为常量不能被修改。
  • 而b是个实打实的指针变量,它自己占了一块内存(比如64位系统里是8字节),里面存的是malloc分配的动态数组的首地址。它是可以被修改的,比如你写b = b + 1完全合法,之后b就指向数组的第二个元素了。

现在拆解你疑惑的两个表达式:

先看*(a + 9)

  • 编译器看到a,直接用它对应的编译期常量地址(数组首元素地址),根本不需要去内存里读任何值。
  • 接着做指针算术:a + 9会自动转换成a + 9 * sizeof(int)(比如int占4字节,就是加36),得到数组第10个元素的地址。
  • 最后用*解引用这个地址,取出里面的9。

再看*(b + 9)

  • 编译器看到b,首先会去读取这个指针变量内部存储的内容——也就是malloc给你的动态数组的首地址,这一步是程序运行时才做的,因为malloc的地址是程序跑起来后分配的。
  • 然后用这个读出来的地址做指针算术,同样加上9 * sizeof(int),得到目标元素的地址。
  • 最后*解引用这个地址,取出对应的值。

你说的“b被读取为变量b里存储的地址”,这个理解完全正确!而a根本不需要读内存,它本身就是编译器硬编码进程序里的地址常量。

再补个直观对比:

  • 你可以写&a,得到的是整个数组的地址(类型是int (*)[10]),它的值和a是一样的,只是类型不同;但&b得到的是指针变量b自己的地址(类型是int**),和b里面存的动态数组地址完全不是一回事。

C语言这么设计,其实是为了语法一致性——让你能用同样的指针算术语法访问静态和动态数组,不用记两套规则,但本质上数组名和指针变量是完全不同的东西哦。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 13:23:09