【C++】日期类Date(详解)

news2024/9/21 1:31:56

🔥个人主页:Forcible Bug Maker

🔥专栏:C++

目录

前言

日期类

日期类实现地图

获取某年某月的天数:GetMonthDay

检查日期合法,构造函数,拷贝构造函数,赋值运算符重载及析构函数

日期类的+=day和+day

日期类的-=day和-day

前置++和后置++

前置--和后置--

比大小运算符的重载

日期-日期返回天数

暴力++法

直接相减法

const成员

流插入和流提取重载

友元(friend)

结语


前言

本篇主要内容:日期类的实现

上篇我们介绍了拷贝构造函数和赋值运算符重载两大类的默认成员函数,本篇将会介绍更多关于操作符重载的实例运用。日期类,是与日期相关的类,主要用于处理与日期和时间相关的操作。我们将在完善一个日期类的过程中加深对运算符重载的理解和运用。在理解操作符重载之后,最后两个默认成员函数学习起来也就不是什么大问题了。

日期类

日期类实现地图

在实现日期类之前,需事先要知道要实现哪些内容。我会给出一份类的指南,也就是成员变量和成员函数的声明,然后根据声明一步步实现其中的成员函数。在代码编写过程中,成员函数是可以直接定义在类内部的;但是在实际开发过程中,考虑到工程级项目的规模,一般采用声明和定义分离的方式经行类的实现。将声明统一放在 Date.h 中,把成员函数的定义统一放在 Date.cpp 中,道理跟C语言的声明定义分离一样。

#include<iostream>
#include<cassert>
using namespace std;

class Date
{
	// 友元
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	// 获取某年某月的天数
	int GetMonthDay(int year, int month);
	// 检查日期是否合法
	bool CheckDate();
	// 全缺省的构造函数
	Date(int year = 1900, int month = 1, int day = 1);
	// 拷贝构造函数
  // d2(d1)
	Date(const Date& d);
	// 赋值运算符重载
  // d2 = d3 -> d2.operator=(&d2, d3)
	Date& operator=(const Date& d);
	// 析构函数
	~Date();
	// 日期+=天数
	Date& operator+=(int day);
	// 日期+天数
	Date operator+(int day);
	// 日期-天数
	Date operator-(int day);
	// 日期-=天数
	Date& operator-=(int day);
	// 前置++
	Date& operator++();
	// 后置++
	Date operator++(int);
	// 后置--
	Date operator--(int);
	// 前置--
	Date& operator--();
	// >运算符重载
	bool operator>(const Date& d);
	// ==运算符重载
	bool operator==(const Date& d);
	// >=运算符重载
	bool operator >= (const Date& d);
	// <运算符重载
	bool operator < (const Date& d);
	// <=运算符重载
	bool operator <= (const Date& d);
	// !=运算符重载
	bool operator != (const Date& d);
	// 日期-日期 返回天数
	int operator-(const Date& d);
	void Print() 
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

// 输出流重载
ostream& operator<<(ostream& out, const Date& d);
// 输入流重载
istream& operator>>(istream& in, Date& d);

这份地图中大家也许会发现很多陌生的内容,如友元,重载前置++和后置++,流插入和流提取重载等。不过不用着急,接下来都会讲到。

获取某年某月的天数:GetMonthDay

GetMonthDay函数用于获取某年某月的天数,由于其在日期加天数和减天数运算符重载的函数中被频繁调用,且代码量较少,我们可以直接将其设置为内联,定义到类的内部定义到类内部的成员函数都默认加了内联inline,而分离定义的成员函数没有此特性)。

注:分离声明和定义的函数是无法内联的

int GetMonthDay(int year, int month)
{
	assert(month > 0 && month < 13);
	int months[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;
	}
	else return months[month];
}

由于此函数定义在类的内部,故没有 Date:: 来指定命名空间,此函数的其他逻辑应该也好理解,最终通过传过来的年和月来确定当月的天数,考虑到闰年判断等问题。

