voidshow_year(int year)
{inti,j,k,t,n; // 用来辅助计数int table[24][21] = {0}; // 年历数组int month_day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; // 每月上限天数if ((0 == year%4 || 0 == year%400) && 0 != year%100) //闰年检查,如果是闰年,2月上限天数改为29
{
month_day[2] = 29;
}
printf ("******************\n");
printf ("%d \n", year);
printf ("******************\n");for (i=0; i<12; i++) // 为了使逻辑更加清晰,一次循环只完成一个月的日期填写,i为当前月份
{n=cal_first(i+1); // n为当前月份第一天的星期数,cal_first函数中的月数必须为1~12,for (j=(i/3)*6; j3)*6+6; j++) // 所以这里传参时+1,j用来根据月数控制每个月在年历数组中的第一维坐标
{ // 坐标(纵坐标)的位置,同样的,用来根据月数控制每个月在年历数组中for (k=(i%3)*7; k3)*7+7; k++) // 第二维坐标(横坐标)的位置
{
t= (j%6)*7 + k%7 - n + 2; // t用来临时记录当前位置应该填入年历数组的值,为了简化逻辑,这里通过if (0 >=t) // 数学计算记录每一个位置应填入的值,(j%6)*7 + k%7计算出的值是本
{ // 月的第几个位置,-n+2就会计算出当前格内正确的日期。这样做会导致得出continue; // 负数或0,或炒熟每月天数上限,我们用if + continue将其跳过,这样
} // 不正确的日期就依然是年历数组初始化时的0if (t <=month_day[i])
{
table[j][k]=t;
}else{continue;
}
}
}
}for (i=0; i<24; i++) // 至此,年历数组已经全部填好,接下来是打印环节,相信已经比较好理解了
{ // 每隔6行打印标头,7列多打印几个空格,遇到数组中为0则同样打印空格if (0 ==i)
{
printf ("Jan Feb Mar\n");
printf ("Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun\n");
}if (6 ==i)
{
printf ("Apr May Jun\n");
printf ("Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun\n");
}if (12 ==i)
{
printf ("Jul Agu Sep\n");
printf ("Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun\n");
}if (18 ==i)
{
printf ("Oct Nov Dec\n");
printf ("Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun Mon Tue Wen Thu Fir Sat Sun\n");
}for (j=0; j<21; j++)
{if (7 == j || 14 ==j)
{
printf (" ");
}if (0 ==table[i][j])
{
printf (" ");continue;
}
printf ("%4d", table[i][j]);
}
printf ("\n");
}
}