思路
你现在活的天数=你当时出生时到出生那年(可能是闰年)年末的天数+出生那年的下一年到今年上一年的年末(中间这些是完整的年)+今年年初到今天的天数,由这三部分的天数组成。这里我们计算的时候也是将三个部分的天数分别去计算,在后面的变量中,我们用tian1,tian2,tian3分别表示这三部分的天数;
思路实现
一年有十二个月,除了二月份,每一个月的天数都固定(一三五七八十腊,三十一天永不差),而二月份可以通过计算当年是否是闰年去决定它的天数,如果是闰年,二月是29天,如果不是闰年,二月是28天;
我们知道判断某一年是否是闰年有两个方面去考虑:
1、能被4整除并且能被100整除
2、能整除400
两个条件满足其一即可,我们用nian表示年数,tian表示天数,以下是判断某一年是否是闰年,并表示二月天数的程序:
if(((nian%4==0)&&((nian%100)!=0))||(nian % 400 == 0)) //二月天数
{
tian=29;
}
else{
tian=28;
}
第一部分的天数
从你出生到当年年末的天数:这时候可以假设你输入你的生日,某某年某某月某某日,这里假设2002年3月24日(这里需要写一个程序让电脑知道你输入的时间);OK,现在我们可以先把当月剩下的天数算出来(3月整月的天数31天减去已经过去的日子24天)+ 剩下几个月的天数;
因为这里是先要判断输入月数,并且把当月剩下的天数和剩下的月的天数加起来,而且每一个月都有自己固定的天数,思来想去,这里我们用一个switch语句去实现最合适(swith语句:通过判断某个值,进入某个情况,执行语句,并且在不遇到break时,会继续执行下去,直至执行完整个switch语句);这里将nian,yue,ri分别表示你输入的你出生时的年月日,tian1表示从你出生那年到出生那年年末的天数,以下是这部分的程序代码:
//从出生那年到年末的天数
switch(yue)
{
case 1:
tian1=tian1+31;
case 2:
if(((nian%4==0)&&((nian%100)!=0))||(nian % 400 == 0))
{
tian1=tian1+29;
}
else{
tian1=tian1+28;
}
case 3:
tian1=tian1+31;
case 4:
tian1=tian1+30;
case 5:
tian1=tian1+31;
case 6:
tian1=tian1+30;
case 7:
tian1=tian1+31;
case 8:
tian1=tian1+31;
case 9:
tian1=tian1+30;
case 10:
tian1=tian1+31;
case 11:
tian1=tian1+30;
case 12:
tian1=tian1+31;
break;
default:
break;
}
tian1=tian1-ri+1;//
printf("从出生那天到当时年末的天数:%d\n",tian1);
//从你出生当月的整月到剩下的月数的天数相加 减去 出生当月已经过去的天数
//+1的原因是:你出生当日即生活开始的日子,得加一哦
第二部分的天数
出生那年的下一年到生活当年(今年)上一年的年末(中间这些是完整的年):这一部分比较简单,先判断你出生那年和你生活的当年是不是同一年(有时会计算小baby的生活天数);如果不是,就开始判断,如果是平年,天数加365,如果是闰年,天数加366;这里用year,month,day表示输入的当年当月当日(今天)的参量;
这一部分的代码可以展示如下:
//中间这些年的天数相加
//先判断一下查询的日期是不是同一年
if(nian!=year)
{
for(int i=nian+1;i<year;i++)//i才是后面过的每一年,才是要判断的,nian是已经固定的,输入的出生的那年
{
//if(((nian%4==0)&&((nian%100)!=0))||(nian % 400 == 0)) 错误示例,一共才加了一次
if(((i%4==0)&&((i%100)!=0))||(i % 400 == 0))
{
tian2=tian2+366;
}
else
{
tian2=tian2+365;//注意检查,不要写错数值,一直找代码错误
}
}
printf("中间这些年一共过的天数:%d\n",tian2);
}
第三部分的天数
今年年初到今天的天数:我的程序思路是用当年总天数减去当年剩下的天数,在下面程序中,tian3表示第三部分的天数,用year,month,day表示输入的当年当月当日(今天)的参量,
//第三段 算出今年过了多少天
int tian3=0;
switch(month)
{
case 1:
tian3 +=31;
case 2:
tian3 +=28;
if((year%4==0&&year%100!=0)||(year%400==0))
{
tian3+=1;
}
case 3:
tian3+=31;
case 4:
tian3+=30;
case 5:
tian3+=31;
case 6:
tian3+=30;
case 7:
tian3+=31;
case 8:
tian3+=31;
case 9:
tian3+=30;
case 10:
tian3+=31;
case 11:
tian3+=30;
case 12:
tian3+=31;
break;
}
tian3=tian3-day;
if((year%4==0&&year%100!=0)||(year%400==0))
{
tian3=366-tian3;
}
else
{
tian3=365-tian3; //现在今年 年初到今天过了多少天tian3
}
printf("从今年最开始到现在的天数:%d\n",tian3);
剩下要做的就是把三部分的天数加起来,假设总天数用sum表示;
但是这里还遗留了一个小点,就是如果当年的天数正好是出生那年的年份(也就是算小baby的天数)时,按照这种程序思路,会多加了一年的天数,所以我们必须判断年份,减去这一年的天数;如果是平年,就减去365天,如果是闰年,就减去366天;这一部分的代码如下:
if(nian==year)//如果出生那年和计算那年是同一年的话,那么按照这个程序思路就多加了一年,需要减去
{
if((nian%4==0&&nian%100!=0)||(nian%400==0))
{
sum=sum-366;
}
else{
sum=sum-365;
}
}
第三部分的第二种思路:
我们都知道switch里面的case语句进行整数匹配,它可以用来匹配任意整数类型的表达式,只要匹配到,就会一直往下执行,而不会去判断你到底是应该怎么执行;所以在这里我们可以改变swich语句里面的case语句选择的顺序,对应另外一种思路:可以先匹配当月的前一个月,用switch语句把前几个月的总天数加起来,再加上本月已经过去的天数;
这个思路可表示代码如下:
switch(month - 1)
{
case 12: tian3 += 31;
case 11: tian3 += 30;
case 10: tian3 += 31;
case 9: tian3 += 30;
case 8: tian3 += 31;
case 7: tian3 += 31;
case 6: tian3 += 30;
case 5: tian3 += 31;
case 4: tian3 += 30;
case 3: tian3 += 31;
case 2:
tian3 += 28;
//判断是不是闰年
if((year%400 == 0) || (year%4 == 0 && year%100 != 0))
{
tian3 += 1;
}
case 1: tian3 += 31;
break;
default:
break;
}
//还要加上当前月已经过了的日子
tian3 += day;
整体代码实现
#include<stdio.h>
#include<math.h>
//计算从出生日期到今日活了多久
int main()
{
int nian,yue,ri;//出生的年月日
int year,month,day;//当年的年月日
int tian1=0;//注意赋初值,否则会出现乱值
int tian2=0;
int tian3=0;
int sum=0;//总天数
printf("本代码将实现:你从出生到现在一共活了多少天!");
printf("请输入你的出生日期:\n");
scanf("%d %d %d",&nian,&yue,&ri);
printf("请输入今天的日期:\n");
scanf("%d %d %d",&year,&month,&day);
//从出生那年到年末的天数
switch(yue)
{
case 1:
tian1=tian1+31;
case 2:
if(((nian%4==0)&&((nian%100)!=0))||(nian % 400 == 0))
{
tian1=tian1+29;
}
else{
tian1=tian1+28;
}
case 3:
tian1=tian1+31;
case 4:
tian1=tian1+30;
case 5:
tian1=tian1+31;
case 6:
tian1=tian1+30;
case 7:
tian1=tian1+31;
case 8:
tian1=tian1+31;
case 9:
tian1=tian1+30;
case 10:
tian1=tian1+31;
case 11:
tian1=tian1+30;
case 12:
tian1=tian1+31;
break;
default:
break;
}
tian1=tian1-ri+1;
// printf("从出生那天到当时年末的天数:%d\n",tian1);
//中间这些年的天数相加
//先判断一下查询的日期是不是同一年
if(nian!=year)
{
for(int i=nian+1;i<year;i++)//i才是后面过的每一年,才是要判断的,nian是已经固定的,输入的出生的那年
{
//if(((nian%4==0)&&((nian%100)!=0))||(nian % 400 == 0)) 错误示例,一共才加了一次
if(((i%4==0)&&((i%100)!=0))||(i % 400 == 0))
{
tian2=tian2+366;
}
else
{
tian2=tian2+365;//注意检查,不要写错数值,一直找代码错误
}
}
// printf("中间这些年一共过的天数:%d\n",tian2);
}
//第三段 算出今年过了多少天
switch(month)
{
case 1:
tian3 +=31;
case 2:
tian3 +=28;
if((year%4==0&&year%100!=0)||(year%400==0))
{
tian3+=1;
}
case 3:
tian3+=31;
case 4:
tian3+=30;
case 5:
tian3+=31;
case 6:
tian3+=30;
case 7:
tian3+=31;
case 8:
tian3+=31;
case 9:
tian3+=30;
case 10:
tian3+=31;
case 11:
tian3+=30;
case 12:
tian3+=31;
break;
}
tian3=tian3-day;
if((year%4==0&&year%100!=0)||(year%400==0))
{
tian3=366-tian3;
}
else
{
tian3=365-tian3; //现在今年 年初到今天过了多少天tian3
}
// printf("从今年最开始到现在的天数:%d\n",tian3);
sum=tian1+tian2+tian3;//注意上下顺序,注意值的前后出现的顺序
//注意赋值符号==
if(nian==year)//如果出生那年和计算那年是同一年的话,那么按照这个程序思路就多加了一年,需要减去
{
printf("你是今年出生的哦!\n",nian,year);
if((nian%4==0&&nian%100!=0)||(nian%400==0))
{
sum=sum-366;
}
else{
sum=sum-365;
}
}
printf("你已经活了%d天哟!\n",sum);
return 0;
}
实现代码中的错误总结:
1、年月日数值填写错误
2、语句上下顺序错误(语句上下顺序会改变代码执行顺序以至于改变代码执行结果)
3、符号错误(C语言输入数值时&符号经常忘记)
4、赋初值的错误(不能忘记赋初值)
注意:这个代码还需要优化,还有一些小bug,我相信随着后面的学习中我会持续改进这个代码及思路的,争取用更好的算法实现它!
这是我在学C语言中,通过老师讲解和询问同学对自己的学习的一个总结,文中有不对或说法不准确的地方,恳请各位大佬指正!
本人的评论区欢迎大家讨论技术性的问题!