300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 神奇的C语言:一段令人百思不得其解的代码

神奇的C语言:一段令人百思不得其解的代码

时间:2021-08-16 17:46:00

相关推荐

神奇的C语言:一段令人百思不得其解的代码

今天在翻阅头条时,无意看到这样一篇微头条,说是作者的同事在工作中遇到一个BUG,两人一起研究了大半天,非但没有解决问题,反而一起陷入了郁闷,甚至三观尽毁!

他没有说具体过程,在简化了问题后,是这样一个代码(我增加了一条打印地址的代码):

#include <stdio.h>int main (int argc,char*argv[]){ int a[5]={0,1,2,3,4}; int b=3; printf("%d,%d",a[b],b[a]}; printf("%d,%d\n",&a[b],&b[a]); return 0; }

这个程序看上去蛮简单的,我的第一反应是该程序应该会报错,因为按照实例内容,b[a]这种表述方式看上去是在实在离谱,然而当我手动测试了一遍后,也大吃一惊。

没有报错,甚至连一个warning也没有,程序正常运行:

于是我怀疑是不是因为编译器的原因,又在VS 上尝试了一遍,结果依旧正常。

不甘心的我觉得可能是系统内核有关,便再次从虚拟机上的ubantu上gcc编译,果不其然,还是可以运行的通。

我估计不少朋友此刻的内心都是和我一样:开什么玩笑!这语法正确?这程序居然没有报错?这程序居然能正常运行?

两者不仅结果一样,连物理地址也是相同的。

在凌乱一番后,我开始研究起了这个程序。终于在翻阅了《C陷阱与缺陷中》,找到了一段关于数组指针的描述。书中说在C语言中,数组和下标是可以互相转换的,即对任何两个表达式a和b,只要其中一个是指针表达式而另一个是整数时,则a[b]和*((a)+b))的结果一致。

看完之后我表示更不明白了,因为从我个人来讲,确实理解不了将b作为数组索引有什么意义,也是头一次听到这种说法。由于书中没有过多提及,我又跑到GNU C library寻找相关资料,果然找到一段官方的解释,原文如下:

A postfix expression followed by an expression in [ ] (brackets) specifies an element of an array. The expression within the brackets is referred to as a subscript. The first element of an array has the subscript zero.

By definition, the expression a[b] is equivalent to the expression *((a) + (b)), and, because addition is associative, it is also equivalent to b[a]. Between expressions a and b, one must be a pointer to a type T, and the other must have integral or enumeration type. The result of an array subscript is an lvalue.

由于我英语也一般,翻译了一下大概是这个意思,前一段是数组的相关定义,不需要解释。关键在于后一段,根据官方表示:根据数组定义,表达式a[b]等价于表达式*((a)+(b)),并且,由于加法是关联的,所以它也等价于b[a]。不过需要满足一个大前提:a式和b式,两者必须满足一个是指向类型T的指针,另一个必须是整形或枚举型。同时还给了一个具体的例子:

#include <stdio.h>int main(void) { int a[3] = { 10, 20, 30 }; printf("a[0] = %d\n", a[0]); printf("a[1] = %d\n", 1[a]); printf("a[2] = %d\n", *(2 + a)); return 0;}

输出结果如下:

a[0] = 10a[1] = 20a[2] = 30

简单来讲,就是a[b]=*(a+b)=*(b+a)=b[a]。但对于为何这么设定,下面并没有具体说明原因。

对此我只想表示,C语言真神奇!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。