算是第一个实用的程序吧,具有一定的实用价值。本以为很简单,但是C毕竟是好久不碰了,在细节上仍然还是没能完善代码。果然,C不是一天两天就能掌握会的。
由于是月历,所以,算法采用每月的第一天是星期几的思路确定1号的位置,然后顺延下来。计算星期的方法采用蔡勒公式,这时的C在整数除法上的特点便显示出来优势了——不用专门取整了。

附上蔡勒公式:$$w=y+\left[\frac{y}{4}\right]+\left[\frac{c}{4}\right]-2c+\left[13\frac{((m+1)}{5}\right]+d-1$$

w代表星期,取模得星期数(0为周日,1为周一,以此类推),c是年份前两位数,y是年份后两位数,m是月份(1、2月转换成上一年13月和14月),d表示日期。
#include<stdio.h>
int Zeller(int y,int m);
int run(int n);
void main()
{
int year,month,i,j,k,n=1,day;
printf("欢迎使用万年历查询工具。\n");
printf("请输入要查询的年份(本程序只支持公元后):\n");
scanf("%d",&year);
printf("请输入月份:\n");
scanf("%d",&month);
i=Zeller(year,month);
switch(month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:day=31;break;
case 4:
case 6:
case 9:
case 11:
day=30;break;
case 2:day=run(year);
}
printf(" S M T W T F S\n");
for(j=0;j<=5;j++)
{
for(k=0;k<=6;k++)
{
if((j==0)&&(j*4+k)<i)
printf(" ");
else
if(n<=day)
{
printf("%3d",n);
n++;
}
}
printf("\n");
}
}

int Zeller(int y,int m)
{
int w,c,d;
c=y/100;
d=y-c*100;
if(m<=2)
{
d-=1;
m+=12;
}
w=d+d/4+c/4-2*c+26*(m+1)/10;
while(w<0)
{
w+=7;
}
return w%7;
}

int run(int n)
{
if(n%100==0)
{
if(n%400==0)
return 29;
else
return 28;
}
else
{
if(n%4==0)
return 29;
else
return 28;
}
}

PS:高亮的滚动条成了鸡肋了。。。。

作者 hsyyf

《用C写的万年历》有5条评论
  1. 真复杂。。。
    ($sec,$min,$hour,$day,$mon,$year,$wan)=localtime(time);
    $year+=1900; $mon+=1; $wan1=($wan+7-($day-1)%7)%7; # 1号是星期几
    $wan%=7;
    …;
    $pango .= ‘ ‘ x $wan1;

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注