当前位置: 首页 > news >正文

专注软件开发成都seo公司

专注软件开发,成都seo公司,oa软件开发,百度网页广告怎么做目录 Ⅰ. 引入 Ⅱ. 列轮廓 Ⅲ. 功能的实现 构造函数 Print 判断是否相等 | ! ➡️: ➡️!: 判断大小 > | > | < | < ➡️>&#xff1a; ➡️<&#xff1a; ➡️>&#xff1a; ➡️<&#xff1a; 加减天数 | | - | - ➡️&#xff1a;…

目录

Ⅰ. 引入

Ⅱ. 列轮廓

Ⅲ. 功能的实现

构造函数

判断是否相等 == | !=

➡️==:

➡️!=:

判断大小 > | >= | < | <=

➡️>:

➡️<=:

➡️>=:

➡️<:

加减天数 + | += | - | -=

➡️+=:

➡️+:

➡️-:

➡️-=:

自增/自减 ++ | --

➡️前置++

➡️后置++

➡️前置--

➡️后置--

日期减日期

➡️Way1(推荐)

➡️Way2( 这个思路繁杂很多)


Ⅰ. 引入

本篇我们用C++来实现一个日期计算器。

想知道迄今为止你在地球上一共度过了多少天吗?距离寒假还有多少天呢?一百天后会是几月几号呢?

解开这些问题的答案,只需来写一个日期计算器~👻

日期计算器是C++入门以来的第一个小项目,亲自实践一遍,我们在C++上的经验值将⬆️⬆️⬆️

🚩我们将分三步:

Step1:在头文件中把日期类的大体轮廓列出来

Step2:把声明的功能一一实现

Step3:逐个测试。我们写一点,测一点。

这样,就可顺利把日期计算器写出个七七八八。

在遇到较复杂的算法时,我会提供思路。

至于某些锦上添花的功能,我们后续想到了,再添上去。

Ⅱ. 列轮廓

🤔我们先来定义一个日期类,同时看看要实现哪些功能:

#pragma once
#include<iostream>
using namespace std;
​
class Date {
public:Date(int year = 1900, int month = 1, int day = 1);  //构造函数:用于初始化
​void Print();   //打印日期,便于测试
​//功能的具体实现bool operator==(const Date& d);  //判断俩date是否相等bool operator!=(const Date& d);  
​bool operator>(const Date& d);    //date间比较大小bool operator>=(const Date& d);bool operator<(const Date& d);bool operator<=(const Date& d);
​Date operator+(int day);     //加(减)天数,今夕是何年Date& operator+=(int day);Date operator-(int day);Date& operator-=(int day);
​Date& operator++();     //date的自增/自减Date operatoe++(int);Date& operator--();Date operatoe--(int);
​int operator-(const Date& d);  //算两个date间差多少天
​
private:int _year;int _month;int _day;
};

Ⅲ. 功能的实现

构造函数

➡️我们实现一个全缺省的构造函数:

class Date{
public:Date(int year = 1900, int month = 1, int day = 1) {  _year = year;_month = month;_day = day;}private:int _year;int _month;int _day;
}

每次实例化出一个对象,都要调用构造函数,调用频率非常高。

所以,我们干脆就把这短短的几行定义在类里,做内联函数。

❓你可能会疑惑:为啥_year可以直接拿来用,不需要this->year嘛?

后者当然可以写,但没必要。因为我们在使用类的成员函数or成员变量时,this指针会默认加上的。

我们就不用一一手动加啦✌

Print

➡️Print,写在Date.c里:

void Date::Print() {printf("%d-%d-%d\n", _year, _month, _day);
}

❓为啥要加Date::呢?

要知道,类定义了一个全新的作用域。类里类外,是有一层屏障的。

正因为类域的存在,我们不能直接从外部访问类的成员。

因此,把成员函数拿到类外定义时,要指明作用域,即加上Date::

❓我们不是学了cout嘛,为啥不直接cout输出,还得用printf?

这个问题我们先保留着,下一趴再讲。🤪

🔬🧪这俩函数先测试一波:

void Test1() {Date d1(2023, 8, 23);Date d2;d1.Print();d2.Print();
}
int main()
{Test1();return 0;
}

结果:

判断是否相等 == | !=

➡️==:

bool Date::operator==(const Date& d) {return _year == d._year&& _month == d._month&& _day == d._day;
}

➡️!=:

bool Date::operator!=(const Date& d) {return !(*this == d);
}

有没有发现,其实我们只实现了==,

写!=时直接套用了==的功能,这叫做复用。

复用可以减少工作量,提高代码的重用性。

❓为啥只有一个形参?

其实有两个形参:第一个形参是隐形的:this指针。只有第二个形参可见。

