第一部分
刚刚看到西芬探测资深软件工程师@快乐的老码农 分享了一个微头条:
![c8888a28e7a8d172111c22c9a8fca592.png](https://i-blog.csdnimg.cn/blog_migrate/eec544e1d8d32f31a9e9e879a699f3f1.jpeg)
相信这位作者是肯定清楚个中原因的,只是抛出来让大家讨论。评论区里有许多朋友显然是不了解的:
![063d7199b1fa9257e292fd048baec862.png](https://i-blog.csdnimg.cn/blog_migrate/ca9de0776a31698a79d08abd69d575fa.jpeg)
![3705f1f13cc0e9c531381b1512756e21.png](https://i-blog.csdnimg.cn/blog_migrate/28490957554d7e82ea3cac25e4f11bea.jpeg)
还有很多,就不一一截图了。
毛主席说“没有调查就没有发言权”,我们还能看到有信口开河的朋友:
![d62df0cea115dac89755d0f2e8342095.png](https://i-blog.csdnimg.cn/blog_migrate/922233676c37a2d70b5daec7eff1fa9e.jpeg)
终于有一位朋友给出了正确答案。不过这个和汇编没关系。
![40db382b978df8f8bb5ba7898f5bcd26.png](https://i-blog.csdnimg.cn/blog_migrate/ff51ad05a17be4698fc5ea1e34f776c4.jpeg)
下面我们来说一说这到底是怎么回事。
第二部分
我们直接看Stack Overflow上面这个2008年提出的问题:
![febb1c23b3d7e879ec79656fe6bd542f.png](https://i-blog.csdnimg.cn/blog_migrate/93435755aa8391f7df23da9d976082ef.jpeg)
然后看看大神的解答:
![ac12587bc6b64ed71271b22ae02565e8.png](https://i-blog.csdnimg.cn/blog_migrate/ceb5b9835d67ebecf1c608752c74f5f4.jpeg)
![7c06d9aeb853498cbd8e685b782242cb.png](https://i-blog.csdnimg.cn/blog_migrate/bf47b92c115af12c26436c281e73f06f.jpeg)
这下大家该明白了吧?
对的,C/C++中对数组取值a[i]的实现,是*(a+i)。你写i[a],得到是*(i+a),结果是一模一样的。
第三部分
![313875d7c270d0e7b3450fe954b5894f.png](https://i-blog.csdnimg.cn/blog_migrate/8dc2823f2a60d26b80d58b85ac06dac6.jpeg)
关于原因,就像这位网友说的一样,在C语言诞生的年代,计算资源并不像我们现在这样丰富,64KB的内存就已经算是很大了。在这种情况下,C语言编译器不会去做很多的语法检查,而是简单的把x[y]给翻译成*(x+y).
第四部分
再简单说一下评论区里关于汇编语言是不是这样写的争论:
![091f4693b05a80ecbbc4f9a153697cb1.png](https://i-blog.csdnimg.cn/blog_migrate/789225fdbdcbec625ca910339ac0af32.jpeg)
没错,通常在汇编中,你需要自己指定“真正”的地址偏移量。不过汇编语言有非常非常多种,所以我也不知道会不会有一种汇编语言不用这样做,不过我估计是没有的。
第五部分
![e6c5a5d4de3aea53e82a7875175a1d7b.png](https://i-blog.csdnimg.cn/blog_migrate/44cfc00befd087cdb36807eb60aa7f49.jpeg)
这部分是给对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.