阅读以下说明和C语言函数,将应填入(n)处的字句写在对应栏内。 【说明】 函数count months(DATE start,DATE end)的功能是:计算两个给定日期之间所包含的完整月份数。 该函数先算出起止日期中所含的完整年数,再计算余下

admin2008-11-20  43

问题 阅读以下说明和C语言函数,将应填入(n)处的字句写在对应栏内。
【说明】
   函数count months(DATE start,DATE end)的功能是:计算两个给定日期之间所包含的完整月份数。
   该函数先算出起止日期中所含的完整年数,再计算余下的完整月份数。
   规定两个相邻年份的同月同日之间的间隔为1年。例如,2007.5.30—2008.5.30的间隔为1年。若相邻两年中前一年是闰年,并且日期是2月29日,则到下一年的2月28日为1年,即2008.2.29—2009.2.28的间隔为1年。
   规定两个相邻月份的相同日之间的间隔为1个月,但需要特别考虑月末的特殊情况。例如,2007.1.29—2007.2.28的间隔为1个月,同理,2007.1.30—2007.2.28、2007.1.31—2007.2.28的间隔都是1个月。
   计算起止日期间隔不足一年的完整月份数时,分如下两种情况。
   (1)起止日期不跨年度。先用终止日期的月号减去起始日期的月号得到月份数,然后再根据情况进行修正。例如,起止日期为2008.3.31—2008.9.20,通过月号算出月份数为6。修正时,通过调用函数makevalid将2008.9.31改为2008.9.30,与终止日期2008.9.20比较后,将月份数修正为5。
   (2)起止日期跨年度。计算方法如下例所示:对于起止日期2008.7.25—2009.3.31,先计算2008.7.25—2008.12.25的月份数为5,再算出2008.12.25—2009.3.25的月份数为 3,因此2008.7.25—2009.3.31之间的完整月份数为8。
   日期数据类型定义如下:
   typedef struct{
   int year;   int month;   int day; /*日期的年号(4位)、月和口号*/
   }DATE;
  程序中使用的函数cmp_date()、isLeap Year()和makevalid()说明如下。

【C语言函数】
   int count_months (DATE start,DATE end)
   {
      int years = 0, months = 0;
      DATE r;
      if  (cmp_date(start,end)  > 0)  {
           r = start;  start = end; end = r;
      }
    years = end.year - start.year; /*计算年数*/
      r = start;
      r.year = end.year;
      if (cmp_date(r, end)  > 0)  {    /*修正年数*/
           (1);
           r.year--;
      }
   if (r.year < end.year) {        /*跨年度时,先计算到12月的月份数*/
         months =(2);
         r.month = 12;
      }
      months += (end.month + 12 - r.month) % 12;
      r.year = end.year;      r.month = end.month;
      makevalid ((3));          /*将日期r修正为有效日期*/
      if (cmp_date(r,end) > 0)      /*修正月份数*/
     (4);
       months +=(5);           /*计算总月份数*/
       return months;
   }使用的函数cmp_date()、isLeap Year()和makevalid()说明如下。

选项

答案(1)years--,或其等价形式 (2)12 - r.month,或其等价形式 (3)&r (4)months--,或其等价形式 (5)years * 12

解析 本题考查编程能力。
   根据题目的说明,函数count_months(DATE start,DATE end)的功能是计算两个给定日期之间所包含的完整月份数。
   计算月份数时,可以从起始日期开始,到终止日期结束,逐月计算;也可以先算出完整年份数,再计算剩余的完整月份数,最后用完整年份数乘以12再加上剩余的完整月份数。题目中采用后者。
   先用end的年号减去start的年号,得到一个年份值,如下所示:
   years = end.year - start.year;   /*计算年数*/
   显然,上式算出的年份数可能产生误差(多算一年,即end的月号和日期要小于start的日期),因此可能需将years减去1后进行修正。因此,空(1)处应填入“years--”。
   接下来计算月份数。由题目中的说明,计算起止日期间隔不足一年的完整月份数时,分如下两种情况。
   (1)起止日期跨年度。计算方法如下例所示:对于起止日期2008.7.25—2009.3.31,先计算2008.7.25—2008.12.25的月份数为5,再算出2008.12.25—2009.3.25的月份数为 3,因此2008.7.25—2009.3.31之间的完整月份数为8。以下代码处理该情况:
   if  (r.year < end.year)  {    /*跨年度时,先计算到12月的月份数*/
           months =  (2)  ;
           r.month = 12;
        }
   因此,空(2)处应填入“12-r.month”。
   (2)起止日期不跨年度。先用终止日期的月号减去起始日期的月号得到月份数,然后再根据情况进行修正。例如,起止日期为2008.3.31—2008.9.20,通过月号算出月份数为6。修正时,通过调用函数makevalid将2008.9.31改为2008.9.30,与终止日期2008.9.20比较后,将月份数修正为5。以下代码处理该情况:
   months +=  (end.month + 12 - r.month)  %  12;
       r.year = end.year;     r.month = end.month;
       makevalid(  (3)  );     /*将日期r修正为有效日期*/
       if  (cmp_date(r,end) > 0)    /*修正月份数*/
     (4)  ;
   根据函数makevalid的接口说明,其实参应取变量r的地址,因此空(3)处填入“&r”。
   简单地用两个月份号相减可能产生的误差是多算了一个月,因此将months减1进行修正,所以空(4)处填入“months--”。
   最后计算总月份数,年份数乘以12再加上不足一整年的月份数即可得到月份总数。因此空(5)处填入“years*12”。
转载请注明原文地址:https://kaotiyun.com/show/VsjZ777K
0

最新回复(0)