万年历_二级指针(存在部分bug以及不完善之处)

#include<STDIO.H>
#include<STDLIB.H>
#include<MALLOC.H>
#include <conio.h>
#define LEFT       75
#define RIGHT      77
#define DOWN       80
#define UP         72

typedef struct Mon{
	int month;
	int days;
}*Pmonth;
/*Create struct of Date*/
typedef struct Date{
	int year ;
	Pmonth pmon;
}*Pdate;

/*Judge if the leap year*/
bool If_leap_year(Pdate Ptr){

	if(Ptr->year%4==0 && Ptr->year%100!=0 || Ptr->year%400==0){
		return true ;
	}
	else
		return false ;
}

/*declare the function Testing_input()*/
bool Testing_input(Pdate) ;

void Month_days(Pdate Ptr){
		switch(Ptr->pmon->month){
	case 1: Ptr->pmon->days=31;break;
	case 2: 	if (If_leap_year(Ptr)){
		Ptr->pmon->days=29;
				}
		else{
			Ptr->pmon->days=28;
		}
		break;
	case 3: Ptr->pmon->days=31;break;
	case 4: Ptr->pmon->days=30;break;
	case 5: Ptr->pmon->days=31;break;
	case 6: Ptr->pmon->days=30;break;
	case 7: Ptr->pmon->days=31;break;
	case 8: Ptr->pmon->days=31;break;
	case 9: Ptr->pmon->days=30;break;
	case 10: Ptr->pmon->days=31;break;
	case 11: Ptr->pmon->days=30;break;
	case 12: Ptr->pmon->days=31;break;
	}
}
/*Input one date*/
Pdate Input_date(){
	Pdate Ptr ;
	Ptr = (Pdate)malloc(sizeof(struct Date));
	Ptr->pmon = (Pmonth)malloc(sizeof(struct Mon));
	if (!Ptr)
	{
		printf("Error!Fail to create!");
	}
	
	scanf("%d %d",&Ptr->year,&Ptr->pmon->month);
	Month_days(Ptr);

	if (Testing_input(Ptr))
	{
		return Ptr ;
	}
	else
	return NULL;
}

/*Testing the format of the date*/
bool Testing_input(Pdate Ptr){
	bool Flag;
	if((Ptr->year)<=3000 && (Ptr->year)>0){
		Flag = true ;
	}
	else{
		Flag = false ;
		printf("Please Input Year between 0~3000\n");
	}

	return Flag ;
}

int Caculate_day(Pdate Ptr){
	int day;
	int Jan=31,Feb,Mar=31,Apr=30,May=31,Jun=30,Jul=31,Aug=31,Sept=30,Oct=31,Nov=30,Dec=31 ;
	if (If_leap_year(Ptr))
	{
		Feb = 29 ;

	}
	else {
		Feb = 28 ;
	}
	switch(Ptr->pmon->month){
	case 1: day = 1;break;
	case 2: day = 1+Jan;break;
	case 3: day =1+ Jan +Feb ;break;
	case 4: day =1+ Jan +Feb+Mar;break;
	case 5: day =1+ Jan +Feb+Mar +Apr;break;
	case 6: day = 1+ Jan +Feb+Mar +Apr+May;break;
	case 7: day = 1+ Jan +Feb+Mar +Apr+May+Jun;break;
	case 8: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul;break;
	case 9:  day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug;break;
	case 10: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug+Sept;break;
	case 11: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug+Sept+Oct;break;
	case 12: day = 1+ Jan +Feb+Mar +Apr+May+Jun+Jul+Aug+Sept+Oct+Nov;break;		
	}

	return day;

}

void Output_Date(Pdate Ptr){

	int i,j;
	int count=1;

	int inital=(Ptr->year-1+(Ptr->year-1)/4-(Ptr->year-1)/100+(Ptr->year-1)/400+1)%7;

	int result = (Caculate_day(Ptr)%7 + inital -1)%7;
	
	printf("%25d-%d\n",Ptr->year,Ptr->pmon->month);
	printf("    Sun    Mon    Tue    Wed    Thur    Fri    Sat     \n") ;
	for (i=0;i<6;i++){
		for (j=0;j<7;j++)
		{
			Month_days(Ptr);
			if(i==0 && j<result||count>Ptr->pmon->days) printf("       ");
			else{
				printf("%7d",count) ;
				count++;
			}
		}
		printf("\n");
	}
}

/*result=(year-1+(year-1)/4-(year-1)/100+(year-1)/400+days)%7;*/

