首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++时之律者的代码掌控:日期类计算器万字详解

  • 25-02-16 13:21
  • 3871
  • 8493
blog.csdn.net

文章目录

  • 1.基本构造实现
    • 1.1 获取某年某月的天数
    • 1.2 构造函数
    • 1.3 拷贝构造函数
    • 1.4 打印函数
  • 2.运算符重载接口实现
    • 2.1日期比较
      • 2.1.1 <运算符重载
      • 2.1.2 ==运算符重载
      • 2.1.3 <=运算符重载
      • 2.1.4 >运算符重载
      • 2.1.5 >=运算符重载
      • 2.1.6 !=运算符重载
    • 2.2 日期与天数的计算
      • 2.2.1 日期+=天数
      • 2.2.2 日期+天数
      • 2.2.3 日期−=天数
      • 2.2.4 日期−天数
    • 2.3 日期的自增自减
      • 2.3.1 前置++
      • 2.3.2 后置++
      • 2.3.3 前置−−
      • 2.3.4 后置−−
    • 2.4 日期-日期
    • 2.5 日期的输入输出
      • 2.5.1 <<运算符重载
      • 2.5.2 >>运算符重载
  • 3.代码展示
    • 3.1 Date.h
    • 3.2 Date.c
  • 希望读者们多多三连支持
  • 小编会继续更新
  • 你们的鼓励就是我前进的动力!

学习完C++类和对象,我们可以实现一个说简单也不简单的日期计算功能,该功能涉及大量的运算符重载知识点及细节,可谓是细节重重,那么本篇将手把手教会你自己写一个日期计算器?

在这里插入图片描述

传送门:日期计算器(网页版)

1.基本构造实现

1.1 获取某年某月的天数

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

口诀:(四年一润,百年不润) 或者 四百年一润

1.2 构造函数

Date(int year = 1900, int month = 1, int day = 1)
	:_year(year)
	,_month(month)
	,_day(day)
{}
  • 1
  • 2
  • 3
  • 4
  • 5

用于初始化创建的每一个实例

1.3 拷贝构造函数

Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通常拷贝构造函数用于用一个已经存在的对象初始化另一个对象,如Date d3(d1),等价于Date d3 = d1

但是像d1 = d2是两个已经存在的对象之间的复制,调用的是=的运算符重载,而不是拷贝构造

具体实现解析可以看往期博客:

传送门:C++天使的灵动心跳代码:类和对象(中下)

1.4 打印函数

void Print()
{
	cout << _year << '-' << _month << '-' << _day << endl;
}
  • 1
  • 2
  • 3
  • 4

用于打印日期类

2.运算符重载接口实现

2.1日期比较

2.1.1 <运算符重载

