news 2026/6/7 1:07:25

C语言入门:指针与数组的关系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言入门:指针与数组的关系

数组名不是指针,可它偏偏总被当指针用,那它到底算个啥呢。

我学C语言快两个月了,光是“a

到底怎么算出来的”这个问题,就反复查了三回标准文档,问了两个同学,还扒了GCC的汇编输出。不是我不想弄懂,是网上太多说法自相矛盾——有的说“数组就是指针”,有的又说“根本不是”,连老师PPT上写的和教材小字批注都对不上。

后来我干脆拿纸笔画内存:`int a

= {1,2,3,4,5};`。我标出每个元素地址,手动算`a+2`是多少,再对照`&a

`,发现真的一样。但`&a`写在纸上时,我愣住了:地址数字和`&a

`并排写着,可我给它标类型时,硬生生多画了个括号,写成`int (*)

`——这玩意儿编译器认识,我一开始真不认识。

我试了`sizeof(a)`和`sizeof(&a)`,结果一个是20,一个是8。就这俩数字,让我盯了十分钟。20是5个int占的总空间,8是地址本身大小。原来“值一样”和“东西一样”真不是一回事。`a`不是变量,它没内存地址可存;`&a`也不是取“a这个符号”的地址,是取整个数组块的起始位置。

我写了个最简单的程序:

```c

int a

= {10,20,30};

printf("%p %p\n", (void*)a, (void*)&a);

```

运行结果两行地址一模一样。我差点又信了“它俩就是一回事”。直到我把`a+1`和`&a+1`打出来——前者是`a

`地址+4,后者直接跳了12字节(3×4)。这才明白,指针加1走多远,全看它指的“东西”有多大。`&a`指的不是int,是一整个`int

`,所以加1就跨过整个数组。

下标`a

`这事,课本说等于`*(a+i)`。我原来以为这只是写法不同,直到看godbolt.org里生成的汇编,`a

`和`*(a+i)`编译出来真的一条指令都不差。它不是“看起来像”,是编译器规定它就必须是。但`a++`为啥错?因为`a`根本不是能放地址的盒子,它连盒子都不是,是贴在内存块上的一张标签。你不能让标签自己动,但你能拿个新盒子(比如`int *p = a;`),把标签上的地址抄进去,再让盒子动。

函数传数组最骗人。我写`void f(int arr

10

)`,还傻乎乎在函数里`sizeof(arr)`,结果永远是8。我删掉10写成`int arr

`,还是一样。问了助教才懂:C标准白纸黑字写了,形参里的数组声明,编译器当场就替换成指针。它不存长度,不存边界,只存首地址。你传进去的是`a`,函数里拿到的是`a`转换后的`int *`,仅此而已。

陷阱真容易踩。有次我把`&a`直接赋给`int *p`,GCC警告我“类型不匹配”,我没理,结果程序跑一半崩了。后来加`-Wall`重编,警告清清楚楚写“initialization from incompatible pointer type”。还有一次越界访问`a

`,程序居然没报错,还打印出一个鬼数字,我真以为它“能用”。直到换台机器跑,直接段错误。UB不是吓唬人,是它真不管你会不会出事。

我拿`int (*p)

10

= &a;`和`int *q = a;`对比着写了几遍。前者`p+1`跳40字节,后者`q+1`跳4字节;`*p`是整个数组,`*q`只是一个int。要访问`a

`,用`q`是`q

`,用`p`得写成`(*p)

`——多一对括号,少一对就错。这不是绕口令,是类型系统在拉警报。

结构体里的数组让我又卡了一次。`struct { int x

; } s;`,我打`&s.x`和`&s.x

`,值一样,但类型一个是`int (*)

`,一个是`int *`。我试了`printf("%d", sizeof(&s.x));`,输出8;`sizeof(&s.x

)`也是8。但把它们传给函数,参数类型写错,编译器立马翻脸。

现在写代码前,我先想三件事:这个东西类型是啥?`sizeof`它多大?`&`它得到什么?想清楚了,`a

`、`p

`、`*(p+i)`在我脑子里就真成了一回事——不是“差不多”,是底层指令一模一样,只是写法不同。

我删掉了所有笔记里“数组就是指针”这几个字。改成:“数组名,在大部分地方,会自动变成指向第一个元素的指针,但它自己从来不是。”

今天用`-O2`编译三个遍历写法,看了汇编,三条`mov`指令排得整整齐齐,没差一个字节。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 1:07:07

Linux 多磁盘分区挂载实战 踩坑复盘

一、实验前期:VMware 创建三块实验磁盘具体如上图所示实验环境:RHEL9 虚拟机,虚拟机关机状态下在 VMware 编辑硬件,分三次添加不同接口规格硬盘,对应 SCSI 5G、SATA 10G、NVME 15G 三块磁盘。打开【编辑虚拟机设置】→…

作者头像 李华
网站建设 2026/6/7 1:03:58

终极指南:5分钟快速上手Thorium浏览器,体验Chromium性能巅峰

终极指南:5分钟快速上手Thorium浏览器,体验Chromium性能巅峰 【免费下载链接】thorium Chromium fork named after radioactive element No. 90. Source code and Linux releases. Windows/MacOS/ARM builds served in different repos, links are towar…

作者头像 李华
网站建设 2026/6/7 1:03:56

AKShare数据接口深度体验:除了stock_zh_a_hist,还有哪些宝藏函数值得股票分析玩家关注?

AKShare数据宝藏挖掘指南:超越行情数据的股票分析新维度当大多数股票分析玩家还在用AKShare获取基础行情数据时,你已经可以解锁这个工具库真正的威力了。就像拥有了一张藏宝图却只使用了上面的比例尺,AKShare中那些被忽视的财务指标、资金动向…

作者头像 李华
网站建设 2026/6/7 1:03:48

040、双OIS与悬浮防抖:旗舰机防抖方案的硬件堆叠与协同控制

040、双OIS与悬浮防抖:旗舰机防抖方案的硬件堆叠与协同控制 去年Q3,我接手一个项目,客户反馈夜景模式下取景画面像“果冻”,快门按下去成片糊成一片。我们当时用的是单OIS+EIS方案,按理说OIS补偿角度够用,EIS裁切也留了余量。但实测发现,在步行跟拍场景下,低频抖动被OI…

作者头像 李华