基于C++實(shí)現(xiàn)簡(jiǎn)單的日期計(jì)算機(jī)
引言
我們?nèi)粘I钪锌赡軙?huì)有一個(gè)煩惱。
今天幾月幾號(hào)?過(guò)n天后又是幾月幾號(hào)?某年某月某天和x年x月x天相差幾天?你和男/女朋友的相識(shí)了幾天?等等。這些問(wèn)題好麻煩,我不想去算,所以我們的日期計(jì)算機(jī)也就油然而生了。
頭文件的準(zhǔn)備
頭文件的聲明代碼:
#pragma once
#include<iostream>
#inclu<assert.h>
using namespace std;
class Date
{
public:
// 獲取某年某月的天數(shù)
int GetMonthDay(int year, int month)
{
static int days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30,31 };
int day = days[month];
if (month == 2 &&
(year & 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
day += 1;
}
return day;
}
//打印函數(shù)
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
// 全缺省的構(gòu)造函數(shù)
Date(int year = 1900, int month = 1, int day = 1);
// 拷貝構(gòu)造函數(shù)
// d2(d1)
Date(const Date& d);
// 賦值運(yùn)算符重載
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d);
// 析構(gòu)函數(shù)
~Date();
// 日期+=天數(shù)
Date& operator+=(int day);
// 日期+天數(shù)
Date operator+(int day);
// 日期-天數(shù)
Date operator-(int day);
// 日期-=天數(shù)
Date& operator-=(int day);
// 前置++
Date& operator++();
// 后置++
Date operator++(int);
// 后置--
Date operator--(int);
// 前置--
Date& operator--();
// >運(yùn)算符重載
bool operator>(const Date& d);
// ==運(yùn)算符重載
bool operator==(const Date& d);
// >=運(yùn)算符重載
bool operator >= (const Date& d);
// <運(yùn)算符重載
bool operator < (const Date& d);
// <=運(yùn)算符重載
bool operator <= (const Date& d);
// !=運(yùn)算符重載
bool operator != (const Date& d);
// 日期-日期 返回天數(shù)
int operator-(const Date& d);
private:
int _year;
int _month;
int _day;
};
函數(shù)代碼的實(shí)現(xiàn)
1.某年某月天數(shù)的獲取
第一個(gè)函數(shù),我們定義在了頭文件中
// 獲取某年某月的天數(shù)
int GetMonthDay(int year, int month)
{
assert(month > 0 && month < 13);
static int DayA[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30,31 };
int day = DayA[month];
if (month == 2 &&
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
day += 1;
}
return day;
}
這里我們直接建立一個(gè)數(shù)組,存儲(chǔ)的是每月的天數(shù)。
第一個(gè)我們存儲(chǔ)為0,畢竟第一個(gè)月我們沒(méi)有經(jīng)歷滿。
這里的數(shù)組我們前邊加上了static,使其成為了全局變量。這里設(shè)置為全局變量是為了方便后邊的使用/調(diào)用。
不要忽略了這里閏年的判定,最后返回我們的天數(shù)
2.全缺省的構(gòu)造函數(shù)
Date::Date(int year,int month,int day)
{
year = _year;
month = _month;
day = _day;
}
這個(gè)函數(shù)就比較簡(jiǎn)單了,就是賦值。
值得注意的是:這里是源文件,我們?cè)陬^文件聲明是已經(jīng)使用了缺省參數(shù),所以在源文件中就不需要使用了。
3.拷貝構(gòu)造函數(shù)
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
這個(gè)函數(shù)也比較簡(jiǎn)單,我們這里利用了this指針,所以傳參只需要傳遞一個(gè)就可以了。也不過(guò)多講解了。
4.七個(gè)運(yùn)算符的重載
首先是==的重載
bool Date::operator==(const Date& d)
{
return _year == d._year &&
_month == d._month &&
_day == d._day;
}
然后再寫(xiě)一個(gè) < 的重載
bool Date::operator<(const Date& d)
{
if (_year < d._year)
{
return true;
}
else if (_year == d._year)
{
if (_month < d._month)
return true;
else if (_month == d._month)
{
if (_day < d._day)
{
return true;
}
}
}
return false;
}寫(xiě)完這兩個(gè)后,我們后邊其他的重載就好寫(xiě)了。
這里我們不需要再去寫(xiě)這種麻煩的代碼,我們偷個(gè)懶,轉(zhuǎn)換一下思路。利用前邊這兩個(gè)去寫(xiě)其他的重載函數(shù)
小于等于就是符合小于的同時(shí)也符合等于
bool Date::operator<=(const Date& d)
{
return *this < d && *this == d;
}
大于就是不是小于等于
bool Date::operator>(const Date& d)
{
return !(*this <= d);
}
大于等于就是不是小于
bool Date::operator>=(const Date& d)
{
return !(*this < d);
}
不等于就是不是等于就可以
bool Date::operator!=(const Date& d)
{
return !(*this == d);
}
賦值運(yùn)算符重載
Date& Date::operator=(const Date& d)
{
if (*this != d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
這個(gè)我們?cè)谥耙仓v解過(guò),就不過(guò)多敘述了
5.四個(gè)日期計(jì)算函數(shù)
第一個(gè):月份日期增加天數(shù)
Date& Date::operator+=(int day)
{
_day +=day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
++_month;
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
首先先獲取天數(shù)
如果天數(shù)大于月份的天數(shù),我們就減去當(dāng)前月份的天數(shù),然后讓月份加一。如果月份大于13了,我們就讓年去加一。
寫(xiě)完+=,那么+就會(huì)好寫(xiě)很多
Date Date::operator+(int day)
{
Date ret = *this;
ret += day;
return ret;
}
這里我們也用到了+=的重載。
但這兩個(gè)都是用來(lái)加天數(shù)的,兩者有什么不同呢?
首先呢,第一個(gè)重載的是運(yùn)算符+=的重載,他們的本質(zhì)是在原有的基礎(chǔ)上進(jìn)行改變,改變了*this指針的值
舉個(gè)例子
int main()
{
Date d1(2024, 4, 24);
d1 += 3;//這里的d1應(yīng)該是2024/4/27
d1.Print();
return 0;
}
利用+=我們改變了d1原本的數(shù)值
再看一看+

雖然d1加了3,但是并沒(méi)有改變d1原本的數(shù)值
總結(jié):
- Date& Date::operator+=(int day) 他的返回類(lèi)型是Date的引用們可以進(jìn)行鏈?zhǔn)讲僮鳎{(diào)用+=,是在原有的基礎(chǔ)上進(jìn)行增加天數(shù),會(huì)改變?cè)凶兞康臄?shù)值。
- Date Date::operator+(int day) 他的返回類(lèi)型是一個(gè)新的Date,需要去利用變量去接受。調(diào)用+,返還的對(duì)象實(shí)在原有的基礎(chǔ)上進(jìn)行增加得到結(jié)果,不會(huì)改變?cè)凶兞康臄?shù)值
那么問(wèn)題又來(lái)了?
我這里顯示寫(xiě)出+=,然后再+中去調(diào)用+=。
那么如果我們先寫(xiě)出+后,再重在+=中去調(diào)用+會(huì)怎么樣呢???
這里就直接說(shuō)結(jié)論了
不論是先寫(xiě)+=再寫(xiě)+,還是先寫(xiě)+再寫(xiě)+=,結(jié)果都是一樣的,但是唯一不同的就是代碼的書(shū)寫(xiě)量以及效率的高低。在這里我比較推薦我的寫(xiě)法,先寫(xiě)+=,再寫(xiě)+會(huì)提高一定的效率。
寫(xiě)完+有關(guān)的,我們開(kāi)始寫(xiě)-有關(guān)的
接下來(lái)是月份日期的減少
Date& Date::operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
--_month;
if (_month == 0)
{
--_year;
_month = 12;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
Date Date::operator-(int day)
{
Date tmp = *this;
tmp -= day;
return tmp;
}6.前置/后置的加加減減
這里需要注意的是,為了區(qū)分時(shí)前置和后置的區(qū)別,我們?cè)趥鲄r(shí)需要加入一個(gè)int
加入int參數(shù)的就是后置++
這里代碼如下:
Date& Date::operator++()
{
_day += 1;
return *this;
}
Date Date::operator++(int)
{
Date tmp(*this);
_day += 1;
return tmp;
}
Date& Date::operator--()
{
_day -= 1;
return *this;
}
Date Date::operator--(int)
{
Date tmp(*this);
_day -= 1;
return tmp;
}
既然是加加就是day加一,這樣的話我們也利用前邊思路想法,前置我們利用引用去寫(xiě),而后置我們不用引用,利用前邊的運(yùn)算符重載去寫(xiě)
7.計(jì)算兩個(gè)日期之間的天數(shù)值
int Date::operator-(const Date& d)
{
int flag = 1;
Date max = *this;
Date min = d;
if (*this < d)
{
int flag = -1;
max = d;
min = *this;
}
int n = 0;
while (min != max)
{
++min;
++n;
}
return n * flag;
}這個(gè)函數(shù)的邏輯也利用了假設(shè)法,其思路則是確定好大的日期后,讓小的日期不斷增加然后直至與大的日期相同。
講解:
第一個(gè)點(diǎn)是確確定日期的大小。我們讓max確保成為大日期,min確保成為小日期,這里就利用了假設(shè)法,設(shè)置完后,利用if語(yǔ)句,確保我們的判斷是正確的,如果不正確就進(jìn)行反轉(zhuǎn),并讓flag成為-1。
第二個(gè)點(diǎn)就是計(jì)算兩者之間差值的天數(shù)。我們通過(guò)循環(huán),每次都讓min不斷增加,同時(shí)也見(jiàn)建立一個(gè)變量n,讓它隨著min增加,從而記錄下兩者之間的差值天數(shù),最后n就是兩者之間的差值。
第三個(gè)點(diǎn)就是返回值。我們這里的返回值最后需要乘上flag,其原因是,我們一開(kāi)始我們讓this指針為大日期,如果不對(duì)的話,就說(shuō)明this指針的日期小,所以?xún)烧咧g差值就是負(fù)的。
以上就是基于C++實(shí)現(xiàn)簡(jiǎn)單的日期計(jì)算機(jī)的詳細(xì)內(nèi)容,更多關(guān)于C++日期計(jì)算機(jī)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的方法
這篇文章主要介紹了C++中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
Qt中Tab與Tree組件實(shí)現(xiàn)分頁(yè)菜單
本文主要介紹tabWidget選擇夾組件與TreeWidget樹(shù)形選擇組件的常用方法及靈活運(yùn)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12
使用C語(yǔ)言詳解霍夫曼樹(shù)數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了使用C語(yǔ)言詳解霍夫曼樹(shù)數(shù)據(jù)結(jié)構(gòu),包括一道AMC相關(guān)的例題演示需要的朋友可以參考下2015-08-08
QT實(shí)現(xiàn)年會(huì)抽獎(jiǎng)小軟件的示例代碼
本文主要介紹了QT實(shí)現(xiàn)年會(huì)抽獎(jiǎng)小軟件的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
C語(yǔ)言實(shí)現(xiàn)的一個(gè)萬(wàn)年歷小程序
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)的一個(gè)萬(wàn)年歷小程序,具有一定的參考價(jià)值,做C語(yǔ)言日期計(jì)算的朋友可以參考下2014-07-07
深入學(xué)習(xí)C語(yǔ)言中常見(jiàn)的八大排序
排序編程中非?;A(chǔ)的的理論方法,雖然排序的方法多,但是理解起來(lái)并不難,它是最基本的,初學(xué)者一定要掌握的東西。本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值2021-11-11
在C/C++與Python之間實(shí)現(xiàn)通信的常見(jiàn)方法
在C/C++與Python之間實(shí)現(xiàn)通信的方式有很多,本文給大家介紹了一些常見(jiàn)的方法,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-12-12

