为什么我的程序在非闰年增加了一天?

时间:2015-09-23 05:15:29

标签: c if-statement switch-statement

这是我的计划,我根据投入的日期找到了一年中的日期。我还必须考虑闰年。我已经完成了所有这些,但当输入一年如12/31/1993时,我得到366这一天是不正确的,因为它不是闰年所以一年中的那一天应该是365.我已经测试过这是否是我的if声明,只是让程序能够只测试闰年,并且如果它是非闰年就关闭。当输入相同的日期时,程序关闭,告诉我问题不在于我的if语句,而在于我的情况和开关。我不确定发生了什么,或者为什么要在额外的一天加入日期。

#include <stdio.h>

int main(void){

    int month,day,year,day_number=0;

    printf("Enter a date in the form (01/02/1996): ");
    scanf("%d/%d/%d", &month,&day,&year);


    if(((year%4 == 0) && (year%100 !=0)) || (year%400==0)){
        goto two;
    }
    else{
        month=month;
        goto one;
    }

    one:
        switch(month)
        {
            case 1:day_number=day;
                break;
            case 2:day_number=31+day; //January+Febuary
                break;
            case 3:day_number=59+day; //January+Febuary+March
                break;
            case 4:day_number=90+day; //January+Febuary+March+April
                break;
            case 5:day_number=120+day; //January+Febuary+March+April+May
                break;
            case 6:day_number=151+day; //January+Febuary+March+April+May+June
                break;
            case 7:day_number=181+day; //January+Febuary+March+April+May+June+July
                break;
            case 8:day_number=212+day; //January+Febuary+March+April+May+June+July+August
                break;
            case 9:day_number=243+day; //January+Febuary+March+April+May+June+July+August+September
                break;
            case 10:day_number=273+day; //January+Febuary+March+April+May+June+July+August+September+October
                break;
            case 11:day_number=304+day; //January+Febuary+March+April+May+June+July+August+September+October+November
                break;
            case 12:day_number=334+day; //January+Febuary+March+April+May+June+July+August+September+October+November+December
                break;
        }
    two:
        switch(month)
        {
            case 1:day_number=day;
                break;
            case 2:day_number=31+day; //January+Febuary
                break;
            case 3:day_number=60+day; //January+Febuary+March
                break;
            case 4:day_number=91+day; //January+Febuary+March+April
                break;
            case 5:day_number=121+day; //January+Febuary+March+April+May
                break;
            case 6:day_number=151+day; //January+Febuary+March+April+May+June
                break;
            case 7:day_number=182+day; //January+Febuary+March+April+May+June+July
                break;
            case 8:day_number=213+day; //January+Febuary+March+April+May+June+July+August
                break;
            case 9:day_number=243+day; //January+Febuary+March+April+May+June+July+August+September
                break;
            case 10:day_number=274+day; //January+Febuary+March+April+May+June+July+August+September+October
                break;
            case 11:day_number=304+day; //January+Febuary+March+April+May+June+July+August+September+October+November
                break;
            case 12:day_number=335+day; //January+Febuary+March+April+May+June+July+August+September+October+November+December
                break;
        }
    printf("day %d\n", day_number);

        return 0;
}

3 个答案:

答案 0 :(得分:5)

代码经过标签one:后,没有什么可以阻止它执行标签two:下的所有内容。所以,它也会执行这些行。

<强>更新

goto陈述是上个世纪:)除非没有别的办法,否则请避开它们。

您可以使用合适的功能减少大量冗余代码。

#include <stdio.h>

int get_non_leap_year_day()
{
   switch(month)
   {
      case 1:
         return day;

      case 2:
         return 31+day; //January+Febuary

      case 3:
         return 59+day; //January+Febuary+March

      case 4:
         return 90+day; //January+Febuary+March+April

      case 5:
         return 120+day; //January+Febuary+March+April+May

      case 6:
         return 151+day; //January+Febuary+March+April+May+June

      case 7:
         return 181+day; //January+Febuary+March+April+May+June+July

      case 8:
         return 212+day; //January+Febuary+March+April+May+June+July+August

      case 9:
         return 243+day; //January+Febuary+March+April+May+June+July+August+September

      case 10:
         return 273+day; //January+Febuary+March+April+May+June+July+August+September+October

      case 11:
         return 304+day; //January+Febuary+March+April+May+June+July+August+September+October+November

      case 12:
         return 334+day; //January+Febuary+March+April+May+June+July+August+September+October+November+December
   }

   // Never should come here.
   // Add a return to keep the compiler happy.
   return 0;
}

int get_leap_year_day()
{
   int day_number = get_leap_year_day();
   if ( month > 2 )
   {
      day_number++;
   }
   return day_number;
}

int main(void)
{
   int month,day,year,day_number=0;

   printf("Enter a date in the form (01/02/1996): ");
   scanf("%d/%d/%d", &month,&day,&year);

   if(((year%4 == 0) && (year%100 !=0)) || (year%400==0))
   {
      day_number = get_leap_year_day(month, day);
   }
   else
   {
      day_number = get_non_leap_year_day(month, day);
   }

   printf("day %d\n", day_number);

   return 0;
}

答案 1 :(得分:2)

您需要在标签one:后面添加一个回复。因为执行one:之后两个人也被执行了。

此外,

  1. 始终尽量避免使用goto语句
  2. month=month行完全没必要。
  3. 有很多代码重复。
  4. 一种更好的方法是:

    #include <stdio.h>
    
    int main(void)
    {
    
      int month,day,year,day_number=0;
    
      printf("Enter a date in the form (01/02/1996): ");
      scanf("%d/%d/%d", &month,&day,&year);
    
    
    
    
      switch(month)
      {
         case 1:day_number=day;
               break;
        case 2:day_number=31+day; //January+Febuary
               break;
        case 3:day_number=59+day; //January+Febuary+March
               break;
        case 4:day_number=90+day; //January+Febuary+March+April
               break;
        case 5:day_number=120+day; //January+Febuary+March+April+May
               break;
        case 6:day_number=151+day; //January+Febuary+March+April+May+June
               break;
        case 7:day_number=181+day; //January+Febuary+March+April+May+June+July
               break;
        case 8:day_number=212+day; //January+Febuary+March+April+May+June+July+August
               break;
        case 9:day_number=243+day; //January+Febuary+March+April+May+June+July+August+September
               break;
        case 10:day_number=273+day; //January+Febuary+March+April+May+June+July+August+September+October
               break;
        case 11:day_number=304+day; //January+Febuary+March+April+May+June+July+August+September+October+November
               break;
        case 12:day_number=334+day; //January+Febuary+March+April+May+June+July+August+September+October+November+December
               break;
      }
    
      if(((year%4 == 0) && (year%100 !=0)) || (year%400==0))
      {
           if(month>2)
           ++day_number;
      }
    
    
      printf("day %d\n", day_number);
      return 0;
    }
    

答案 2 :(得分:0)

为什么不使用数组来简化代码。即。

static int days_in_non_leap_year[] = 
   {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; 

if (((year%4 == 0) && (year%100 !=0)) || (year%400==0)) {
   day_number = days_in_non_leap_year[month] + 1 + days;
} else {
   day_number = days_in_non_leap_year[month] + days;
}

当然你也应该检查输入。 -1是因为月份从1开始 - 它只是一个填充物