C/C++数组取值的真实实现——一个初学者的常见疑惑
头条审核了两个小时都没审核完,先发到这里了。
第一部分
刚刚看到西芬探测资深软件工程师@快乐的老码农 分享了一个微头条:
相信这位作者是肯定清楚个中原因的,只是抛出来让大家讨论。评论区里有许多朋友显然是不了解的:
还有很多,就不一一截图了。
毛主席说“没有调查就没有发言权”,我们还能看到有信口开河的朋友:
终于有一位朋友给出了正确答案,但是可惜的是,这个和汇编没关系。
下面我们来说一说这到底是怎么回事。
第二部分
我们直接看Stack Overflow上面这个2008年提出的问题:
然后看看大神的解答:
这下大家该明白了吧?
对的,C/C++中对数组取值a[i]的实现,是*(a+i)。你写i[a],得到是*(i+a),结果是一模一样的。
第三部分
关于原因,就像这位网友说的一样,在C语言诞生的年代,计算资源并不像我们现在这样丰富,64KB的内存就已经算是很大了。在这种情况下,C语言编译器不会去做很多的语法检查,而是简单的把x[y]给翻译成*(x+y).
第四部分
再简单说一下评论区里关于汇编语言是不是这样写的争论:
没错,通常在汇编中,你需要自己指定“真正”的地址偏移量。不过汇编语言有非常非常多种,所以我也不知道会不会有一种汇编语言不用这样做,不过我估计是没有的。
第五部分
这部分是给对C语言指针不熟悉的朋友准备的。看如下代码:
int a[5];
我们取a[2],编译器翻译成*(a+2)。有人会说,这怎么能行呢?
这就是在第四部分说的C语言区别于汇编的特性。a是一个数组,在这里被看成一个int类型的指针,对它进行+操作,实际上a的偏移量不是2,而是2*sizeof(int),在一般的32位机器上是2*4=8。
这就是说,如果一个int的指针p指向0x1230,那做p+2,得到的不是0x1232而是0x1238.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义