文章目录

  • 万年历简述
  • 代码

万年历简述

万年历——就是输入一个日期可以查询是星期几,这个功能看起来很普通,但是如果用程序时间的话,还是药费一番周折:

  1. 我们需要保存一个固定的日期,存放它是星期几,输入一个自定义的日期,通过二者的日期差推断出输入日是星期几
  2. 我们需要考虑每一年是闰年还是平年,这个关系我们的日期差到底是几。所以需要创建一个返回bool型变量的函数bool isleapyear(int year)
  3. 我们使用的语言是C语言不是Visual Basic。在VB里面是有日期类型(date)的变量的,加减非常方便,但是C里面没有,我们可以通过结构体定义一个
      typedef struct{int year;typedef struct{int year;int month;int day;enum Weekdays weekday;} Date;

将一个时间点的年、月、日、星期建立联系,方便我们后面的输出和查找。

  1. 每个月的天数是不一样的,而这个日期的分布规律又过于复杂,我们不妨设一个数组来存放月份的天数。2月份的天数初始化的时候可以设为28,如果isleapyear(int year)==true,再将2月份天数改为29,否则设为28。
  2. 计算两个日期的日期差,如果两个日期的年份>2,则需要通过闰年判断函数对每个年份判断,并确定应该分别加多少,而对零头(也就是一年中的哪一天),我们需要另外设一个函数int count_days(int *days,Date *datetime);,通过传递days月份天数数组和一个日期,来计算该日期在该年是哪一天。假设参考日期在所在年的天数是day1,所在年天数为year1,输入日期在所在年的天数是day2,所在年天数为year2,两年所隔的年份总天数为是years,则相隔日期Δ\DeltaΔdays=year1-day1+years+day2;
  3. 我们在程序里面设计一个逻辑性变量bool next,每次运行完一个循环都扫描一下逻辑变量的值,如果用户输入1代表继续(其实非零值均可),输入0代表结束,整个过程使用do…whie循环控制,并且在循环体末尾要加上扫描是否继续的选择到next逻辑变量中的语句,即:
do{...
printf("\n是否继续?(是:1,否:0): ")
scanf("%d",&next);
fflush(stdin);//在循环中使用scanf必须要清空输入缓存区,否则执行完1次循环会跳过循环体中的第一个scanf
)while(next);

使用一个判断是否继续的变量可以更好地实现人机交互的功能,同时也可以一次性多次测试代码的正确性。
7. 由于日期差值是负的还是整的关系到我们的计算结果,直接不管正负地模7取余是有问题的,所有我们保存7个参考日期,如果相减可以被7整除就代表是星期几。

代码

#include <stdio.h>
#include <stdbool.h>
#include <malloc.h>
#include <math.h>
#define LEN sizeof(Date)
enum Weekdays{Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
};//定义weekday枚举型变量
typedef struct {int year;int month;int day;enum Weekdays weekday;
}Date;//定义日期的结构体变量
int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};//平年的日期,可以借助modify_year修改
Date refdate[7];//定义7个参考日期,依次为周一到周日
int datedistract(Date date1,Date date2); //日期相减的函数
bool isleapyear(int year);//判断闰年的函数
void modify_days(int *days,int year);//通过闰年对月份日期修改的函数
void findweekday(Date *datetime);
void weekdayprint(enum Weekdays weekday);
int count_days(int *days,Date *datetime); //计算结构体日期变量在一年中处于哪一天
int main()
{printf("************日期计算实验****************\n");bool next;//是否继续do{Date *datetime=malloc(LEN);//定义Date类型的结构体指针datetime,同时开辟一段内存(不开辟内存会使程序崩溃)int i;for(i=0;i<7;i++){refdate[i].year=2018;refdate[i].month=12;refdate[i].day=10+i;}//refdate结构体数组存放了2018/12/20~2018/12/26的7个日期,他们正好是周一到周日 printf("请输入一个日期(year/month/day): ");scanf("%d/%d/%d",&datetime->year,&datetime->month,&datetime->day);printf("该日期所在年份中的天数为%d\t",count_days(days,datetime)); findweekday(datetime);weekdayprint(datetime->weekday);printf("\n是否继续?(是:1,否:0):  ");//是否继续的判断如下scanf("%d",&next); fflush(stdin);//刷新标准输入流,否则循环的时候会跳过第一个scanf } while(next);return 0;
}
bool isleapyear(int year)
{if(year%4==0){if(year%100==0){if(year%400==0)return true;else return false;}else return true;}else return false;
}
//闰年修改函数
void modify_days(int *days,int year)
{if(isleapyear(year)==true)days[1]=29;else days[1]=28;
}
int count_days(int *days,Date *datetime)//将该年各月份日期已经结构体变量录入,计算在该年的天数
{int i,count=0;modify_days(days,datetime->year);for(i=0;i<datetime->month-1;i++)count+=days[i];count+=datetime->day;return count;
}
int datedistract(Date date1,Date date2)
{int year,month,day,count=0;bool cmp;//比较两个日期哪个在前面,方便写循环Date temp;//作为交换变量的中间变量if(date1.year>date2.year)cmp=true;else if(date1.year<date2.year)cmp=false;else if(date1.month>date2.month)cmp=true;else if(date1.month<date2.month)cmp=false;else if(date1.day>date2.day)cmp=true;else cmp=false;if(cmp){temp=date1;date1=date2;date2=temp;}//如果date1在date2后面,则交换二者,保证date1始终比date2小for(year=date1.year;year<date2.year;year++)count+=isleapyear(year)?366:365;//按照是否为闰年书累加count+=count_days(days,&date2)-count_days(days,&date1);//计算零头return abs(count);//返回所差日期
}
void findweekday(Date *datetime)
{int i;for(i=0;i<7;i++){if(datedistract(*datetime,refdate[i])%7==0){datetime->weekday=i;break;}}
}
void weekdayprint(enum Weekdays weekday)
{switch(weekday){case 0:printf("星期一");break;case 1:printf("星期二");break;case 2:printf("星期三");break;case 3:printf("星期四");break;case 4:printf("星期五");break;case 5:printf("星期六");break;case 6:printf("星期日");break;}
}