“d1!=d2; ” 就相当于在调用函数 “d1.operator!=(d2); ”

此函数的this指针指向d1,形参的d即d2。

🔬🧪测试一下:

void Test2() {Date d1(2023, 8, 23);Date d2(2000, 1, 1);if (d1 != d2) {cout << "unequal"<<endl;}
}
int main()
{//Test1();Test2();return 0;
}

结果:

判断大小 > | >= | < | <=

日期的大小,听着蛮抽象。其实就是日期的先后:2023年1月1日比2000年1月1日要大(后)。

➡️>:

bool Date::operator>(const Date& d) {if (_year > d._year|| _year == d._year && _month > d._month|| _year == d._year && _month == d._month && _day > d._day) {return true;}else {return false;}
}

这种算法的思路是:

写完>,先不急着写<,因为>的对立面是<=,那我们可以把这段代码复用到<=👻

➡️<=:

bool Date::operator<=(const Date& d) {return !(*this > d);
}

➡️>=:

bool Date::operator>=(const Date& d) {return *this > d || *this == d;
}

➡️<:

bool Date::operator<(const Date& d) {return !(*this >= d);
}

🔬🧪测试一下:

void Test3() {Date d1(2023, 8, 23);Date d2(2000, 1, 1);cout << (d1 > d2) << endl;cout << (d1 <= d2)<<endl;
}
​
int main()
{//Test1();//Test2();Test3();return 0;
}

结果:

加减天数 + | += | - | -=

➡️+=:

日期加天数要考虑进位的问题。我举个例子,先顺下思路:

2023-12-21往后推40天

61相比当月的31已经溢出了,

怎么判断是否溢出呢?

写个函数GetMonthDay(),取到每月的天数进行比对

GetMonthDay()实现如下:

