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

江西师范大学两学一做专题网站百度手机卫士下载安装

江西师范大学两学一做专题网站,百度手机卫士下载安装,律师做网站推广有用吗,开源微信小程序商城目录 日期天数 需要考虑的几个问题 1.天数加在日上,有可能会溢出,需要进位 2.对月进位,也有可能导致月会溢出,需要进位 3.对年进位,需要考虑是否为闰年 代码设计 取得指定月的天数GetMonthDay函数 方法1:if判断或switch/case 方法2:查表 版本1 版本2 operator 初始…

目录

日期+天数

需要考虑的几个问题

1.天数加在日上,有可能会溢出,需要进位

2.对月进位,也有可能导致月会溢出,需要进位

3.对年进位,需要考虑是否为闰年

代码设计

取得指定月的天数GetMonthDay函数

方法1:if判断或switch/case

方法2:查表

版本1

版本2

operator+

初始化临时对象

进位的处理

完整代码

测试代码

提问

operator+=

完整代码

测试代码

代码复用

1.+复用+=

2.+=复用+

提问

+复用+=调用拷贝构造函数次数如下:

+=复用+调用拷贝构造函数次数如下:

练习


日期+天数

日期+天数:显然需要重载"+",操作:?年?月?日+天数==?年?月?日

需要考虑的几个问题

1.天数加在日上,有可能会溢出,需要进位

2.对月进位,也有可能导致月会溢出,需要进位

3.对年进位,需要考虑是否为闰年

闰年判断参见15.【C语言】初识操作符 下文章

口诀:四年一闰,百年不闰,四百年又闰

if ((year%4==0 && year%100!=0) || (year%400==0))
{//do_something
}

代码设计

取得指定月的天数GetMonthDay函数

天数加在日上,有可能会溢出,需要进位则需要考虑每一个月最多多少天,而且二月份比较特殊(闰年2月有29天,非闰年2月有28天),可以写一个函数来取得每个月的天数

方法1:if判断或switch/case
if (month==1)
{//......
}
else if (month==2)
{//......
}
else if (month==3)
{//......
}
//.......
else
{//......
}

或者使用switch/case

switch (month)
{case 1:case 2://......case 3:
}

无论使用if还是switch/case,代码冗长,可读性差

方法2:查表

这个思想其实是哈希表思想

int day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//默认2月是28天,之后单独判断

(注:day[0]可以为任何数,仅起到占位的作用)

使用下标访问的方法:day[month]来取得指定月的天数

版本1
int GetMonthDay(int year,int month)
{int day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//默认2月是28天,之后单独判断if (((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) && month == 2){return 29;}return day[month];
}

提问:版本1代码有没有可以优化的地方?

答:

优化1:day数组为局部数组,每次调用该函数,程序都会创建day数组,如果多次调用,该步骤会消耗大量时间,可以尝试使用全局数组或者将数组放到静态区上

优化2:if判断的改进

可以利用短路运算的特点,将第二个条件month==2前置,月份不为2就不判断是否为闰年,节省时间

版本2
int GetMonthDay(int year,int month)//可以不使用引用返回
{//数组放到静态区上,只创建一次static int day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//默认2月是28天,之后单独判断if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return day[month];
}

operator+

算法:天满了向月进位,月满了向年进位.显然需要使用循环

要点:

1.先加到天上,再考虑进位的问题

2.operator+是不能改变原对象的,需要使用临时对象tmp,一旦使用临时对象tmp就不能引用返回,只能传值返回(避免传引用返回错误,牺牲一点时间)

3.区分operator+和operator+=

初始化临时对象

可以使用构造函数来初始化tmp,如下:

Date Date::operator+(int day)
{Date tmp(*this);tmp._day += day;//......
}
进位的处理
while (tmp._day > GetMonthDay(tmp._year,tmp._month))
{tmp._day -= GetMonthDay(tmp._year,tmp._month);tmp._month++;if (_month == 13){tmp._year++;tmp._month = 1;}
}
完整代码
Date Date::operator+(int day)
{Date tmp(*this);tmp._day += day;while (tmp._day > GetMonthDay(tmp._year,tmp._month)){tmp._day -= GetMonthDay(tmp._year,tmp._month);tmp._month++;if (_month == 13){tmp._year++;tmp._month = 1;}}return tmp;//注意返回的不是*this!
}
测试代码
#include "Date.h"
int main()
{Date d1(2025, 3, 25);Date d2=d1 + 100;d2.Print();return 0;
}