输出结果如下图,可以多次输入,一次性查找多个日期:

C语言结构体的应用——万年历相关推荐

  1. ARM汇编语言实现peek()_ARM汇编之访问C语言结构体数据

    前言 本文的写作目的在于装逼,没有要产生实际价值的意思. 前几天在做编译器的项目,有一个项目团队成员一直在问我ARM汇编能不能读C语言的结构体.我心想,我这生成ARM汇编的代码是用C++写的呀,又不是 ...

  2. C语言结构体和结构体数组示例 - Win32窗口程序演示

    C语言结构体和结构体数组的使用: /* C结构体和结构体数组示例,by bobo */#include <windows.h>LRESULT CALLBACK WndProc (HWND, ...

  3. C语言结构体-大小,对齐,填充,使用及其他

    C语言结构体-大小,对齐 C语言中的结构体(struct)的定义 在C语言中,最常用的数据结构就是结构体了,结构体也是其它数据结构(比如链表等)的基础,结构体的使用非常简单. 比如,定义一个结构体: ...

  4. 关于c语言结构体偏移的一点思考

    注:此处只是利用了编译器的特性来计算结构体偏移 这句话就一笔带过,说得有点牵强附会.以后有时间自己再详细了解一下编译器的特性... more exceptional c++ 中文版 26页 https ...

  5. C语言结构体指针的使用方法

    1.首先定义一个结构体,给它取别名: typedef struct node{ struct node * next://指向下一节点 int data://数据域 }pnode,*linklist; ...

  6. C语言结构体与联合体

    c语言结构体与联合体 结构类型定义和结构变量说明 一.结构的定义 二.结构类型变量的说明 结构变量的赋值 结构变量的初始化 结构数组 结构指针变量 其访问的一般形式为: (*结构指针变量).成员名 结 ...

  7. C语言结构体对齐的不足

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105065657 C ...

  8. C语言结构体占用内存总结

    C语言结构体占用内存总结 前几天有个小朋友问了我一下,关于C语言结构体占用空间的问题.觉得以后会对小可爱有点帮助,就打算先写一下. struct Test {int a;char b;int c; } ...

  9. 深入解析JNA—模拟C语言结构体

    原帖:http://blog.csdn.net/shendl/article/details/3599849 深入解析JNA-模拟C语言结构体 前言 前几天写<JNA--JNI终结者>一文 ...

最新文章

  1. Object-c实现各种排序算法 (汇总)
  2. 启明云端1.54寸串口屏使用经验分享
  3. OpenGL实现3D魔方游戏源代码
  4. IIS问题:Server Application Error 的解决
  5. python爬取天气预报源代码_python抓取天气并分析 实例源码
  6. 测视力距离5米还是3米_7岁男孩近视猛涨300度!眼科专家提醒:保护孩子视力这一点很关键...
  7. 定个小目标,炒股咯....
  8. 分治-Strassen矩阵乘法
  9. abstract、virtual、override 和 new
  10. Android-Device supports x86,but APK only supports armeabi-v7a,armeabi,x86_64
  11. linux源码中的核心数据结构
  12. 计算机设备运输规范,《电子计算机机房设计规范》GB50174-93
  13. Java-根据经纬度计算距离
  14. 极大似然法(ML)与最大期望法(EM)
  15. win10设备管理没有android,win10电脑不能识别安卓设备怎么解决?
  16. 一篇讲给自己听的k8s网络模型
  17. AJAX框架衣柜内部结构,衣柜内部结构这样布局,解决你家 90% 的收纳难题
  18. Python-数据类型转换
  19. php artisan tanker,Artisan 开发
  20. a as as big rat_亲子阅读《Big,bad bug》大坏虫

热门文章

  1. Gamma阶段第八次scrum meeting
  2. Web框架之Django_01初识(三大主流web框架、Django安装、Django项目创建方式及其相关配置、Django基础三件套:HttpResponse、render、redirect)...
  3. 十二赞日志收集与报警系统一览
  4. Exploit开发系列教程-Mona 2 SEH
  5. 微信小程序笔记六模块化 —— module.exports
  6. POJ 1014 Dividing 背包
  7. python操作mysql数据库的常用方法使用详解
  8. libcstl中的list没法插入自定义数据
  9. Solr入门——安装
  10. POJ 3250 Bad Hair Day【单调队列】