int Date::GetMonthDay(int year, int month) {int days[13]={ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int ret = days[month];
​//考虑闰年的2月是29天的情况//闰年,要么能被4整除&&不能被100~;要么能被400整除
​if (month == 2&& (year % 4 == 0 && year % 100 == 0|| year % 400 == 0)) {ret += 1;}
​return ret;
}

☑️operator+=实现如下:

Date& Date::operator+=(int day) {_day += day;int MaxDay = GetMonthDay(_year, _month);
​while (_day > MaxDay) {_day -= MaxDay;_month++;
​//防止month溢出if (_month == 13) {_month = 1;_year++;}
​MaxDay = GetMonthDay(_year, _month);}
​return *this;
}

➡️+:

有了+=,+就直接复用~👻

Date Date::operator+(int day) {Date ret = *this;ret += day;return ret;
}

🤔❓思考:为啥不能这样写?

Date Date::operator+(int day) {Date ret = *this+day;return ret;
}

因为:

➡️-:

加要考虑进位,减要考虑借位。

举例:2023-3-2 往前40天

思路:

🌀你可能有点晕:-38为什么要借2月的28?

可以把2023-3-2往前40天视为2023-3-0往前38天。

此时要借位,我们没法从3月借,因为它是空的。只能从2月借。

☑️实现:

Date& Date::operator-=(int day) {_day -= day;
​while (_day <= 0) {_month--;
​if (_month == 0) {_month = 12;_year--;}int BorrowDay = GetMonthDay(_year, _month);_day += BorrowDay;}
​return *this;
}

➡️-=:

同样,复用🥰

Date Date::operator-(int day) {Date ret = *this;ret -= day;return ret;
}

🔬🧪测试一下:

void Test4() {Date d1(2023, 12, 21);   //+  +=Date d2(d1);(d1 + 40).Print();(d2 += 700).Print();Date d3(d1);   //-  -=Date d4(2023, 3, 2);(d3 -= 400).Print();(d4 - 40).Print();
}

结果:

自增/自减 ++ | --

我们用参数占位来区分前置/后置++:

前置:operator++( )

后置:operator++( int )

❓前置++和后置++的区别是什么?

这俩都能实现自增,但返回值不同。

前置:++d; 先加加,再使用。返回的是加加的值。

后置:d++;先使用,再加加。返回的是加加的值。

假设d=0,d++:返回1,d=1

++d:返回0,同时实现自增,d=1

所以说,后置加加是不能引用返回的。而前置可以。

➡️前置++

Date& Date::operator++() {return *this += 1;
}

➡️后置++

Date Date::operator++(int) {Date ret = *this;*this += 1;return ret;
}

➡️前置--

Date& Date::operator--() {return *this -= 1;
}

➡️后置--

Date Date::operator--(int) {Date ret = *this;*this -= 1;return ret;
}

🔬🧪测试一下:

void Test5() {Date d1(2023, 1, 1);   //++Date d2(d1);(++d1).Print();(d2++).Print();
​Date d3(2023, 1, 1);  //--Date d4(d3);(--d3).Print();(d4--).Print();
}

结果:

日期减日期

距离新年还有多少天呢?

Date(2024,1,1) - Date(2023,8,24) =❓天

➡️Way1(推荐)

我们刚刚不是写了好多功能嘛,复用起来~👻

实现:

int Date::operator-(const Date& d) {Date More = *this;  //先把date标个大小Date Less = d;
​if (Less > More) {More=d;Less=*this;}
​int count = 0;    //用计数法算差值while (Less<More) {Less++;    //复用🥰👻count++;}
​int flag = 1;      //我们不知道是大-小or小-大if (More == d) {    //为了区分结果的正负,引入flagflag = -1;  }
​return count*flag;
}

这种方法虽然思路简单,但是深度复用了代码,效率会下降。

➡️Way2( 这个思路繁杂很多)

(❗这个方法效率会⬆️,但是较复杂,可略过不看!)

Q: 2023-2-13到2024-1-15,要过多少天?、

思路:

Step1:把月、日转化成总天数;

Step2:年与年之间相减,天与天之间相减

Step3:全化成天

实现:

Step1 我们先写一个把月、日转换成天数的函数ConverttoDay( )

如下:

int Date::ConverttoDay(int year, int month, int day) {int MonthtoDay = 0;month -= 1;
​while (month) {MonthtoDay += GetMonthDay(year, month);month--;}
​int ret = MonthtoDay + day;return ret;
}

Step2 实现operator-函数

int Date::operator-(const Date& d) {//先判断日期的大小Date BigDate = *this;Date SmallDate = d;
​if (BigDate < SmallDate) {Date tmp = SmallDate;SmallDate = BigDate;BigDate = tmp;}
​//把月、日都转换成天int BigDay = ConverttoDay(BigDate._year, BigDate._month, BigDate. _day);int SmallDay = ConverttoDay(SmallDate._year, SmallDate._month, SmallDate._day);
​
​int RetofDay = BigDay - SmallDay;  //天之间相减,大天-小天int BigYear = BigDate._year;int SmallYear = SmallDate._year;
​//年之间相减,大年-小年int CountDay = 0;
​while (SmallYear < BigYear) {CountDay += 365;
​if (SmallYear % 4 == 0 && SmallYear % 100 != 0  //考虑闰年|| SmallYear % 400 == 0) {CountDay += 1;}
​SmallYear++;}
​//把两者的天数合一int ret = RetofDay + CountDay;
​int flag = 1;if (*this == BigDate) {flag = -1;}
​return flag * ret;
}

🔬🧪测试一下:

void Test6() {Date d1(2023, 8, 24);Date d2(2024, 1, 1);
​printf("%d\n", d2 - d1);
}

结果:


OK, 到这我们的日期计算器已经完成啦~🥰👻

http://www.mnyf.cn/news/41454.html

相关文章:

  • 网页作业班级网站怎么做百度推广方案怎么写
  • 做的好的手机网站有哪些湖北网站建设制作
  • 单页导航网站模板网络营销的基本特征有哪七个
  • 深圳网站如何制作网络销售技巧和话术
  • 洛阳做网站公司在哪企业网站建设方案论文
  • android 做分享的网站新品上市怎么推广词
  • 青岛网站制作网页搜索引擎优化的方法和技巧
  • 密云做网站的深圳关键词优化软件
  • 刷单做任务的网站郑州企业网站seo
  • wordpress图文直播seo的英文全称是什么
  • 系统网站建设需求分析兰州网络推广技术
  • 如何做一份网站推广方案新闻稿发布平台
  • 邢台网站关键词优化河北百度seo
  • 做h5免费的网站有百度竞价一个月5000够吗
  • 关于党建微网站建设经费的报告常见的微信营销方式有哪些
  • 购物网站怎么建立cilimao磁力猫最新版地址
  • 怎么在微信公众号上做网站免费seo网站推广在线观看
  • 学做美食网站哪个好旅游网站网页设计
  • 贵阳网站建设多钱钱重庆网站建设维护
  • 网站的登录注册页面怎么做的本周新闻热点事件
  • 网站内链符号网站客服
  • 上海网站建设咨如何建立个人网站的步骤
  • 查看一个网站的备案seo排名查询软件
  • 微信做淘宝客 网站打不开了seo学习网站
  • 专门做高仿的网站品牌推广经典案例
  • 页面网站缓存如何做百度推广平台登陆
  • 定制网站建设服务器seo引擎优化
  • 望京 网站开发短视频精准获客系统
  • 做老师讲课视频的教育网站百度联盟注册
  • 外汇申报在哪个网站上做上海疫情突然消失的原因