运行结果:

提问

Date d2=d1 + 100;是初始化还是赋值?

回顾CD17.【C++ Dev】类和对象(8):赋值运算符文章的知识点:

1.赋值运算符重载:已经存在的两个对象之间的拷贝(如d3 = d1)

2.构造函数:用一个已经存在的对象去初始化另一个对象

显然Date d2=d1 + 100是构造函数执行的,因此为初始化

也可以手动打印测试信息:

修改构造函数和拷贝构造函数:

Date::Date(int year , int month, int day)
{cout << this <<" Date::Date(int year , int month, int day)" << endl;_year = year;_month = month;_day = day;
}Date::Date(const Date& x)
{cout << this<< " Date::Date(const Date& x)" << endl;_year = x._year;_month = x._month;_day = x._day;
}

调用哪个函数就打印哪个函数的信息

测试以下代码:

#include "Date.h"
int main()
{Date d1(2025, 3, 25);cout << "d1 address:"<< & d1 << endl;Date d2 = d1 + 100;cout <<"d2 address:"<< &d2 << endl;return 0;
}

运行结果:

初始化d2时调用的是拷贝构造函数,因为拷贝构造也是构造!

operator+=

可以在operator+的基础上进行代码复用(代码复用的思想参见CD18.【C++ Dev】类和对象(9)(声明和定义分离的写法以及代码复用)文章)

完整代码

按照之前在CD17.【C++ Dev】类和对象(8):赋值运算符文章中讲过复制运算符的格式,注意要返回*this,返回类型为Date&

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;
}
测试代码
#include "Date.h"
int main()
{Date d1(2025, 3, 25);d1 += 100;d1.Print();return 0;
}

运行结果是正确的:

提问

operator+=的代码真的没有问题吗?

答:其实仍然有问题.

使用下面这个测试代码:

#include "Date.h"
int main()
{Date d1(2025, 3, 25);d1 += -100;d1.Print();return 0;
}

 运行结果:日是负数,错误

修复

需要添加判断:加一个负数等于减这个数的相反数,需要调用operator-=,会在CD20.【C++ Dev】类和对象(11) 日期类对象的成员函数(++、--、日期-日期)文章实现

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

代码复用

+和+=的代码有些重复,代码如下:

1.+复用+=

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

2.+=复用+

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

提问

对比以上两段代码,哪个写法更高效?

修改函数,打印测试信息:

Date::Date(int year , int month, int day)
{cout <<"构造函数:Date::Date(int year , int month, int day)" << endl;_year = year;_month = month;_day = day;
}Date::Date(const Date& x)
{cout << "拷贝构造函数:Date::Date(const Date& x)" << endl;_year = x._year;_month = x._month;_day = x._day;
}

测试代码(在没有优化的情况下,问一共拷贝对象几次?)

#include "Date.h"
int main()
{cout << "d1和d2初始化:" << endl;Date d1(2025, 3, 25);Date d2(1, 1, 1);cout << endl;cout << "d2=d1 + 100如下:" << endl;d2=d1 + 100;cout << endl;cout << "d1 += 100如下:" << endl;d1 += 100;return 0;
}
+复用+=调用拷贝构造函数次数如下:

可画过程图分析:

(注:Date tmp(*this)传的是*this,为Date::Date(const Date& x)需要的参数) 

结果:拷贝对象一共两次 

测试代码执行结果:

(VS显示只调用拷贝对象一次的原因:编译器做了优化)

 如果在MSDOS下的老编译器Tubro C++上测试:

