第20届国际C语言代码大赛《科学计算器》代码分析

来源:互联网 发布:写轮眼p图软件 编辑:程序博客网 时间:2024/05/02 00:13

    本文试图分析一个来在中国的Hou Qiming编写的一个科学计算器代码,看看它的真实面目是什么,以及它是如何工作的。关于这个程序的介绍请参阅http://www.ioccc.org/2011/hou/hint.html

 

原始的代码见下 

#include <stdio.h>#include <math.h>#define clear 1;if(c>=11){c=0;sscanf(_,"%lf%c",&r,&c);while(*++_-c);}\  else if(argc>=4&&!main(4-(*_++=='('),argv))_++;g:c+=#define puts(d,e) return 0;}{double a;int b;char c=(argc<4?d)&15;\  b=(*_%__LINE__+7)%9*(3*e>>c&1);c+=#define I(d) (r);if(argc<4&&*#d==*_){a=r;r=usage?r*a:r+a;goto g;}c=c#define return if(argc==2)printf("%f\n",r);return argc>=4+#define usage main(4-__LINE__/26,argv)#define calculator *_*(int)#define l (r);r=--b?r:#define _ argv[1]#define xdouble r;int main(int argc,char** argv){  if(argc<2){    puts(      usage: calculator 11/26+222/31      +~~~~~~~~~~~~~~~~~~~~~~~~calculator-\      !                          7.584,367 )      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+      ! clear ! 0 ||l   -x  l   tan  I (/) |      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+      ! 1 | 2 | 3 ||l  1/x  l   cos  I (*) |      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+      ! 4 | 5 | 6 ||l  exp  l  sqrt  I (+) |      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+      ! 7 | 8 | 9 ||l  sin  l   log  I (-) |      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0    );  }  return 0;}

 

采用GCC 对原始代码进行预处理,并重新编排格式,得到功能等价的代码如下。

 

#include <stdio.h>#include <math.h>double r;int main(int argc,char** argv){if(argc<2){    if(argc==2)     printf("%f\n",r);    return argc>=4+ 0;    }        {    double a;    int b;char c;    c= (argc<4?main(4-21/26,argv): *argv[1]*(int) 11/26+222/31 + *argv[1]*(int)- !7.584)&15; b=(*argv[1]%21 +7)%9*(3*367>>c&1);    c+= !1;    if(c>=11)    {    c=0;    sscanf(argv[1],"%lf%c",&r,&c);    while( *++argv[1]-c);    }    else if ( argc>=4 && !main ( 4- ( *argv[1]++=='('),argv) ) argv[1]++;        g:    c+= ! 0 || (r);    r=--b? r: - (r);    r=--b? r: tan (r);        if (argc<4&&*"/"==*argv[1])    {    a=r;    r=main(4-23/26,argv)? r*a: r+a;    goto g;    }        c=c |! 1 | 2 | 3 || (r);      r=--b?r: 1/ (r);      r=--b?r: cos (r);            if (argc<4&&*"*"==*argv[1])      {      a=r;      r=main(4-25/26,argv)?r*a:r+a;      goto g;      }                  c=c | !4 | 5 | 6 || (r);            r=--b ? r: exp (r);      r=--b ? r: sqrt (r);            if (argc<4&&*"+"==*argv[1])      {      a=r;      r=main(4-27/26,argv) ? r*a : r+a;      goto g;      }            c=c | ! 7 | 8 | 9 ||(r);            r=--b? r: sin (r);      r=--b? r: log (r);            if (argc<4 && *"-" == *argv[1] )      {      a=r;      r=main(4-29/26,argv)?r*a:r+a;      goto g;      }  }  if(argc==2)  printf("%f\n",r);  return argc>=4+0;}


 

可以看出,这个程序是一个递归程序,main函数反复的调用自己,将计算结果存入全局变量r,当所有计算完成后,打印计算结果。限于时间的关系,这里暂不分析其工作原理,等以后有时间再作分析。

 

原创粉丝点击