检查日期合法,构造函数,拷贝构造函数,赋值运算符重载及析构函数

检查日期是否合法,需要检查月不能小于1或者大于12,日要根据年和月来判断,见代码:

bool Date::CheckDate() // 由于声明和定义分离,定义函数时需指定一下命名空间Date::
{
	if (_month < 1 || _month > 12
		|| _day < 1 || _day > GetMonthDay(_year, _month)) {
		return false;
	}
	else return true;
}

构造函数,拷贝构造以及赋值重载等没什么好说的,注意拷贝构造需判断一下日期是否合法:

// 全缺省的构造函数
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
	if (!CheckDate()) {
		cout << "日期非法\n" << endl;
	}
}

// 拷贝构造函数
// d2(d1)
Date::Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

// 赋值运算符重载
 // d2 = d3 -> d2.operator=(&d2, d3)
Date& Date::operator=(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
	return *this;
}

// 析构函数
Date::~Date()
{
	_year = 0;
	_month = 0;
	_day = 0;
}

日期类的+=day和+day

日期类可以+吗?答案是肯定的,不过不是两个日期相加,而是一个日期去+一个天数,如,今天是2024/4/20,加上5就是五天后,五天后是2024/4/25。如何实现+=,来看看代码:

// 日期+=天数
Date& Date::operator+=(int day)
{
    // 此处是对+的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;
}

如果day为大于0的数,首先将day的值加到成员变量_day上,然后循环判断_day是否大于当月天数,如果大于,就减去当月天数,_month+1,_year根据_month是否大于12判断自增;如果_day小于当月天数,则跳出循环。最后返回值是为了贴合内置类型连续运算赋值的规则,如,a=b+=c;而Date&引用返回则是为了减少拷贝

写道这里,就即将到类和对象一个神奇的使用方式了,它的名字叫——复用

我们可以直接复用+=来实现+,来看看具体的复用代码:

// 日期+天数
Date Date::operator+(int day)
{
	Date tmp(*this);
	tmp += day; // 复用+=
	return tmp;
}

日期+day的规则是不能改变运算日期的值,所以这里在成员函数中定义了一个tmp拷贝,用来执行运算操作,最后传值返回,是因为tmp作为临时变量,出了函数就会销毁。

注:这里提供的是+=复用+的设计模式。实际上,用+复用+=也是可行的,但是这种复用方式却比+=复用的质量差,大家感兴趣可以自行实现并考虑其中原因。

日期类的-=day和-day

-=day虽然思路和+=差不多,但是逻辑却比+=难搞一些,建议仔细思考后在上手写。

// 日期-=天数
Date& Date::operator-=(int day)
{
    // 当减的天数为负时的操作
	if (day < 0) {
		*this += (-day);// 复用了刚才写的+=
		return *this;
	}
	_day -= day;
	while (_day < 1) {
		--_month;
		if (_month == 0) {
			--_year;
			_month = 12;
		}
		day += GetMonthDay(_year, _month);
	}
	return *this;
}

在给_day+=天数时,注意加的是上个月的天数,并非本月天数。写了-=,-的实现也就是简单的复用操作了:

// 日期-天数
Date Date::operator-(int day)
{
	Date tmp(*this);
	tmp -= day;
	return tmp;
}

返回值是否引用返回和+=day和+day是同理的。

前置++和后置++

知道内置类型的前置++和后置++吗?如++a,a++等,它们的作用都是给变量a自增1,学了这么长时间,你是否对它们的区别了如指掌。本篇我们讲的是自定义类型的自增,如,日期类,我们要给一个自定义类型(日期类)自增,但计算机并不知道日期自增的规则,这时就需要人为提供内置类型的自增运算符。其实,上面刚刚讲过复用,我们直接复用+=和-=就可以了,你想想,什么是++?什么是--?不就是+=1和-=1嘛!