#include <iostream.h>
#include <conio.h>
class Date
{
public:int GetMonthDay(int year,int month){static int day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return day[month];}Date (int year , int month, int day){cout << this <<"Date (int year , int month, int day)" << endl;_year = year;_month = month;_day = day;}Date (const Date& x){cout << "Date(const Date& x)" << endl;_year = x._year;_month = x._month;_day = x._day;}Date operator+(int day){Date tmp(*this);tmp += day;return tmp;}Date& operator+=(int day){_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;}int _year;int _month;int _day;
};int main()
{cout << "Initializing d1 and d2......" << endl;Date d1(2025, 3, 25);Date d2(1, 1, 1);cout << endl;cout << "d2=d1 + 100:" << endl;d2=d1 + 100;cout << endl;cout << "d1 += 100:" << endl;d1 += 100;getch();return 0;
}

(旧编译器下头文件是.h结尾的,最后的getch()是为了让运行临时暂停,好查看结果)  

运行结果:

(没有优化,一共拷贝对象2次)  

+=复用+调用拷贝构造函数次数如下:

可画过程图分析:

结果:拷贝对象一共四次

测试代码执行结果:

(VS显示只调用拷贝对象两次的原因:编译器做了优化)  

如果在MSDOS下的老编译器Tubro C++上测试:

#include <iostream.h>
#include <conio.h>
class Date
{
public:int GetMonthDay(int year,int month){static int day[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return day[month];}Date (int year , int month, int day){cout << this <<"Date (int year , int month, int day)" << endl;_year = year;_month = month;_day = day;}Date (const Date& x){cout << "Date(const Date& x)" << endl;_year = x._year;_month = x._month;_day = x._day;}Date operator+(int day){Date tmp(*this);tmp._day += day;while (tmp._day > GetMonthDay(tmp._year,tmp._month)){tmp._day -= GetMonthDay(tmp._year,tmp._month);tmp._month++;if (tmp._month == 13){tmp._year++;tmp._month = 1;}}return tmp;}Date& operator+=(int day){*this = *this + day;return *this;}int _year;int _month;int _day;
};int main()
{cout << "Initializing d1 and d2......" << endl;Date d1(2025, 3, 25);Date d2(1, 1, 1);cout << endl;cout << "d2=d1 + 100:" << endl;d2=d1 + 100;cout << endl;cout << "d1 += 100:" << endl;d1 += 100;getch();return 0;
}

运行结果是这样的: 

(没有优化,一共拷贝对象4次)

练习

日期-日期问题:

https://leetcode.cn/problems/number-of-days-between-two-dates/

下篇博客将分析此题

http://www.dtcms.com/wzjs/183595.html

相关文章:

  • 有什么好字体可以导入wordpress网站seo 优化
  • 郑州网站制作费用推广平台
  • 攸县住房和城乡规划建设局网站设计公司取名字大全集
  • 北京营销型网站建设培训站长统计app软件
  • b2c网站二次开发seo的优缺点
  • 做网站要求付全款旅游最新资讯
  • 做发包业务网站技师培训
  • 做餐饮网站建设今日搜索排行榜
  • 专业做包包的网站好爱站长
  • 网站title在哪里武汉百度seo网站优化
  • 内部网站管理办法网站seo源码
  • 江西城乡住房建设网站网站seo方案案例
  • 什么网站允许搭建建材企业网站推广方案
  • 教做家庭菜的网站头条新闻 最新消息条
  • 抓好门户网站 建设网络营销的5种方式
  • 上海网站建设招标搜索引擎优化seo信息
  • 重庆市建设网站首页网站建设报价方案
  • 网站开发工具简述百度官方app免费下载
  • 公司网站建设行业怎么样深圳seo优化外包
  • 专门做网上链接推广的网站网络整合营销4i原则是指
  • 网站建设公司软件开发谷歌浏览器入口
  • 个人网站模板王网络营销的专业知识
  • 网站显示图片标记百度推广代理加盟
  • 巴青网站制作百度公司招聘岗位
  • 做电商网站搭建就业岗位360搜索网址是多少
  • 网站建设劳务合同站长工具星空传媒
  • 网站建设的所需解决的技术问题线上推广的公司
  • winform和网站做交互百度灰色关键词排名
  • 做网站的核验单 是下载的吗汕头seo计费管理
  • aspcms网站打不开永久免费用的在线客服系统