Chinaunix首页 | 论坛 | 博客
  • 博客访问: 306569
  • 博文数量: 84
  • 博客积分: 5016
  • 博客等级: 大校
  • 技术积分: 900
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-30 20:22
文章分类

全部博文(84)

文章存档

2008年(21)

2007年(63)

我的朋友

分类: C/C++

2007-01-14 21:24:50

发表个自己写的小程序吧,免得被人误会成只会胡诌白咧的骗子理论家,哈哈。

这个程序是一个多月前愚者刚学C语言没多久的时候写的,后来因为重装系统前忘记备份导致了源代码全数丢失。

今天下午,当愚者想把那个程序发布到这里时才想起来源代码早就没了。

结果花了3小时11分钟才把它重新写出来……

      点击这里察看 :      效果图(1024*768)           代码截图(1024*768)

      点击下载      :       源代码安装包

     (因为上传时,原名Calendar.tar.gz被低智能的网站系统自动改成了070115134333.gz,请下载后自己将后缀名改一下吧,不好意思啦)

     (自己make一下然后用“cld”就能启动程序了)

下面是源代码(分为4个文件编写的)

(关于安装包中的Makefile,就不用写了吧?)

 

main.c

main()
{int y,m,t;
printf("Input year :");
scanf("%i",&y);
printf("Input month:");
scanf("%i",&m);
t=tabs(y,m);
line(0);
loops(y,m,t);
line(1);
}

tabs.c                                                           // 注释1

int tab[12]={1,4,4,0,2,5,0,3,6,1,4,6};               

int tabs (int y,int m)
{int yx,t;
 for(yx=1,t=tab[m-1]-1;yx<=y;yx++)
    {t++;
      if (yx%4==0 && yx!=1000)                          // 注释2
              t++;
    }
 if (y%4==0 && y!=1000 && m<=2)
              t--;
 t%=7;
 return t;
}

line.c

void line (int i)
{printf("------------------------------------------------------------------\n");
 if (i)
   printf("    Made by ZAROK\n\t\t\t\t\t\tCopyright   2006\n");
}

 

loops.c                                                         // 注释3

char mo[12][12]={"January","February","March","April","May","June","July","August","September","October","November","December"};
int  dmax0[12]={31,28,31,30,31,30,31,31,30,31,30,31};    
int  dmax1[12]={31,29,31,30,31,30,31,31,30,31,30,31};

void loops (int y,int m,int t)
{int d,dm,w,i;
 if (y%4==0 && y!=1000)
                 dm=dmax1[m-1];
 else         
 dm=dmax0[m-1];
 printf("\n    Year  : %.4i\n    Month : %s\n\n",y,mo[m-1]);
 line(0);
 printf(" | \tSun\tMon\tTue\tWen\tThu\tFri\tSat\t");
 for(d=1;;)
     {printf("|\n | \t");
      w=1;
      if(d==1)
           {for(i=1;i<=t;i++,w++)
                {printf("\t");
                }
           }
      for(;w<=7;w++,d++)
           {printf("%2i\t",d);
             if (d==dm)
             goto L1;
           }
     }
L1:
 for (i=7-w;i!=0;i--)
     {printf("\t");
     }
 printf("|\n");
}

 

   程序中的变量名起得比较潦草,希望你先打开效果图,这样才能看明白我下面的注释

注释1:

            理所当然,每个月的1号并非都是星期一,所以要使用\t来填充空缺的部分,而这个模块的用途就在于返回你所输入的年份-月份的第一天究竟是星期几——确切地说,应该是输出几个\t 。

            模块中的tab数组所保存的是公元元年中,每个月一号前面的\t数量。另外,有那么一个规律,是我从前无意中发现的——

      假设y年m月1日是星期w(并且y年和y+1年都是平年)

      那么,y+1年的m月1日一定是星期w+1(别问我“如果w是星期日会怎么样”,w是七进制的,我想你不会不明白吧?);

      如果y是闰年,那y+1年的2月以下的月份的1号是星期w+2,其他月份是w+1,而y-1年的2月以上的月份的1号是星期w-2。

            最终,该模块将最终计算的结果%7(如果你不知道为什么%7,关上这篇文章,干点别的去吧)所得的结果就是你所输入的这个月的1号前面将会输出的\t的数量。

 

注释2:

            在这里,不得不说的一个重点就是公元1000年,理论上它是闰年,这点毫无疑问,但事实上,历史中的公元1000年是被当时的居民按照平年算的(你可以查一查其他的万年历,这是真的,如果那一年是闰年,公元1000年后的全部历史都会往后错一天),愚者实在无法理解古代的那些低能们为什么要这么做,这为愚者编写程序带来了很大的不便!这一点是愚者失败了十多次才发现的(原来不是代码有错)——一通咒骂之余,不得不加上对于公元1000年特别处理的代码。

 

注释3:

            这个模块是负责主要内容的输出的(比第二个模块要容易理解多了吧?),文中两个dmax数组分别是平年和闰年中每个月的最大天数,用于对日期输出的控制。这个模块虽然稍显庞大,不过没有难点,主要的一点技巧也就是输出中,月份的最后一天与边缘线之间的动态距离控制,其实很简单,一个星期一共有几天?这个月的最后一天是星期几?该输出几个\t还不知道吗?

 

另外,正如愚者在文章《数据类型》中所述,这和你在国考2级中所学到的完全不同,因为那并不是真正的C,那些东西很多都只是局限于可怜又难看的TC编译器——你别忘了16位的模拟环境毕竟是过时的产物,如果你真想学会C,去用开源系统才是唯一的选择。

我的意思是,你看到了,如果你输入一个科幻小说中的年份,在模块tabs中那些\t的数量累积起来会有多么恐怖,用TC来做的话,发生数据溢出是一件多么容易的事(可能除此之外,TC没有别的长处了)。

选一个好的编译器,他会成为你最得力的帮手,选一个差的,它会处处与你作对。

 

PS:

      虽然对你来说tabs模块可能看起来有一点晦涩难懂,但是不要轻易的下结论——这并不意味着我没有遵守KISS原则,事实上,那是个很好的原则,我也向来都很遵守它的。只是这个模块的功能实在很难表述,但它的确非常重要。

      我知道,很可能我上面的一番解释仍然无法让你明白某些代码的含义,毕竟语言不是万能的,希望你自己去做,忘掉我的思路、我的逻辑、我发现的规律,一切自己动手,从头来

      ——我不就是这么一路走过来的吗?

 

ZARK
阅读(1378) | 评论(1) | 转发(0) |
0

上一篇:TO:小朋友

下一篇:简历

给主人留下些什么吧!~~

chinaunix网友2008-01-01 11:37:58

恩。這文章不錯。