// 前置++:返回+1之后的结果
Date& Date::operator++()
{
	*this += 1;
	return *this;
}

注:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率

如果不提供参数,在C++的定义之下,默认就是放到对象前面的重载运算符:++d,但如果单将一个运算符放到对象后面构成运算符重载应该怎么办呢?看看C++提供的解决方式:

// 后置++:自增,返回自增之前的拷贝
Date Date::operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}

前置++和后置++都是一元运算符,为了可以让前置++和后置++形成正确重载,C++规定后置++重载时多增加一个int类型的参数,但调用参数时该参数不用传递,编译器自动传递

注:后置++是先使用后+1,因此只需要返回+1前的值,故需要先将this保存一份,然后给this+1。而代码中的tmp是临时对象,因此只能以值得方式返回,而不能返回引用

前置--和后置--

不想多说了,四个字——同理,复用

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

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

注意区分前置和后置的区别,控制下返回值是否引用返回就行。

比大小运算符的重载

为什么要给日期提供比大小重载,因为内置类型无法完成比较日期的任务。比大小需要提供的重载函数就多了,包括 <,<=,==,>,>=,!= ,一套写下来,岂不是能把人累瘫,别着急,实际上,需要你完成的实际上只有两个,> 和 ==,当然你选择 < 和 ==,或者 <,!= 统统都可以,如果还没想通,没关系,来看看我是如何实现的,这里以> 和 ==为例。

// >运算符重载
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;
	return false;
}

// ==运算符重载
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 == d;
}

发现C++运算符重载和复用的魅力了吗?

如果此时你需要一个 < 重载:

// <运算符重载
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);
}

如果……哦,已经没有如果了,这就是所有的比大小运算符重载🙂,很有意思吧。

日期-日期返回天数

日期减日期为的是计算两个日期之间的天数间隔。对于日期相减,这里提供了两种实现方案。

暴力++法

找出日期中小的那个,然后通过记录每次++的次数n来记录两日期之间的间隔,同时设置一个变量flag来记录两个日期之间的差是正的还是负的。

// 日期-日期 返回天数
int Date::operator-(const Date& d)
{
	Date max = *this;// 假设大的那个是*this
	Date min = d;
	int flag = 1;
	int n = 0;
	if (*this < d) { //判断并重置max和min以及日期间隔正负
		max = d;
		min = *this;
        flag = -1;
	}
	while (min != max) {
		++min;
		++n;
	}
	return n * flag;
}

此方法也是最好理解的一种,虽然暴力++会有一些消耗,但是对于目前计算机的算力来说却是微不足道的。

直接相减法

这个过程就稍稍有些复杂,你可以先确定max(大日期对象)下一年的第一天tmpmaxmin(小日期对象)本年的第一天tmpmin,让它们的差值✖365,加到 n 上,同时遍历一遍这些年,找到一个闰年就让n+1。最后定义两个整型变量(tmp1,tmp2),让tmpmin逐次++(++使用的是之前重载的日期类++,最好用前置++,减少拷贝的消耗),同时用tmp1计数,直到和min相等让max逐次++,同时tmp2计数,直到和tmpmax相等。这时让n减去tmp1和tmp2后,得到的就是两个日期之间的差值了。

以下是实现代码,亲测正确:

int Date::operator-(const Date& d)
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	int n = 0;
	if (*this < d) {
		max = d;
		min = *this;
		flag = -1;
	}
    // 以上是比较日期确定max和min
	n += (max._year - min._year + 1) * 365;
	for (int i = min._year; i <= max._year; i++)
		if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)
			++n;
    // 以上是根据年计算间隔的天数
	Date tmpmax(max._year + 1, 1, 1);int tmp1 = 0;
	Date tmpmin(min._year, 1, 1);int tmp2 = 0;
	while (tmpmax != max) {
		++max;
		++tmp1;
	}
	while (tmpmin != min) {
		++tmpmin;
		++tmp2;
	}
    // 以上是日期矫正,计算tmp1和tmp2
	n -= tmp1;
	n -= tmp2;
	return n * flag;
}

