C语言进阶-第15~16讲:结构体应用(玩转日期和时间)

任务和代码:

定义一个表示时间(包括年、月、日、时、分、秒)的结构体,然后完成下面的功能。
提示:将各个功能分别设计成函数实现,在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;
}


运行结果:

C语言进阶-第15~16讲:结构体应用(玩转日期和时间)_第1张图片


知识点总结:

     1)使用了工程中更常用的指向结构体变量的指针;

     2)用指向结构体变量的指针进行函数传参,加深了返回值是一个指针及其函数声明的使用;

     3)求"指定日期后多少天的具体日期"算法,可以与之前"两个日期相隔多少天"比较。


心得:

    1)改进之处:

         输入一个时间并未注意各部分数据的取值范围;

         进一步将多个模块中要用到的功能独立出一个模块,在实现其他功能时也对该模块加以利用

    2)关于设计:

         一是存储数据所用的数据结构——结构体,二是整个程序的框架(即提前设计好功能模块),

         因为还在学习语法阶段,更多考虑用怎样的算法并如何实现它。

    3)关于测试:

         对这样实现多种情况下的程序,必须要拿各种测试数据测试后,才能保证正确性

         测试路径:一个个输入—>多个输入(循环)—>测试数据放入数组的初始化中

         测试数据也要进行一番好的设计

    4)改进、设计、测试,本题都提供了很好的例子,可以多多参考练习。






你可能感兴趣的:(C语言进阶,c语言,应用)