话不在多,达意就行
在学校bbs的C/C++版上看到这么一个小小的C程序,顿时勾起了我的好奇心。
源代码非常简短,仅有一行:
main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}
分析一下,其实是等价于下面更易懂得形式:
main()
{
int i=1;
char data[]="J!Mpwf!Zpv\1";
for(--i; putchar(data[i++]-1); )
}
首先是_这个东西有点碍眼。其实它就是一个变量标示符,同普通变量i没有区别。
其次是对for循环退出条件的理解。putchar是stdio.h中定义的系统函数,在屏幕上输出传递给他的字符串。返回的值不是十分清楚,但可以肯定地是当传给他的参数是’\0’时返回0。这样for就可以退出了。
最核心的是对_++["J!Mpwf!Zpv\1"]的理解。C中a[b]的等价形式是*(a+b)。所以_++["J!Mpwf!Zpv\1"]与"J!Mpwf!Zpv\1"[_++]是等同的,都等价于*((_++)+"J!Mpwf!Zpv\1")。"J!Mpwf!Zpv\1"作为一个字符数组常量,在C编译器看来与其首地址没有区别的。所以for循环的作用就是遍历字符数组"J!Mpwf!Zpv\1",在屏幕上输出其中每个字符的ASCII码-1对应的字符。至于这些字符是什么,自己试试就知道了J。PS:原帖子的标题是“追“计院”mm得用这个程序”,呵呵。
接下来是变量_的初值得问题。一开始我不理解为什么_的初值是1,后经bbs高手点拨,原来_作为main的参数,原形为main(int argv, char *args[])。在运行程序的时候默认情况可执行文件的路径作为唯一一个参数传递给main,所以argv(即_)为1。这也是for循环在初始化时对_作—操作的原因。
最后,在Linux环境下用gcc –S得到了终极汇编代码,经过分析,一切都真相大白。
别看这个程序只有短短的一行代码,但是要透彻的理解它,没有扎实的C语言基本功是不行的。
就像爱情的表白一样,话不再多,达意就行。
什么,你还没编译出来,赶紧把这行代码运行了再来发言……
注:Visual Studio的编译器需要把main(_)改为main(int _)
Labels: Computer Technology

0 Comments:
Post a Comment
<< Home