C++ | Date 日期类详解

目录

简介

日期类总代码  |  Date

类的定义 & 构造 & Print

类的定义

构造函数 & Print

比较类,如<、>、<=......

值加减类,如+、-、+=、-=......

加减类具体分类

判断某个月有多少天 GetMonthDay

日期类 + / +=(- / -=) 整数

日期类 - 日期类

日期类++ / --(前置后置)

流相关,如<<、>>(cout、cin)

结语


简介

日期类Date实现的本质就是  运算符重载  和  赋值运算符重载

我们要实现自定义类型像内置类型一样相加减,肯定会用到operator关键字+操作符

接下来我们要实现的分为三类:

  1. 比较类,如<、>、<=......
  2. 值加减类,如+、-、+=、-=......
  3. 流相关,如<<、>>(cout、cin)

日期类总代码  |  Date

如果有需要代码的同学,下方的链接是我上传到 gitee 里的代码

2024 - 5 - 3 - gitee - Date

类的定义 & 构造 & Print

我们会建三个文件:

  1. test.cpp
  2. Date.cpp
  3. Date.h

其中我们的Date.h是头文件,我们的函数声明与类的定义,以及头文件都被包含在头文件里面

另外,我们在正式开始开始讲解日期类之前,我们需要先将类给定义出来,然后将其的构造函数、析构函数、Print函数写好

类的定义

代码如下:

class Date
{
public:private:int _year;int _month;int _day;
};

构造函数 & Print

我们现在写函数都需要现在类中声明一份,然后再到Date.cpp中去实现逻辑,最后到test.cpp中进行测试

Date.h 内部代码如下:

class Date
{
public://构造函数声明Date(int year = 1, int month = 1, int day = 1);void Print();
private:int _year;int _month;int _day;
};

Date.cpp 内部逻辑实现:

Date::Date(int year, int month, int day):_year(year), _month(month), _day(day)
{}void Date::Print()
{cout << _year << " "<< _month << " "<< _day << endl;
}

由于我们分成了头文件与.cpp文件,所以我们在.cpp文件中实现逻辑之前我们得先Date::一下

不然我们就没法使用我们定义的类

比较类,如<、>、<=......

在开始之前,我得先介绍一个符号防止有同学没听说过:!

这个是逻辑取反:0 取反就是非 0,非 0 取反就是 0

对于这一类,我们的实现逻辑是这样的:

我们先实现<,然后再实现==

当我们将这两个实现了之后,我们就可以复用这两个,然后将其余所有比较类的函数全都表示出来

试想一下:我们实现了<和==,当我们要实现<=怎么办

那是不是同时满足<和==就算是<=

这是我们要实现>怎么办

当一个数不<=时,即<=取反( ! 符号)就是 >

闲话少叙,我们先来实现一下 小于<

bool Date::operator<(const Date& d)const
{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;
}

注意看,我们在上文中实现的逻辑是:如果年小于,那就小于

如果年相等(大于的情况统一出判断之后返回false),那我们就看月,如果月小于,那就小于

如果月相等,那就看天,天小于,那就小于

如果上述条件都不符合,那就是大于或者等于,反正就是不小于

注:我们这里要的只是小于,如果等于或大于,那就不是小于

接着我们来实现一下 等于==

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

等于的实现逻辑相当简单,只有在我的年月日都相等的时候我的两个日期才想等

但凡有一个不相等,那就是不相等,全相等我们就直接返回一个 1,反之则是 0

接着就是很有意思的复用环节了,我们来实现一下 小于等于<=

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

你会看到,我们直接将自定义类型像内置类型一样进行了比较

但是这些比较的符号都是我们刚刚才实现过的:<、==

当两个日期既小于又等于时,那么这两个日期就是小于等于

趁热打铁,我们再一鼓作气将 >、>=、!=给一起实现了

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

我们能看到,大于就是小于等于取反

大于等于就是小于取反

不等于就是等于取反

