习题9.5
(1)输入某年某月某日,计算并输出他是这一年的第几天。
解析:
在看到这道题,我的第一想法是如何判断是不是闰年(因为闰年的2月是29天,而非闰年的2月是28天,这对于月份的计算很重要,因为这道题是计算第几天,所以涉及到前边月份求和)对于闰年的判断就是year%4==0&&year%100!=0或者year%400==0就这两种判断方法,由于数组的下标是从0开始的,而人们对月份的编写是从1开始的,这就造成输入的月份一定要和数组区分开。
int DayofYear(int year,int month,int day)
{
int ans=0;
if((year%4==0&&year%100!=0)||(year%400==0))//判断是不是闰年
{
for(int i=0;i<=month-2;i++)
{
ans+=data[1][i];//闰年
}
ans+=day;
}
else
{
for(int i=0;i<month-2;i++)
{
ans+=data[0][i];//非闰年
}
ans+=day;
}
return ans;
}
注意:
上边的data数组并没有传入到函数中,所以我采用的是全局变量,读者在敲代码时一定不要忘记在函数前加入全局变量data数组。
整体代码:
#include <stdio.h>
#include <stdlib.h>
int data[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
int DayofYear(int year,int month,int day)
{
int ans=0;
if((year%4==0&&year%100!=0)||(year%400==0))
{
for(int i=0;i<=month-2;i++)
{
ans+=data[1][i];
}
ans+=day;
}
else
{
for(int i=0;i<month-2;i++)
{
ans+=data[0][i];
}
ans+=day;
}
return ans;
}
int main()
{
printf("请输入查寻的日期:\n");
int year,month,day;
scanf("%d %d %d",&year,&month,&day);
int ans=DayofYear(year,month,day);
printf("是今年的第%d天\n",ans);
return 0;
}
(2)输入某一年的第几天,计算并输出它是这一年的第几月第几天。
解析:
看到题目首先判断闰年,这在第一问已经解释过了这里不再赘述。对于给出第几天可以采用逆向考虑,第几天是如何构成的?
假如给出2000年的第61天,那么这是几月几号呢?请读者自行查找月份表试试。首先2000年是闰年,那么2000年的2月就有29天。由于1月份有31天,并且61>31,那么61-31=30天。2月份有29天,并且30>29,30-29=1。3月份有31天,但是1<31于是2000年的第61天就是2000年3月1日。
可能有的读者已经理解我给出的这个例子是什么意思了,给出第几天让我们算出是几月几号也就是说这个过程是用当前剩余天数与当前月份天数比较,如果大于月份天数,两者相减剩余的数作为剩余天数,与下一个月作比较,直到剩余天数比月份天数小,此时剩余天数就是在月份中的天数。
整体代码:
#include <stdio.h>
#include <stdlib.h>
int data[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
void MonthDay(int year,int yearday,int *pMonth,int *pDay)
{
int n=0;
if((year%4==0&&year%100!=0)||year%400==0)//判断是闰年
{
while(yearday>data[1][n])
{
yearday-=data[1][n];
n++;
}
}
else
{
while(yearday>data[0][n])
{
yearday-=data[0][n];
n++;
}
}
*pMonth=n+1;
*pDay=yearday;
}
int main()
{
int year,yearday,pMonth,pDay;
printf("请输入哪一年的第几天:\n");
scanf("%d %d",&year,&yearday);
MonthDay(year,yearday,&pMonth,&pDay);
printf("%d年的第%d天是%d月%d日\n",year,yearday,pMonth,pDay);
return 0;
}
注意:
请读者考虑在这段代码中是否会出现空指针引用等情况。
(3)输出如下菜单,用switch语句实现选择相应的操作
year/month/day->yearday
yearday->year/month/day
Exit
please enter your choice
解析:
此题考验对switch语句的使用,以及将前两问的函数整理到一起。
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
int data[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
int DayofYear(int year,int month,int day)
{
int ans=0;
if((year%4==0&&year%100!=0)||(year%400==0))
{
for(int i=0;i<=month-2;i++)
{
ans+=data[1][i];
}
ans+=day;
}
else
{
for(int i=0;i<month-2;i++)
{
ans+=data[0][i];
}
ans+=day;
}
return ans;
}
void MonthDay(int year,int yearday,int *pMonth,int *pDay)
{
int n=0;
if((year%4==0&&year%100!=0)||year%400==0)//判断是闰年
{
while(yearday>data[1][n])
{
yearday-=data[1][n];
n++;
}
}
else
{
while(yearday>data[0][n])
{
yearday-=data[0][n];
n++;
}
}
*pMonth=n+1;
*pDay=yearday;
}
int main()
{
printf("1. year/month/day->yearday\n2. yearday->year/month/day\n3. Exit\nplease enter your choice:\n");
int n;
scanf("%d",&n);
switch(n%3)//选择%3是想输入任意数都能有操作
{
case 0:
{
break;
}
case 1:
{
printf("请输入查寻的日期:\n");
int year,month,day;
scanf("%d %d %d",&year,&month,&day);
int ans=DayofYear(year,month,day);
printf("是今年的第%d天\n",ans);
break;
}
case 2:
{
int year,yearday,pMonth,pDay;
printf("请输入哪一年的第几天:\n");
scanf("%d %d",&year,&yearday);
MonthDay(year,yearday,&pMonth,&pDay);
printf("%d年的第%d天是%d月%d日\n",year,yearday,pMonth,pDay);
break;
}
}
return 0;
}