bool Date::operator < (const Date& x)
{
	if (_year < x._year)
	{
		return true;
	}
	else if (_year == x._year && _month < x._month)
	{
		return true;
	}
	else if (_year == x._year && _month == x._month && _year < x._year)
	{
		return true;
	}

	return false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

实现日期小于的比较,我们要先思考日期的比较需要分别比较年月日,从年开始依次比较,一旦成立则说明小于成立;反之应该是大于,小于不成立

?值得注意的是:

  1. 传参时要特别注意,运算符有几个操作数,就传几个参数,this指针也算在参数中,
    所以这里默认<左边的对象是用this指针传过去了,右边的对象引用传参(加const避免被传的数值被修改,引用传参提高效率)
  2. 这里的运算符重载函数是成员函数

在这里插入图片描述

调试状态下,转到反汇编比较可以观察到,两种写法的底层代码是一样的,说明了d1 < d2会转换成d1.operator<(d2)

如果是非成员函数的情况下呢?

bool Date::operator < (const Date& x1, const Date& x2)
{
	if (x1._year < x2._year)
	{
		return true;
	}
	else if (x1._year == x2._year && x1._month < x2._month)
	{
		return true;
	}
	else if (x1._year == x2._year && x1._month == x2._month && x1._year < x2._year)
	{
		return true;
	}

	return false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意在类内要添加友元的声明,在类外定义运算符重载函数时,要传两个参数,原因在于非成员函数没有隐含的 this 指针来指向调用对象。不像成员函数,通过 this 指针隐式获取左侧对象,只需要显式接收右侧对象作为参数

在这里插入图片描述
同样转到反汇编比较,可以观察到非成员函数下,d1 < d2会转换成operator<(d1, d2),底层代码也清晰的指出要传几个参数

2.1.2 ==运算符重载

bool Date::operator==(const Date& x)
{
	return _year == x._year
		&& _month == x._month
		&& _day == x._day;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

==的运算符重载很简单,直接返回即可,如果相等返回true;反之则为false

2.1.3 <=运算符重载

bool Date::operator<=(const Date& x)
{
	return *this < x || *this == x;
}
  • 1
  • 2
  • 3
  • 4

显而易见,注意左边的数是由this指针隐式传递,满足小于或等于都能成立

2.1.4 >运算符重载

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

		return false;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

大于的运算符重载和小于的同理,修改符号即可

但是这样写实在是太麻烦了,根据上面写的==的运算符重载,>=运算符重载和<运算符重载,可以极大的简化和日期类比较有关的函数

bool Date::operator > (const Date& x)
{
	return !(*this <= x);
}
  • 1
  • 2
  • 3
  • 4

<=的反面就是>,借助这一点能够减少很多不必要的代码

2.1.5 >=运算符重载

bool Date::operator>=(const Date& x)
{
	return !(*this < x);
}
  • 1
  • 2
  • 3
  • 4

同理,借助刚写完的>运算符重载也能简单的写出>=运算符重载函数

2.1.6 !=运算符重载

bool Date::operator!=(const Date& x)
{
	return !(*this == x);
}
  • 1
  • 2
  • 3
  • 4

==运算符重载取反即可

2.2 日期与天数的计算

2.2.1 日期+=天数

在这里插入图片描述
首先我们要明白日期+天数如何计算,那么经过举例演算可以发现,用进位的方式实现日期+天数,简单来说就是天满了往月进,月满了往年进,依赖于GetMonthDay函数处理每个月的天数,不断减掉天数直到合法为止

Date& Date::operator+=(int day)
{
	if (day < 0)
	{
		*this -= -day;
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}
	return *this;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

因为我们是在原本的日期上操作,所以是+=且引用返回,而不是+,注意加上负数等同于减去正数,也可以用abs取绝对值

Date& Date::operator+=(int day)
{
	*this = *this + day;
	return *this;
}
  • 1
  • 2
  • 3
  • 4
  • 5

+=还可以利用下面实现的日期+天数的运算来写

2.2.2 日期+天数

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 (tmp._month == 13)
		{
			++_year;
			tmp._month = 1;
		}
	}
	return tmp;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

那么真正的日期+天数,应该是不会修改原来的日期的,而是以另一个变量返回,所以这里就可以利用拷贝构造,将一个新的日期返回,注意不能引用返回,因为tmp是局部变量,出了作用域就被销毁了

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

	return tmp;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

同理+也可以利用日期+=天数来运算,但是这两种简洁的写法不可能同时存在,因为至少要有一种是完整实现了的,那么就可以对两种组合进行比对

在这里插入图片描述
考虑到变量的拷贝以及创建,明显是创建完整的+=运算,然后据此写+运算更优,因为这个组合创建的对象更少,减少对拷贝构造的调用

2.2.3 日期−=天数

在这里插入图片描述
举一反三,既然日期+天数是进位,那么日期-天数就是借位,每当被减成负数的时候,要注意是向上个月借天数,不是本月的天数

Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		*this += -day;
	}
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

和+=的写法其实大差不差,注意减去负数就是加上正数

2.2.4 日期−天数

Date Date::operator-(int day)
{
	Date tmp(*this);
	*this -= day;
	return tmp;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

利用-=运算减少不必要的算法,记得保存原先的日期

2.3 日期的自增自减

2.3.1 前置++

Date& Date::operator++()
{
	*this += 1;
	return *this;
}
  • 1
  • 2
  • 3
  • 4
  • 5

在+=运算的前提下,日期也是能实现自增的,所以不用担心自增后会不会越过当月的天数,在+=已经处理好了

2.3.2 后置++

Date Date::operator++(int)
{
	Date tmp = *this;
	*this += 1;
	return tmp;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

后置++需要提前保存值,因为是先使用再++

?值得注意的是:

  1. 前置++和后置++虽然是运算符重载,但是形式上也构成函数重载
  2. 后置++增加这个int参数不是为了接受具体的值,仅仅是占位,跟前置++构成重载
  3. int这个位置传任何值都可以,实际调用的时候前置++和后置++可能分别为d1.operator++()和d1.operator++(0),括号内的值是随机的

2.3.3 前置−−

Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
  • 1
  • 2
  • 3
  • 4
  • 5

−−的操作和++几乎是一样的,这里就不过多赘述了

2.3.4 后置−−

Date Date::operator--(int)
{
	Date tmp = *this;
	*this -= 1;
	return tmp;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.4 日期-日期

通常日期的计算我们一般是用来计算两个日期之前相差多少天,因此我们的运算符重载是否有意义决定了是否要创建这个重载,所以只考虑日期-日期,日期+日期是没有意义的
在这里插入图片描述
根据前面的算法,我们也能很容易总结出计算方法,把年份大的的日期的月份天数,假设成和一样的年份小的一样,然后两者作天数差的计算即可

其实还有更简单的思路,就是让年份小的日期一天一天去++

int Date::operator-(const Date& d)
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}
	return n * flag;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里最妙的是这个flag,能够刚好体现出计算的正负,虽然这种方式没有上面那种来的快,但是这种程度的差距对于计算机来说其实是可以忽略不计的

2.5 日期的输入输出

基本数据类型基于cout和cin的使用能够很方便的进行输入输出的操作,那么日期依托于运算符重载也能达到此类效果,cout和cin分别属于iostram库里的ostream和istream

2.5.1 <<运算符重载

根据前面的经验,我们依旧把<<运算符重载放在成员函数里

void Date::operator<<(ostream& out)
{
	out << d._year << "年" << d._month << "月" << d._day;
}
  • 1
  • 2
  • 3
  • 4

可是当我们输出的时候就报错了,这是因为正常情况下cout<会转化成d1.operator<,Date对象默认占用第一个参数,也就是做了左操作数,所以正确的写法应该是d1<才能正常输出,但是这样太奇怪了,完全不符合我们的使用习惯

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day;
	return out;
}
  • 1
  • 2
  • 3
  • 4
  • 5

既然不能写成成员函数,那就在类外写成非成员函数,就可以带入两个参数,cout<就会转化成operator<<(cout,d1),符合书写情况

?值得注意的是:

  1. cout从左往右连续输出,所以要返回ostream类型才能连续输出
  2. 类外访问私有变量使用友元函数就能解决
  3. ostream& out前不能加const,因为流插入就是不断改变cout的过程

2.5.2 >>运算符重载

istream& operator>>(istream& in, const Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}
  • 1
  • 2
  • 3
  • 4
  • 5

同理,流输入也是同样的格式

3.代码展示

3.1 Date.h

#include 
#include 
using namespace std;

class Date
{
public:
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& out, const Date& d);
	// 计算每个月的天数
	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;
	}

	// 全缺省的构造函数
	Date(int year = 1900, int month = 1, int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
	
	// 拷贝构造函数
	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
 // d2(d1)

	//打印日期
	void Print()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}

	bool operator < (const Date& x);
	bool operator > (const Date& x);
	bool operator >= (const Date& x);
	bool operator <= (const Date& x);
	bool operator==(const Date& x);
	bool operator!=(const Date& x);
	Date& operator+=(int day);
	Date operator+(int day);
	Date& operator-=(int day);
	Date operator-(int day);
	Date& operator++();
	Date operator++(int);
	Date& operator--();
	Date operator--(int);
	int operator-(const Date& d);
	
private:
	int _year;
	int _month;
	int _day;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

3.2 Date.c

//1.<运算符重载
bool Date::operator < (const Date& x)
{
	if (_year < x._year)
	{
		return true;
	}
	else if (_year == x._year && _month < x._month)
	{
		return true;
	}
	else if (_year == x._year && _month == x._month && _year < x._year)
	{
		return true;
	}

	return false;
}

//2.>的运算符重载
bool Date::operator > (const Date& x)
{
	if (_year > x._year)
	{
		return true;
	}
	else if (_year == x._year && _month > x._month)
	{
		return true;
	}
	else if (_year == x._year && _month == x._month && _year > x._year)
	{
		return true;
	}

	return false;
}

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

//3.=的运算符重载
///*void operator=(const Date& d)
//{
//	_year = d._year;
//	_month = d._month;
//	_day = d._month;
//}*/
//Date& Date::operator=(const Date& d)
//{
//	if (this != &d)
//	{
//		_year = d._year;
//		_month = d._month;
//		_day = d._day;
//	}
//	return *this;
//}

//4.==的运算符重载
bool Date::operator==(const Date& x)
{
	return _year == x._year
		&& _month == x._month
		&& _day == x._day;
}

//5.<=的运算符重载
bool Date::operator<=(const Date& x)
{
	return *this < x || *this == x;
}

//6.>=的运算符重载
bool Date::operator>=(const Date& x)
{
	return !(*this < x);
}

//7.!=的运算符重载
bool Date::operator!=(const Date& x)
{
	return !(*this == x);
}

//8.+=的运算符重载
Date& Date::operator+=(int day)
{
	if (day < 0)
	{
		*this -= -day;
	}
	//*this = *this + day;
	//return *this;
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}
	return *this;
}

//9.+的运算符重载
Date Date::operator+(int day)
{
	Date tmp(*this);
	tmp += day;

	return tmp;

	/*tmp._day += day;
	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	{
		tmp._day -= GetMonthDay(tmp._year, tmp._month);
		++tmp._month;
		if (tmp._month == 13)
		{
			++_year;
			tmp._month = 1;
		}
	}
	return tmp;*/
}

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

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

//12.-=的运算符重载
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		*this += -day;
	}
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

//13.-的运算符重载
Date Date::operator-(int day)
{
	Date tmp(*this);
	*this -= day;
	return tmp;
}

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

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

//16.日期-日期
int Date::operator-(const Date& d)
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}
	return n * flag;
}

//17.输出日期
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day;
	return out;
}

//18.输入日期
istream& operator>>(istream& in, const Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述

欢迎交流~长期互三互推交流可加v
微信名片
注:本文转载自blog.csdn.net的DARLING Zero two♡的文章"https://blog.csdn.net/Zero_VPN/article/details/145329738"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

106
编程语言
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top