为什么我的程序要在非闰年中多加一天?
Why is my program adding an extra day to a non leap year?
这是我的程序,我根据输入的日期找到一年中的某一天。我还必须考虑闰年。我拥有所有这些,但是当输入诸如 12/31/1993 之类的年份时,我得到的日期是 366,这是不正确的,因为它不是闰年,所以一年中的某一天应该是 365。我测试过这是否是我的 if 语句,只是让程序能够只测试闰年并在非闰年时关闭。当输入相同的日期时,程序关闭并告诉我问题不在我的 if 语句中,而在我的 case 和 switch 中。我不太确定发生了什么,也不确定为什么要在日期中添加额外的一天。
#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;
}
代码通过标签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;
}
您需要在标签 one:
后加上一个 return。因为在执行 one:
之后,还有两个也被执行了。
此外,
- 始终尽量避免使用
goto
语句
month=month
行完全没有必要。
- 代码重复较多
更好的方法是:
#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;
}
为什么不用数组来简化代码。即
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 开始 - 它只是一个填充符
这是我的程序,我根据输入的日期找到一年中的某一天。我还必须考虑闰年。我拥有所有这些,但是当输入诸如 12/31/1993 之类的年份时,我得到的日期是 366,这是不正确的,因为它不是闰年,所以一年中的某一天应该是 365。我测试过这是否是我的 if 语句,只是让程序能够只测试闰年并在非闰年时关闭。当输入相同的日期时,程序关闭并告诉我问题不在我的 if 语句中,而在我的 case 和 switch 中。我不太确定发生了什么,也不确定为什么要在日期中添加额外的一天。
#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;
}
代码通过标签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;
}
您需要在标签 one:
后加上一个 return。因为在执行 one:
之后,还有两个也被执行了。
此外,
- 始终尽量避免使用
goto
语句 month=month
行完全没有必要。- 代码重复较多
更好的方法是:
#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;
}
为什么不用数组来简化代码。即
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 开始 - 它只是一个填充符