对于日期相减,不止有这两种实现,大家想到一些别的方式也可以自己亲自试一试,还是很有意思的。

const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改

具体怎么修饰呢?写一个const在参数列表后面:

在()括号后放const是将隐式传递的*this指针类型变成了const *this指针类型,这种解决方案是为了应对*this无法被显示改变为const类型而产生的。

对于const类型的对象,和内置类型的const修饰规则非常相似,权限只能平移和缩小,而不能放大。看看代码案例:

const Date d1;
Date& d2 = d1;// 不支持,d2是Date类型,取d1的引用属权限放大
const Date& d3 = d1;//支持,权限平移

Date d4;
const Date& d5 = d4;// 支持,权限缩小

对于const成员函数内部,是不可以调用非const成员函数的;而非const成员函数却可以调用其他的const成员函数

所以,对于一些不会改动Date对象数据的成员函数,尽量提供const类型的成员函数即可,如下:

// 获取某年某月的天数const版
int GetMonthDay(int year, int month)const
{
	assert(month > 0 && month < 13);
	int months[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;
	}
	else return months[month];
}

GetMonthDay定义在类内部,故不需要限定命名空间。

// 检查日期是否合法const版
bool Date::CheckDate()const
{
	if (_month < 1 || _month>12
		|| _day < 1 || _day>GetMonthDay(_year, _month)) {
		return false;
	}
	else return true;
}

基本上就是在函数()后加上const即可,需要这样调整的函数还包括比大小重载函数,日期相减函数,-day和+day,Print打印日期函数等等,这里就不一一列举了。

流插入和流提取重载

大家之前可能接触过C语言,这里就能体现出C语言输入输出的局限性了,它没办法支持对象类型的输入输出。在C++标准库<iostream>(包含istream类和ostream类)中,内含了输入流对象cin和输出流对象cout,通过使用这两个对象,我们可以支持输出所有的内置类型变量。今天要讲的流插入和流提取重载,就是可以帮助大家直接用cin和cout支持内置类型的输入输出。

如果需要定义一个流插入的重载,你会如何定义呢?

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

是这样吗?那就大错特错了,按照运算符重载规则,

cout << d;

这种书写方式明显不符合重载时的参数顺序,所以如果想要调用上面这份重载,需要这样写:

d << cout;

但是,这种使用方式明显违背了像内置类型那样使用输入输出流的初衷。产生这种问题的主要原因还是无法改变调用类内部定义的成员函数时第一个传过去的元素永远是this指针

为解决这样的问题,需要我们把流插入和流提取的函数重载在类的外部,像下面这样:

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

这里返回一个对象引用类型是为了贴合内置类型的使用规则,连续输出,如cout << a << b << c;如果没有此返回值,那么使用对象时,就只能用一次cout打印一个Date对象,如cout << d;而不是cout << d1 << d2 << d3;。

流提取也是同样的方法:

istream& operator>>(istream& in, Date& d)
{
	cout << "请输入年月日,用空格分隔:";
	in >> d._year >> d._month >> d._day;
	if (!d.CheckDate()) {
		cout << "日期非法\n" << endl;
	}
	return in;
}

返回一个对象的引用也是为了贴合内置类型使用规则。

到这里,你不免会问,如果将重载函数定义在了类的外部,那么该如何使用类内部定义的私有成员变量,如_year,_month,_day呢?别急,接下来补一下之前挖的坑,友元。

友元(friend)

在C++中,友元(Friend)是一个特殊的机制,它允许一个非成员函数或者一个类(或类的成员函数)访问另一个类的私有(private)或保护(protected)成员。友元不是类的成员,但它可以访问类的所有成员,包括私有和保护成员。这种访问权限的赋予是通过在类的定义中使用friend关键字来实现的。只需要在类的内部添加上类外定义的函数的声明,并在声明前加上关键字friend即可,一般这种友元函数允许写在类内部的任意地方,一般来说会把它放在整个类的开头。当一个函数成为一个类的友元,那么这个函数内部就可以随意使用类中的私有(private)或保护(protected)成员了