值加减类,如+、-、+=、-=......

加减类具体分类

加减类里面其实还分了三类

  1. 日期类 + / +=(- / -=) 整数(某个日期的多少天之后)
  2. 日期类 - 日期类(宝宝,今天离我们刚开始在一起已经过了多少天了呀)
  3. 日期类++ / --(前置后置) 

判断某个月有多少天 GetMonthDay

在正式开始讲之前,我们为了防止后序的逻辑太乱,所以我们就单独将判断某个月有多少天的逻辑拿出来单独实现

而这个函数我们可以在类里面实现,这是为了类的包装,增加安全性、

当然如果你非要将其定义在全局也不是不可以,随你喜欢,出事了与我无瓜

接下来我们来讲一讲判断某个月有多少天的逻辑

由于一年有12个月,如果一个月一个月地返回的话,那就太挫了

所以我们可以创建一个数组,返回之时我们就可以把月当下标返回了

int MonthDayArray[13] =
{ -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

可以看到,我们创建了一个13个数的数组,因为第一个的下表为0,我们要的效果是1月对应下标1

但是平年和闰年的判断关乎了二月的大小,所以我们不妨假设二月是28天

接着我们在下面判断今年是不是闰年且   要返回的月份是不是2月,如果不是二月,那我们判不判断闰年其实没意义

所以,如果月为2月,如果传过来的年判断为闰年,我们直接返回29即可

如果不是闰年或者根本就不是二月,那我们就返回每个月对应的对应数组下标中的值即可

代码如下:

int GetMonthDay(int year, int month)
{assert(month < 13 && month > 0);int MonthDayArray[13] ={ -1, 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;elsereturn MonthDayArray[month];
}

日期类 + / +=(- / -=) 整数

首先我们先来想一个问题:+和+=之间有什么不同

+是将值传过去,自身并不会改变,比如 int i = n + m; 其中 n 和 m 并没有改变

而 += 是自身的值会改变

所以我们面对这两类函数时,返回值也不一样,因为面对自身不改变的情况,我们只能创建一个临时变量,但是临时变量出了函数会销毁,所以我们的返回值不能为引用,需要让其调用拷贝构造函数,所以返回值类型为 Date

但是如果是对象自身要改变的情况,那我们就无需创建临时变量,直接在原对象的基础上进行改变即可,最后直接返回*this,所以返回值的类型需为引用,为了防止调用不必要的拷贝构造影响效率,所以参数的返回值类型为 Date&

我们先来实现一下 +=

+= 的逻辑如下:

我们先将 _day 与 day 直接相加,然后我们再对 _day 进行减小,每次减一个月的天数

我们while循环内的逻辑就是,当我的 _day 减小到比 GetMonthDay 函数返回的天数要大时,就证明我们的天数还需要再减

就好比我的月本来是 24,我想知道 100 天后是那一天,我就先 24 + 100 = 124

但是124肯定不止一个月的量,所以我们需要减

假设现在是3月,我就124 - 31 = 93,然后就来到了 4 月,但是还是有多,我就继续减,现在是 4 月就减 30,93 - 30 = 63......

直到 _day 是正常的,循环终止

我们每减一次日期,我们的月就要++一次

当我们的月为13时,我们就将13手动置为1,随后年++

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

接着我们来实现一下 +

+其实就可以直接复用+=

我们可以直接创建一个和*this一摸一样的Date类型对象tmp

我们只需要对tmp进行改变(+=)最后返回即可

代码如下:

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

接着是 -= 的实现

-= 的逻辑和 += 很类似,只不过我们现在是直接 _day - day

如此一来,我们的 _day 就为负数,我们就需要不断对其进行加的操作,并在此过程中注意月的--和年的--

但是有一个点需要注意的是,如果调用这个函数的人,要-=却传了一个负数过来,那就单独对其进行判断

如果传过来的是负数,那我们就将其 += 上负的参数即可

代码如下:

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

最后是 - 的实现

类似的,我们的减就是实例化一个和 *this 一摸一样的临时对象 tmp(拷贝构造),然后对其进行 -= 操作,最后返回 tmp 即可

代码如下:

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

日期类 - 日期类

可能有人会疑惑,为什么只有日期类的-,而没有+

这是因为日期类的+是没有意义的,试想,2024年1月13号 + 2024年3月31号有什么意义?

而 - 之所以有意义是因为,如果未来有一天你的对象问你:宝,这是我们在一起的第几天啊?

也就是两个日期之间相差几天,这个是有意义的

而我们要实现这个的逻辑也较为简单:

我们只需要将两个日期分为大和小

我们找出小的那一个,不断让其+=1,然后再额外设置一个整形变量,小的那个日期类每+=1一次,整型变量就 ++ 1次

当小的那个日期和大的那个日期相等的时候,我们创建出来的那个整型变量的值就是两个日期之间的差值

当然,为了防止两个日期之间的差值为负数的情况,我们应该先将this指针指向的设置为max,另一个参数指向的为min,如果此时发现设置的max比min要小,那我们就将两者进行交换,随后设置一个变量flag,如果存在max小于min而后两者需要交换的情况,那我们就将flag赋值为-1,否则flag为1

最后返回的结果是两个日期之间的差值*flag

代码如下:

int Date::operator-(const Date& d)
{Date max = *this;Date min = d;int flag = 1;int count = 0;if (*this < d){max = d;min = *this;flag = -1;}while (max != min){min += 1;count++;}return count * flag;
}

日期类++ / --(前置后置)

其实我们++或--的逻辑在我们将+=和-=实现完了之后都变得非常简单

我们++本质将就是+=1,那我们之间将日期类+=1即可实现++

直接将日期类-=1即可得到--

需要详细讲解的是前置与后置

我们前置与后置唯一的区别就在于,一个是先++后使用,一个是先使用后++

但是我们在写操作符名称的时候,都只能写operator++,所以我们无法分辨哪个是前置哪个是后置

本贾尼博士也发现了这个漏洞,所以就规定说,在传参数的括号中加上一个int的就是后置++

而这个int并不是说要传值的意思,里面传多少都没用,可以理解为就是对编译器的一个提醒,告诉编译器我现在的这个++是后置++

而我们前置与后置的函数返回值类型也是不一样的

前置是直接对*this指向的内容进行修改,修改完后直接返回*this即可,而*this并不是临时变量,出了函数并不会被销毁,所以我们函数的返回类型是引用,这样可以防止多调用拷贝构造影响效率,Date&

后置是需要在函数内部实例化一个临时变量tmp,而我们直接对*this进行修改,最后将tmp返回,因为我们实现的是后置++,*this指向的内容需要更改,但是我们需要返回的是一个更改之前的值,所以我们需要备一份。但是对象tmp是临时的,出了函数的作用域就会被销毁,所以我们只能任其调用拷贝构造,所以返回类型不能为引用Date

综上,++ / --(前置 / 后置)代码如下:

Date& Date::operator--()//前置
{*this -= 1;return *this;
}Date Date::operator--(int)//后置
{Date tmp = *this;tmp -= 1;return tmp;
}Date& Date::operator++()//前置
{*this += 1;return *this;
}Date Date::operator++(int)//后置
{Date tmp = *this;tmp += 1;return tmp;
}

流相关,如<<、>>(cout、cin)

我们在C语言中曾学到了printf和scanf

我们都知道其用法,就是先指定类型,接着我们再将要打印的变量放上去

如果只是打印内置类型还好,但如果是打印自定义类型呢?我们没办法用printf打印自定义类型

本贾尼博士之所以整了一个cout、cin(流插入流提取),就是因为想像打印内置类型一样打印自定义类型的,并且cout可以自动判断要打印变量的类型

我们来看一张图:

如上我们可以看到,cout 和 cin 是两个实例化出来的全局对象,类的类型分别是 ostream、istream

而 ostream、istream 又被包在iostream里面

而我们如果想要实现可以像内置类型一样打印自定义类型的话,我们只需要自己实现一下operator<< 和 operator>> 即可

我们先不考虑连续打印的问题,返回值先设置为void

而我们的参数就传一个ostream&类型的对象即可,剩下还有一个this指针(这里埋一个坑)

代码如下:

void Date::operator<<(ostream& out)
{out << _year << " " << _month << " " << _day << endl;
}

但是当我们想要调用的时候,却会发现调用不了

Date s1(2024, 1, 13);
cout<<s1;

你会发现调用不了,这是因为我们在调用的时候,要遵循的顺序是参数的顺序

看我们函数内实现的逻辑,我们的第一个参数是this指针,随后才是ostream

这就意味着如果按照上面写的函数的话,我们就需要将调用的顺序改一下我们才能调用成功

Date s1(2024, 1, 13);
s1<<cout;

如果还不理解的话,我们来显示调用一下我们的函数相信你就能看得懂了

s1.operator<<(cout)

综上,我们如果这么写的话与我们日常的使用逻辑相悖,所以我们需要做出相应的调整

但是this指针已经将第一个参数的位置给牢牢地占住了,我们没有办法做更改

所以我们需要将这个函数变为全局的

当这个函数编程全局的的时候,我们就能够自己定义参数的位置了

void operator<<(ostream& out, const Date& d)

但是如上我们就=还是不能正常调用

这是因为当我们将这个函数变为全局函数的时候,这个函数就无法调用类里面的私有变量

为此,我们需要使用友元的方式进行解决

我们在这里先简单提一下友元的概念,具体的知识我们放到下一篇博客类和对象下中去讲

友元,就是说:我是你的朋友,所以你的东西就是我的东西,但是只是你把我当朋友,我还没有把你当朋友,所以你的东西我能用,但我的东西你不能用

要定义成友元也比较简单,我们只需将函数的声明在类中任意位置放一份,并在最前面加上一个friend即可,如下:

friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);

.h文件全:

class Date
{friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);public:Date(int year = 1, int month = 1, int day = 1);void Print();int GetMonthDay(int year, int month){assert(month < 13 && month > 0);int MonthDayArray[13] ={ -1, 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;elsereturn MonthDayArray[month];}bool operator<(const Date& d)const;bool operator>(const Date& d)const;bool operator<=(const Date& d)const;bool operator>=(const Date& d)const;bool operator==(const Date& d)const;bool operator!=(const Date& d)const;Date& operator+=(int day);//*this要变,故不加constDate operator+(int day)const;Date& operator-=(int day);Date operator-(int day)const;int operator-(const Date& d);Date& operator--();Date operator--(int);Date& operator++();Date operator++(int);//日期类无需析构函数,编译器默认生成的就够用
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

所以我们的<<就变成了:

void operator<<(ostream& out, const Date& d)
{out << d._year << " " << d._month << " " << d._day << endl;
}

但是,如果我们遇到需要连续打印的情况,我们写的这个函数就不够用了,因为没有返回值

但是如果我们想要支持连续打印的话,我们需要将out传回去

所以,最终版本如下:

ostream& operator<<(ostream& out, const Date& d)
{out << d._year << " " << d._month << " " << d._day << endl;return out;
}

接着我们来看一下   >>

这个也是一样的,我们的istream是一个类,我们同样将其设置为全局函数,最后通过友元的方式令其能够访问到私有变量,而为了支持连续赋值,所以我们同样需要一个返回值,返回值的类型就是istream&

代码如下:

istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}

结语

到这里我们的日期类就结束了

如果你觉得这篇博客对你有帮助的话,希望各位能够多多支持!!

(比心)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/6380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

随便聊一下 显控科技 控制屏 通过 RS485 接口 上位机 通讯 说明

系统搭建&#xff1a; 1、自己研发的一个小系统&#xff08;采集信号&#xff0c;将采集的信号数字化&#xff09;通过COM口&#xff0c;连接显控屏 COM3 口采用 485 协议送到显控屏&#xff08;显控科技&#xff09;的显示屏展示出来&#xff09;。 2、显控屏 将 展示的数据…

Jenkins(超详细的Docker安装Jenkins教程!!!)

Jenkins Jenkins&#xff0c;原名 Hudson&#xff0c;2011 年改为现在的名字。它是一个开源的实现持续集成的软件工具。 官方网站&#xff1a;https://www.jenkins.io/ 中文文档&#xff1a;https://www.jenkins.io/zh/ 为什么需要Jenkins&#xff1f; 我们以前写完代码&a…

Excel中怎样把单元格里的数据拆分成多行?

时常会遇到这种情况&#xff0c;需要将一个单元格里的数据分拆到多行&#xff0c;可以使用公式&#xff0c;这里演示使用基础操作的办法。 按照excel使用经验&#xff0c;可以复制数据&#xff0c;粘贴到MS Word里&#xff0c;这个是excel的同族软件&#xff0c;兼容性好。 在…

Redis的面试

认识Redis 认识NoSQL SQL&#xff08;关系型数据库&#xff09; NoSQL&#xff08;非关系型数据库&#xff09; 1.结构化 非结构化 2.关联的 非关联的 3.SQL查询 非SQL 4.事务 …

[C++基础学习-07]----C++结构体详解

前言 结构体&#xff08;Struct&#xff09;是C中一种用户定义的复合数据类型&#xff0c;用于存储不同类型的数据项。结构体可以包含不同类型的数据成员&#xff0c;这些数据成员可以是基本类型&#xff08;如int、float、char等&#xff09;&#xff0c;也可以是数组、指针、…

【SSM进阶学习系列丨分页篇】PageHelper 分页插件导入集成实践

文章目录 一、说明什么是分页PageHelper介绍 二、导入依赖三、集成Spring框架中四、编写Service五、编写Controller六、编写queryAllByPage页面展示数据 一、说明 什么是分页 ​ 针对分页&#xff0c;使用的是PageHelper分页插件&#xff0c;版本使用的是5.1.8 。 ​ 参考文档…

第十三届蓝桥杯国赛真题 Java C 组【原卷】

文章目录 发现宝藏试题 A: 斐波那契与 7试题 B: 小蓝做实验试题 C: 取模试题 D: 内存空间试题 E \mathrm{E} E : 斐波那契数组试题 F: 最大公约数试题 G: 交通信号试题 I: 打折试题 J: 宝石收集 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#x…

为什么 IP 地址通常以 192.168 开头?(精简版)

网络通讯的本质就是收发数据包。如果说收发数据包就跟收发快递一样。IP地址就类似于快递上填的收件地址和发件地址一样&#xff0c;路由器就充当快递员的角色&#xff0c;在这个纷繁复杂的网络世界里找到该由谁来接收这个数据包&#xff0c;所以说&#xff1a;IP地址就像快递里…

AG32 MCU在触摸屏的应用(AGM FPGA/MCU行业应用)

传统的屏驱MCU常见应用于洗衣机、空调、空调面板、仪器仪表等人机交互界面显示场景中&#xff0c;通常是以段码的形式显示设备运转的时间、温度、测量结果等简单运行数据&#xff0c;随着人机交互需求丰富化&#xff0c;智能家居设备、摩托车、电动车等产品也逐步增加了屏幕显示…

2024年第六届先进材料、机械和制造国际会议(AMMM 2024)即将召开!

2024年第六届先进材料、机械和制造国际会议&#xff08;AMMM 2024&#xff09;将于2024年9月6-8日在日本东京举行。AMMM 2024将以国际材料&#xff0c;机械和制造为主题&#xff0c;吸引到来自多个领域的研究人员和学者相聚在一起分享知识&#xff0c;讨论想法&#xff0c;并了…

Android 音视频播放器 Demo(一)—— 视频解码与渲染

本篇作为 Android 音视频实战系列的第二篇文章&#xff0c;主要介绍视频解码与渲染过程。本系列文章目录如下&#xff1a; Android 音视频基础知识 Android 音视频播放器 Demo&#xff08;一&#xff09;—— 视频解码与渲染 Android 音视频播放器 Demo&#xff08;二&#xff…

字符函数与字符串函数(2)

遇见她如春水映莲花 字符函数与字符串函数&#xff08;2&#xff09; 前言一、strcatstrncat 二、strcmpstrncmp在这里插入图片描述 三、strstr四、strtok五、strerror总结 前言 根据上期字符函数与字符串函数我们可以了解到字符函数与个别字符串函数的用法&#xff0c; 那么接…

STM32——GPIO篇

技术笔记&#xff01; 1. 什么是GPIO&#xff1f; GPIO是通用输入输出端口&#xff08;General-purpose input/output&#xff09;的英文简写&#xff0c;是所有的微控制器必不可少的外设之一&#xff0c;可以由STM32直接驱动从而实现与外部设备通信、控制以及采集和捕获的功…

当管道运算符遇上无限可能:探索数据流的奇妙之旅

文章目录 序言目的进程间通信的理解进程间通信的发展历史管道创建验证管道的大小管道的4种情况管道的5种特征 序言 通过该命令计算了在当前路径下一共有多少个文件夹的任务 进程虽然有独立性,但是进程并不孤僻,他们之间也会相互进行协作共同完成一件事 这个前提是他们之间的信…

嵌入式全栈开发学习笔记---C语言笔试复习大全7(编程题1~8)

目录 1、200&#xff5e;300之间能被3整除的数&#xff0c;5个一行输出&#xff1b; 2、求两个数的最大公约数、最小公倍数&#xff1b; 3、输入十个数&#xff0c;求出平均值&#xff1b; 4、通过编程实现,统计1~n有多少个9&#xff1b; 5、有1、2、3、4个数字&#xff0…

C#简单创建DLL文件并调用

DLL是Dynamic Link Library的缩写&#xff0c;意为动态链接库。动态链接库其实是由编译器将一系列相关的类型编译、链接并封装成一个独立的文件&#xff0c;与对其进行调用的程序分开。这样一个独立的文件相当于程序的一个模块&#xff0c;如果需要对程序进行更新&#xff0c;只…

ESP32-C3第二路串口(非调试)串口打通(1)

1. 概述与引脚复用 《ESP32-C3 系列芯片技术规格书》中提到&#xff0c;ESP32-C3系列芯片中有两路串口。 第1路串口就是常用的调试串口&#xff0c;在笔者使用的ESP32-C3-DevKitC-02开发板中&#xff0c;这一路串口通过CP2102 USB转UART桥芯片与电脑的USB口相连接&#xff0c;…

42 线程池

一种线程使用模式&#xff0c;线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。线程池维护多个线程&#xff0c;等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价&#xff0c;线程池不仅能保证内核的充分利用&#xf…

redis中的双写一致性问题

双写一致性问题 1.先删除缓存或者先修改数据库都可能出现脏数据。 2.删除两次缓存&#xff0c;可以在一定程度上降低脏数据的出现。 3.延时是因为数据库一般采用主从分离&#xff0c;读写分离。延迟一会是让主节点把数据同步到从节点。 1.读写锁保证数据的强一致性 因为一般放…

数据结构------栈的介绍和实现

目录 1.栈的一些初步认识 2.栈的实现 3.相关的函数介绍 &#xff08;1&#xff09;栈的初始化 &#xff08;2&#xff09;栈的销毁 &#xff08;3&#xff09;栈的数据插入 &#xff08;6&#xff09;判断是否为空 &#xff08;7&#xff09;栈的大小 4.栈的实现完整…