任务和代码:
定义一个表示时间(包括年、月、日、时、分、秒)的结构体,然后完成下面的功能。
提示:将各个功能分别设计成函数实现,在main函数中调用,进行测试。可以设计一个函数,即刻进行测试,以降低复杂度。
要实现的功能是:
(1)输入一个时间(注意各部分数据的取值范围)将输入的时间保存在一个结构体变量中;
(2)输出该日在本年中是第几天(注意闰年问题);
(3)输出这是这一天中的第几秒;
(4)输出这是这一年中的第几秒;(不要认为这个数荒唐,在计算中需要取随机数时需要一个不会重复的“种子数”,这个秒数是常用的。)
(5)求你输入的时间d天后是哪年哪月哪日,将结果保存在一个结构体变量中输出。
//head.h
#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
typedef struct{
int year;
int month;
int day;
int hour;
int minute;
int second;
}Time;
int daysInYear(Time *);
long secondsInDay(Time *);
long secondsInYear(Time *);
Time *dateAfterDays(Time *,int);
void outputTime(Time *);
int daysOfYear(int);
int daysOfMonth(int,int);
#endif // HEAD_H_INCLUDED
//main.c
#include
#include "head.h"
int main(){
Time time,*pt,*pt1;
pt=&time;
int days;
printf("请输入一个时间:");
scanf("%d %d %d %d %d %d",&pt->year,&pt->month,&pt->day,&pt->hour,&pt->minute,&pt->second);
printf("\n");
printf("该日在本年中是第%d天:\n",daysInYear(pt));
printf("这是这一天中的第%ld秒:\n",secondsInDay(pt));
printf("输出这是这一年中的第%ld秒:\n\n",secondsInYear(pt));
printf("间隔多少天:");
scanf("%d",&days);
printf("%d天后是哪年哪月哪日:\n",days);
pt1=dateAfterDays(pt,days); //将结果保存在一个结构体变量中输出
outputTime(pt1);
return 0;
}
//daysInYear.c
#include
#include "head.h"
int daysInYear(Time *p){
int sum=p->day;
int a[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int i;
for(i=1;imonth;i++){
sum+=a[i];
}
if(p->month>2&&((p->year%4==0&&p->year%100!=0)||p->year%400==0)) //若闰年,且晚于2月,加一天
sum++;
return sum;
}
//secondsInDay.c
#include
#include "head.h"
long secondsInDay(Time *p){
return (p->second+p->minute*60+p->hour*3600);
}
//secondsInYear.c
#include
#include "head.h"
//先算该年第几天再算该天第几秒
long secondsInYear(Time *p){
int sumDay=p->day;
int a[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int i;
for(i=1;imonth;i++){
sumDay+=a[i];
}
if(p->month>2&&((p->year%4==0&&p->year%100!=0)||p->year%400==0))
sumDay++;
return ((sumDay-1)*3600+secondsInDay(p)); //该年该天前所有的秒数加上该天的秒数
}
//daysOfYear.c
#include
#include "head.h"
int daysOfYear(int y){
return ((y%4==0&&y%100!=0)||y%400==0)?366:365;
}
//daysOfMonth.c
#include
#include "head.h"
int daysOfMonth(int m,int y){
int days;
switch(m){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days=31;
break;
case 4:
case 6:
case 9:
case 11:
days=30;
break;
case 2:
if((y%4==0&&y%100!=0)||y%400==0)
days=29;
else
days=28;
}
return days;
}
//outputTime.c
#include
#include "head.h"
void outputTime(Time *p){
printf("时间为: %d年%d月%d日%d时%d分%d秒\n",p->year,p->month,p->day,p->hour,p->minute,p->second);
}
//dateAfterDays.c
#include
#include "head.h"
//以天数为最小计数单位并以日/月/年从右至左进位
Time *dateAfterDays(Time *p,int d){
Time *tp;
tp=p;
int d1=d+daysInYear(p); //从该日期的当年第几天的基础上加上天数
tp->month=1; //已将指定日期的月日转换成当年第几天,故1月成为起始月
tp->day=0;
while(d1>daysOfYear(tp->year)){
d1-=daysOfYear(tp->year); //把当年是平年还是闰年考虑进去
++tp->year;
}
while(d1>daysOfMonth(tp->month,tp->year)){
d1-=daysOfMonth(tp->month,tp->year);
++tp->month;
}
tp->day+=d1; //tp->day=0; 加上d1天,故设初值为0
return tp;
}
1)使用了工程中更常用的指向结构体变量的指针;
2)用指向结构体变量的指针进行函数传参,加深了返回值是一个指针及其函数声明的使用;
3)求"指定日期后多少天的具体日期"算法,可以与之前"两个日期相隔多少天"比较。
心得:
1)改进之处:
输入一个时间并未注意各部分数据的取值范围;
进一步将多个模块中要用到的功能独立出一个模块,在实现其他功能时也对该模块加以利用
2)关于设计:
一是存储数据所用的数据结构——结构体,二是整个程序的框架(即提前设计好功能模块),
因为还在学习语法阶段,更多考虑用怎样的算法并如何实现它。
3)关于测试:
对这样实现多种情况下的程序,必须要拿各种测试数据测试后,才能保证正确性
测试路径:一个个输入—>多个输入(循环)—>测试数据放入数组的初始化中
测试数据也要进行一番好的设计
4)改进、设计、测试,本题都提供了很好的例子,可以多多参考练习。