class Date
{
	// 友元
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
    //。。。
private:
    //。。。
}

结语

本篇博客实现了日期类Date,加深对运算符重载的运用,讲了前置++和后置++:传一个改变成后置++样式的int;还讲到const成员:由于无法改变*this类型而添加的const;流插入和流提取重载:由于无法改变传参顺序而定义到类的外部等等。这篇博客也算是对之前学到类和对象内容的一个阶段性的应用和总结吧。

博主后续还会产出更多有意思的内容,感谢大家的支持!♥

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

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

相关文章

【Qt】探索Qt框架:跨平台GUI开发的利器

文章目录 1. Qt框架概述1.1. Qt框架的优点1.2. Qt框架支持的系统1.3. Qt开发环境 2. 搭建 Qt 开发环境2.1. Qt SDK 的下载和安装2.2. 新建项目: 3. Qt 框架内容简介总结 在当今软件开发领域&#xff0c;跨平台性和用户界面的友好性是至关重要的。而Qt框架作为一款跨平台的C图形…

<计算机网络自顶向下> TCP拥塞

目录 TCP拥塞控制机制 TCP拥塞感知 TCP速率控制方法 TCP拥塞控制和流量控制的联合动作 TCP拥塞控制策略 TCP吞吐量 TCP公平性 TCP拥塞控制机制 端到端的拥塞控制机制 路由器不向主机提供有关拥塞的反馈信息 路由器负担较轻 符合网络核心简单的TCP/IP架构原则 端系统根据自…

【github主页】优化简历

【github主页】优化简历 写在最前面一、新建秘密仓库二、插件卡片配置1、仓库状态统计2、Most used languages&#xff08;GitHub 常用语言统计&#xff09;使用细则 3、Visitor Badge&#xff08;GitHub 访客徽章&#xff09;4、社交统计5、打字特效6、省略展示小猫 &#x1f…

浅谈命理学的男女婚姻篇

对于中国人来说&#xff0c;八字预测已成为生活中不可缺少的组成部分&#xff0c;不懂八字预测&#xff0c;就不会真正了解中国的传统文化。八字预测经历几千年的风风雨雨&#xff0c;是一种古老的中国命理学&#xff0c;通过生辰八字的天干地支的组合&#xff0c;可以推测一个…

[阅读笔记21][RA-CM3]Retrieval-Augmented Multimodal Language Modeling

这篇论文是meta联合斯坦福在23年4月发表的论文&#xff0c;提出了一个使用外部知识检索增强的多模态模型。 这篇模型提出的RA-CM3模型是第一个能够检索并生成图像文本的多模态模型&#xff0c;在图像文本生成任务上优于现有的多模态模型&#xff0c;同时使用更少的训练量。 RA-…

模型 框架效应

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。部分真相不等于真相。 1 框架效应的应用 1.1 框架效应在营销策略上的应用 亚洲航空公司面临的挑战是如何在竞争激烈的航空市场中吸引更多的顾客&#xff0c;并提高机票的预订率。这家低成本航空公司…

2.Vue简介

Vue简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;V…

Scala的函数至简原则

对于scala语言来说&#xff0c;函数的至简原则是它的一大特色。下面让我们一起来看看分别有什么吧&#xff01; 函数至简原则&#xff1a;能省则省&#xff01; 初始函数 def test(name:String):String{return name }1、return可以省略&#xff0c;Scala会使用函数体的最后一…

排序算法集合

912. 排序数组 趁着这道题总结下排序方法 1.快速排序 算法描述 1.从数列中挑出一个元素&#xff0c;称为"基准"&#xff08;pivot&#xff09;&#xff0c; 2.重新排序数列&#xff0c;所有比基准值小的元素摆放在基准前面&#xff0c;所有比基准值大的元素摆在基…