void Which_key(Pdate ptr){
		char ch = getch();
		if(ch==-32)
		ch=getch(); 

		switch(ch) {
		case UP:
			if(ptr->pmon->month==12){
				ptr->pmon->month=1;
				ptr->year++;
			}
			else
			(ptr->pmon->month)++;
			break;
		case DOWN:
			if(ptr->pmon->month==1){
				ptr->pmon->month=12;
				ptr->year--;
			}
			else
			(ptr->pmon->month)--;;break;
		case LEFT:
			if(ptr->year==1)
				ptr->year = 3000;
			else
			 (ptr->year)--;break;
		case RIGHT:
			if(ptr->year==3000)
				ptr->year=1;
			else
				(ptr->year)++;break;
		}
}
int main(){
	
	Pdate ptr = Input_date();
	while(1){
	if(ptr){
	Output_Date(ptr);	
	}
	Which_key(ptr);
	}
	return 0;
}
</pre><pre class="objc" name="code" snippet_file_name="blog_20150424_3_2034350" code_snippet_id="652457"> 
 
时间仓促,程序存在一些需要完善的地方,基本上实现了万年历的功能,但是对于输入的处理仍然没有做相应的处理,不是很符合软件工程的设计思想。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于单片机、LED1602和DS1302的万年历代码,你可以参考一下: ```c #include <reg52.h> //头文件,引用51单片机的寄存器定义 sbit SCL=P3^6; //定义DS1302通信引脚 sbit SDA=P3^4; sbit RST=P3^5; void delay_us(unsigned char i) //延时函数,i为延时时间 { while(i--); } void delay_ms(unsigned int i) { unsigned char j,k; for(k=0;k<i;k++) for(j=0;j<120;j++); } void ds1302_writebyte(unsigned char dat) //向DS1302写入一个字节 { unsigned char i; for(i=0;i<8;i++) { SDA=dat&0x01; //先送最低位 dat>>=1; //右移一位,将次低位变为最低位 SCL=0; //拉低时钟线 delay_us(1); //延时1us SCL=1; //拉高时钟线 delay_us(1); } } unsigned char ds1302_readbyte() //从DS1302读取一个字节 { unsigned char i,dat=0; for(i=0;i<8;i++) { dat>>=1; SCL=0; delay_us(1); if(SDA) //如果数据线为高电平,dat的最高位为1 dat|=0x80; SCL=1; delay_us(1); } return dat; } void ds1302_write(unsigned char addr,unsigned char dat) //向DS1302写入一个字节 { RST=0; delay_us(2); RST=1; ds1302_writebyte(addr); ds1302_writebyte(dat); RST=0; } unsigned char ds1302_read(unsigned char addr) //从DS1302读取一个字节 { unsigned char dat; RST=0; delay_us(2); RST=1; ds1302_writebyte(addr); dat=ds1302_readbyte(); RST=0; return dat; } void init_ds1302() //初始化DS1302 { ds1302_write(0x8e,0x00); //关闭写保护 ds1302_write(0x80,0x01); //控制寄存器,禁止写保护 ds1302_write(0x81,0x00); //秒归零 ds1302_write(0x84,0x00); //日归零 ds1302_write(0x8e,0x80); //打开写保护 } void lcd_write_cmd(unsigned char cmd) //向LCD发送指令 { P2=cmd; P1&=0xf8; P1|=0x04; delay_ms(1); P1&=0xfb; delay_ms(1); } void lcd_write_data(unsigned char dat) //向LCD发送数据 { P2=dat; P1&=0xf8; P1|=0x05; delay_ms(1); P1&=0xfb; delay_ms(1); } void lcd_init() //LCD初始化 { lcd_write_cmd(0x38); //设置8位数据总线,2行显示,5x7点阵字符 lcd_write_cmd(0x0c); //显示器开,光标关,光标移动关 lcd_write_cmd(0x06); //字符输入时,光标右移,整屏不移 lcd_write_cmd(0x01); //清屏 } void lcd_display(unsigned char *p) //显示字符函数 { unsigned char i; lcd_write_cmd(0x80); for(i=0;i<16;i++) { if(*p=='\0') break; lcd_write_data(*p++); } lcd_write_cmd(0x80+0x40); for(i=0;i<16;i++) { if(*p=='\0') break; lcd_write_data(*p++); } } void main() { unsigned char date[17]; unsigned char year,month,day,week,hour,minute,second; lcd_init(); init_ds1302(); while(1) { second=ds1302_read(0x81); //读取秒 minute=ds1302_read(0x83); //读取分 hour=ds1302_read(0x85); //读取时 week=ds1302_read(0x86); //读取星期 day=ds1302_read(0x87); //读取日 month=ds1302_read(0x88); //读取月 year=ds1302_read(0x89); //读取年 date[0]=(year/10)+'0'; //转换为字符 date[1]=(year%10)+'0'; date[2]='-'; date[3]=(month/10)+'0'; date[4]=(month%10)+'0'; date[5]='-'; date[6]=(day/10)+'0'; date[7]=(day%10)+'0'; date[8]=' '; date[9]=(week%10)+'0'; date[10]=' '; date[11]=(hour/10)+'0'; date[12]=(hour%10)+'0'; date[13]=':'; date[14]=(minute/10)+'0'; date[15]=(minute%10)+'0'; date[16]='\0'; lcd_display(date); //显示日期时间 } } ``` 注意:以上代码只是一个简单的示例,真实的万年历代码要根据需要进行修改和完善
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值