其中 if 语句的布尔表达式是根据闰年的规定得到的:年份能被 4 整除并且不能被 100 整除(除非该年能被 400 整除)。

    再考虑函数 heading 的实现,该函数用于打印每个月日历的标题部分(月份和星期名 称)。我们将月份名称放在一个列表中,然后通过传递给 heading 函数的月份值作为索引 来查找月份名称。代码如下:

    图 4.9 每个月的日历布局 由于问题有点复杂,我们再次分解任务,用三个子程序来实现 oneMonth():days() 函数计算该月份的天数,layout()函数用于布置该月每一天在日历框架中的位置 ,printMonth()用于输出日历。即:

    oneMonth 函数有三个参数:year 表示年份,month 表示月份,first 表示该月 1 日是星期几(0~6)。对于一月份,first 由上层模块 printCalendar 的参数 w 提供; 对于其他月份,first 可由上一个月的 first 和天数确定,因此我们让 oneMonth 在打印 本月日历后返回下个月 1 日的星期序号。

    设计至此,结构图演变为图 4.10 所示的情况。

    4.3.3 第三层设计 - 图2

    图 4.10 calendar 程序的第三层结构图