网络安全基础技术-常见web漏洞之XSS跨站脚本攻击

首先&#xff0c;我们来探究XSS&#xff08;跨站脚本攻击&#xff09;的基本概念。简而言之&#xff0c;这种攻击方式涉及将用户的输入错误地作为前端代码执行。在Web应用领域&#xff0c;前端代码通常由HTML、CSS和JavaScript三大构件组成&#xff1a; HTML&#xff08;超文本…

力扣HOT100 - 19. 删除链表的倒数第N个节点

解题思路&#xff1a; 链表题目&#xff1a;哑节点、栈、快慢指针&#xff08;双指针&#xff09; 方法一&#xff1a;计算链表长度 class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dum new ListNode(0, head);int len getLen(head);…

binary tree Leetcode 二叉树算法题

144.二叉树的前序遍历 前序遍历是&#xff1a;根-左-右 所以记录序列的的时候放在最前面 递归 class Solution {List<Integer> ans new ArrayList<>();public List<Integer> preorderTraversal(TreeNode root) {if(root null) return ans;ans.add(root…

书生·浦语大模型实战营Day05作业

作业 基础作业 完成以下任务&#xff0c;并将实现过程记录截图&#xff1a; 配置 LMDeploy 运行环境: 书生浦语大模型实战营Day05LMDeploy实践 以命令行方式与 InternLM2-Chat-1.8B 模型对话: 书生浦语大模型实战营Day05LMDeploy实践 进阶作业 完成以下任务&#xff0c;并将…

PCIe总线-PCIe配置空间介绍(三)

1.概述 配置空间是PCIe设备/桥的标识符&#xff0c;其保存了设备/桥的信息。主机在枚举设备/桥的时候需要先访问配置空间&#xff0c;获取设备厂家、型号、类型、所需资源等信息&#xff0c;然后再分配资源&#xff0c;最后才能访问PCIe设备的存储或IO地址空间。PCIe总线规定了…

JavaScript之分时函数、分时间段渲染页面、提高用户体验、参数归一化、高阶函数、分段、appendChild、requestIdleCallback

MENU 前言效果图html原始写法优化方式一(参数归一化)优化方式二(当浏览器不支持requestIdleCallback方法的时候)优化方式三(判断环境) 前言 当前需要向页面插入十万个div元素&#xff0c;如果使用普通的渲染方式&#xff0c;会造成延迟。这时候就需要通过分时函数来实现渲染了。…

【R数据分析-基础】

R语言介绍 为什么使用R&#xff1f; R&#xff1a;数据分析与可视化平台 R的获取和安装 http://cran.r-project.org 免费下载 一、R、Rtools安装 R语言&#xff1a; 免费开源 支持多平台&#xff0c;包括Windows、UNIX、Mac OS 擅长统计与可视化 Rtools&#xff1a;R语言…

Android安卓写入WIFI热点自动连接NDEF标签

本示例使用的发卡器&#xff1a;Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/网址/海报-淘宝网 (taobao.com) package com.usbreadertest;import android.os.Bundle; import android.view.MenuItem; import android.view.View; import android.widget.EditText; impo…

C++从入门到出门

C 概述 c 融合了3中不同的编程方式&#xff1a; C语言代表的过程性语言C 在C语言基础上添加的类代表的面向对象语言C 模板支持的泛型编程 1、在c语言中头文件使用扩展名.h,将其作为一种通过名称标识文件类型的简单方式。但是c得用法改变了&#xff0c;c头文件没有扩展名。但是…

大数据平台搭建2024(二)

二&#xff1a;Hive安装 只在node01上操作 1 安装MySQL 8.0 最小化安装需要安装这个 yum install -y wget1-1 下载MySQL的yum源 wget http://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm检查是否安装成功 rpm -qpl mysql80-community-release-el7-7.n…