C++ 类和对象(中篇)

news2025/1/25 4:26:43

类的6个默认成员函数

如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情 况下,都会自动生成下面6个默认成员函数。

构造函数:

定义:构造函数是一个特殊的成员函数,名字与类名相同,创建类 类型对象时由编译器自动调用,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次。

特性:

1.不是开空间创建对象,而是初始化对象。

2. 函数名与类名相同。

3. 无返回值。

4. 对象实例化时编译器自动调用对应的构造函数。

5. 构造函数可以重载


#include <iostream>
#include <assert.h>

using namespace std;


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

public:
	//1.无参构造函数
	Date()
	{
	
	}
	// 2.带参构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};

int main()
{
	Date d1; // 调用无参构造函数
	Date d2(2015, 1, 1); // 调用带参的构造函数
	// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
	// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象
	Date d3();
	return 0;
}

根据不同的初始化需求,去选择构造函数:

6.如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成

class Date
{
private:
	int _year;
	int _month;
	int _day;
	void MPrintf()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
};

int main()
{
// 没有定义构造函数,对象也可以创建成功,因此此处调用的是编译器生成的默认构造函数
	Date d1;
	d1.MPrintf();

	return 0;
}

7.无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参 构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。

默认成员函数分为:

为什么默认构造函数只能有一个?

回答:

当同时有无参构造函数和全缺省构造函数时,在实例化过程中编译器无法判断选择哪一种构造函数。

//为什么默认构造函数只能有一个?
class Date
{
private:
	int _year;
	int _month;
	int _day;

public:
	//1.无参构造函数
	Date()
	{
	
	}
	// 2.全缺省构造函数
	Date(int year=2018, int month=1, int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
		void MPrintf()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
};

int main()
{   
	// 调用无参构造函数
	Date d1; 
	//全缺省构造函数--注释1.无参构造函数
	Date d2(1111);
	d2.MPrintf();
	Date d3(2222, 2);
	d3.MPrintf();
	Date d4(3333, 3, 3);
	d4.MPrintf();
	return 0;
}

此时编译器是无法确定选择哪一种默认构造函数;

全缺省构造函数结果:

8.默认构造函数多用于自定义类型

对于自定义类型(复杂情况)我们会用构造函数的默认生成,更方便

class Time
{
public:
//默认构造
	Time()
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{

private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

调试结果:

对于内置类型,默认构造函数时不进行内容的改变,只保留随机值。

对于自定义类型,我们设置了他的默认成员函数,随机值进行了改变,在以后多次使用tmie类型是,他的初始化内容都会改变成自己一开始设置的初始化内容。

内置和自定义混合的,可以给内置缺省

此处不是初始化(空间没有创造就不能算是初始化,只能算是声明缺省值)

解释:默认构造没有参数传递,使用其原本的缺省值

由此得出:

默认生成构造函数:

1.内置类型成员不做处理

2.自定义类型成员,会去调用它的默认构造(不用传参数的构造)

建议:每个类都提供一个默认构造函数(内置类型->缺省构造)

析构函数:

定义:与构造函数功能相反,析构函数不是完成对象的销毁局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作

特征:

1. 析构函数名是在类名前加上字符 ~

2. 无参数无返回值。

3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。

4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

拷贝构造函数:
 

定义:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。(将已近实例化好的类型对象拷贝给将要实例化的新的对象的构造函数

特征:

1. 拷贝构造函数是构造函数的一个重载形式。

2. 拷贝构造函数的参数只有一个必须使用引用传参,使用传值方式会引发无穷递归调用。

为什么只传一个参数?

回答:其在结构体内部,本身还有一个隐形的This指针。

必须使用引用的原因?

回答:避免出现使用传值方式会引发无穷递归调用。--在拷贝时先准备启用拷贝构造函数,传值时会调用拷贝构造函数。这样会形成无穷递归调用。(不理解直接记成:拷贝构造函数必用引用


使用const的原因?

回答:在传递过程中,将可读可写的修改成const(只读)模式。将其权限缩小,避免因为自己思路的问题而导致原本值的改变。

3. 若未显示定义,系统生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝我们叫做浅拷贝,或者值拷贝。

代码:

#include <iostream>

using namespace std;

class Date
{
public:
	//构造函数-全缺省
	Date(int year = 2018, 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;
	//}
	void Mprintf()
	{
		cout << _year << "/" << _month<<"/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;
	d1.Mprintf();
	Date d2(d1);
	d2.Mprintf();

	return 0;
}

结果:

通过两次运行结果对比发现貌似这个拷贝构造函数有无都一样?

其实不然,C语言本身是对一些内置类型(int char等)在编译器的底层是有类似拷贝构造函数的结构的。

但是,面对一些自定义类型,或者申请有申请空间的情况,C语言不能满足需求

那就需要我们自己写专门针对自己的类的类型的拷贝构造函数

如以下代码:

无自己写的拷贝构造函数使用系统默认的拷贝构造函数

//开辟一个字符串空间
class String
{
public:
	String(const char* str = "jack")
	{
		_str = (char*)malloc(strlen(str) + 1);
		strcpy(_str, str);
	}
	//析构函数
	~String()
	{
		cout << "~String()" << endl;
		free(_str);
	}
private:
	char* _str;
};
int main()
{
	String s1("hello");
	String s2(s1);
}

此时默认的拷贝的运行结果就是错误。

什么情况下用拷贝构造函数:
自己实现了析构函数释放空间,就需要实现拷贝构造函数;

拷贝构造应用场景:

获取x天后的日期:

//拷贝构造应用场景
class Date
{
public:
	//构造函数--全缺省
	Date(int year = 2018, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//打印函数
	void Mprintf()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
	int GetMonthDay(int year,int month)
	{
		assert(month > 0 && month < 13);
		//正常情况下当前月数返回的天数,月从1开始,所以多加一位占位
		int monthArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		//闰年2月天数情况
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400) == 0))
		{
			return 29;
		}
		else
		{
			return monthArray[month];
		}
	}
	//x天后的日期
	Date GetAfterXDay(int x)
	{
		//因为不想改变初始日期所以使用拷贝
		Date tmp = *this;
		tmp._day += x;
		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;
	}

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2222, 2, 2);
	//d1.GetAfterXDay(100)调用类d1里的GetAfterXDay函数
	//返回一个Date类型的对象再拷贝到(Date d2=返回值)d2中
	Date d2 = d1.GetAfterXDay(100);
	d1.Mprintf();
	d2.Mprintf();
	return 0;
}

赋值运算符重载

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)(对于比较类,不需要更改值,常用const修饰)

用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不 能改变其含义

.* 、:: 、sizeof 、?: (三目运算符)、. 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

公共成员:

要在类外调用还得将声明对象的private改成public

class Date
{
public:
	Date(int year = 1111, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//private:
	int _year;
	int _month;
	int _day;
};
//d1与d2位置分别对应==的两端,不能修改
//参数和操作数(函数形参位置)是成正比的
bool operator==(const Date& d1, const Date& d2)
{
	return d1._year == d2._year
		&& d1._month == d2._month
		&& d1._day == d2._day;
}
int main()
{
	Date d1(2018, 9, 26);
	Date d2(2018, 9, 27);
	cout << (d1 == d2) << endl;
	//d1==d2会自动call对于函数地址
	//改变成->operator==(d1,d2)进行比较
}

为什么要在输出是加括号:

回答:因为<< 和== 优先级不同cout << d1 == d2 << endl;只会先识别cout << d1

成员函数:

class Date
{
public:
	Date(int year = 1111, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
//因为是成员函数,所以有其自身的this
// 完全展开后:bool operator==(Date* this, const Date& d2)
	bool operator==(const Date& d2)
	{
		return _year == d2._year
			&& _month == d2._month
			&& _day == d2._day;
	}
private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	Date d1(2018, 9, 26);
	Date d2(2018, 9, 27);
	d1 == d2;
	//因为是成员函数,其内部自身有隐藏this所以值传递一个值
	d1.operator==(d2);

	cout << (d1 == d2) << endl;
	cout << d1.operator==(d2) << endl;
}

并不局限于==除了.*    、   ::     、    sizeof     、   ?: (三目运算符)   、  .  这5个外都可以用operator(运算符)更改

运算符重载的复用:

代码:

//运算符重载的复用
class Date
{
public:
	Date(int year = 1111, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//因为是成员函数,所以有其自身的this
	// 完全展开后:bool operator==(Date* this, const Date& d2)
	bool operator==(const Date& d2)
	{
		return _year == d2._year
			&& _month == d2._month
			&& _day == d2._day;
	}

	//复用!!
	//由于已知了==,根据==就能写出!=(> < >= <=(小于或等于)同理)
	bool operator!=(const Date& d)
	{
		return !(*this == d);
		//相等1再!->false
		//不等0再!->true
	}
private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	Date d1(2018, 9, 26);
	Date d2(2018, 9, 27);
	cout << (d1!=d2) << endl;//显示1,true
	return 0;
}

赋值运算符重载 =

主要特点:

1. 参数类型

2. 返回值

3. 检测是否自己给自己赋值

4. 返回*this

5. 一个类如果没有显式定义赋值运算符重载编译器也会生成一个,完成对象按字节序的值拷贝

赋值运算使用:

常用域自己实现了析构函数释放空间,就需要使用自己编写的赋值运算符重载;

class Date
{
public:
	Date(int year = 1111, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Mprintf()
	{
		cout << _year << "/" << _month<<"/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

class String
{
public:
	//构造
	String(const char* str = "")
	{
		_str = (char*)malloc(strlen(str) + 1);
		strcpy(_str, str);
	}
	//析构
	~String()
	{
		cout << "~String()" << endl;
		free(_str);
	}
	void Mprintf()
	{
		cout << _str << endl;
	}
private:
	char* _str;
};

int main()
{
	Date d1(2222, 9, 26);
	Date d2(3333, 9, 27);
	String s1("hello");
	String s2("world");

	d1.Mprintf();
	d2.Mprintf();
	s1.Mprintf();
	s2.Mprintf();

	//编译器生成的默认赋值重载函数已经可以完成字节序的值拷贝了
	d1 = d2;//正常
	s1 = s2;//报错
	//此时,自己没有写赋值重载函数,当s2赋值给s1后
	//s1和s2同时指向相同的一块空间(s2开出的)
	//后序清理资源,清理s2的时候,s1所指向的空间也会改变
	//所以错误,编译器不通过
	d1.Mprintf();
	s1.Mprintf();
	return 0;
}

这里想要将s2的值赋值给s1就得自己写赋值函数了

连续赋值

有返回值用于支持这里的连续赋值,保持运算符的特性

eg.i=j=k;连续赋值的顺序是先j=k后返回j再i=j;

所以由于以上连续赋值的可能性,也要考虑赋值运算符重载的连续赋值的可能。


class Date
{
public:
	Date(int year = 1111, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Mprintf()
	{
		cout << _year << "/" << _month<<"/" << _day << endl;
	}
	//d3=d2=d1
	//返回的是赋值的左操作数所以返回*this
	//返回后该操作数的生命周期还存在所以用引用返回
	Date& operator=(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;

		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(1111, 1, 1);
	Date d2(2222, 2, 2);
	Date d3(3333, 3, 3);
	d1.Mprintf();//1111,1,1

	d1 = d2 = d3;
	d1.Mprintf();//3333,3,3

	return 0;
}

自己给自己赋值

有时不小心的操作可能会造成自己给自己赋值的情况

所以还需要在自己写的赋值情况中加入if判断

总结:

赋值重载和拷贝构造区别:

赋值重载是多个已近定义出来的对象

拷贝构造是一个已经实例化的对象初始化另一个未实例化的对象

在使用引用返回时,不能盲目的为了追求使用引用返回而使用静态变量static

静态变量static在整体函数调用中,只会初始化他的第一次,再次走到static内一步时,不会再初始化,而是使用其之前的值;

++a和a++区别:

这里int在vs中传0,编译器不一样传的值也不一样。

const成员函数:

const修饰类的成员函数

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

不管类成员函数中变量有多少,const都只针对*this修饰

友元标志:

背景:有时我们的公共函数也想在类里用,但苦于一个已经处于封装好了,那就用友元,来让他们增加一层关系使得,类中你能用到公共函数;

本段代码背景:生成日期每次都有._year    ._month……很多很麻烦但是同时cout有事已经封装好的库,不能随意改动,那就只能用运算符重载+函数重载

#include <iostream>
#include<assert.h>

using namespace std;

class Date
{
	//友元:
	friend ostream& operator<<(ostream& out, const Date& d);
public:
	Date(int year = 2024, int month = 4, int day = 9)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;

};

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

int main()
{
	Date d1;
	Date d2(1111, 1, 1);
	cout << d1 << d2 << endl;
	return 0;
}

为什么不直接写在类里?

回答:
直接写变成ostream& operator<<(ostream& out)默认做操作数成*this,和本来顺序相反了

const修饰隐藏指针this

class Num
{
public:
	//举例
	void Print() const
	{
		cout << _a << endl;
	}
private:
	int _a=10;
};

int main()
{
	Num a1;
	a1.Print();
	return 0;
}

总结:

内部 (类中) 不改变成员变量(_a)的  成员函数最好加上const增强代码健壮性;

此处const值修饰This指针,不管()中有多少参数

取地址及const取地址操作符重载

取地址编译器会默认生成一个一般是不需要我们特别再写一个

直接打印地址

成员函数有可能是普通成员函数也有可能是const修饰的成员函数

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

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

相关文章

【PHP系统学习】——Laravel框架数据库的连接以及数据库的增删改查的详细教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【招贤纳士】长期有效

【招贤纳士】长期有效&#xff0c;有意者联系 一、SLAM算法工程师工作内容&#xff1a;任职资格&#xff1a; 二、规划算法工程师工作内容&#xff1a;任职资格&#xff1a; 工作地点&#xff1a;深圳南山 公司行业&#xff1a;家用扫地机器人 待遇从优&#xff0c;有机器人比赛…

CAD导入GIS平台常见问题大全

1.CAD导入图新地球报【坐标超出范围】、【导入失败】 一般是投影不对&#xff0c;多数是中央经线选错了&#xff0c;或者是没注意是否有带号 这种情况&#xff0c;先打开CAD软件&#xff0c;通过id命令看一下数据的坐标&#xff0c;如下图 看到坐标是这样式的&#xff0c;X达…

达梦数据库审计相关参数

达梦数据库审计相关参数 基础环境 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本&#xff1a;DM Database Server 64 V8 架构&#xff1a;单实例1 查看审计相关的参数 查看AUD相关的参数。 1.1 查看dm.ini配置文件。 在dm.ini配置文…

gurobi不同版本切换

每年年底&#xff0c;gurobi都会推出新版本。新版本是大的迭代更新&#xff0c;求解问题的效率和精度都会提升。官方人员一般会建议我们安装最新的版本&#xff0c;此外&#xff0c;写论文审稿专家也会建议我们使用较新的版本。 从我们现装的版本切换到新版本。我以往的做法是…

【CVE-2023-38831】进行钓鱼攻击的研究

本文仅仅是对相关漏洞利用的学习记录&#xff0c;请各位合法合规食用&#xff01; WinRAR是一款文件压缩器,该产品支持RAR、ZIP等格式文件的压缩和解压等。WinRAR在处理压缩包内同名的文件与文件夹时代码执行漏洞,攻击者构建由恶意文件与非恶意文件构成的特制压缩包文件,诱导受…

【负载均衡——一致性哈希算法】

1.一致性哈希是什么 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时&#xff0c;发生过多的数据迁移的问题。 一致哈希算法也用了取模运算&#xff0c;但与哈希算法不同的是&#xff0c;哈希算法是对节点的数量进行取模运算&#xff0c;而一致哈希算法是对 2^32 进…

吴恩达机器学习理论基础—决策树模型

吴恩达机器学习理论基础—决策树模型 决策树模型&#xff08;Decision Trees&#xff09; 采用猫狗分类的数据集&#xff0c;同时拥有三个基本的特征&#xff08;输入&#xff09;作为模型建立时使用的数据集。 将构造出来的决策树&#xff0c;分为了决策结点和叶子节点&#…

【C++入门】内联函数、auto与基于范围的for循环

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

2024-04-08

作业要求&#xff1a; 1> 思维导图 2>使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否…

【日常记录】【JS】一道解构面试题

文章目录 1、描述2、分析与实现3、参考链接 1、描述 让这一段代码可以执行&#xff0c;并且正确输出 let [name, age] {name: 呆呆狗,age: 20}console.log(name, age);2、分析与实现 在浏览器上执行这段代码会报错 翻译以下&#xff1a;不是可迭代对象 可迭代对象&#xff08;…

Go——面向对象

一. 匿名字段 go支持只提供类型而不写字段名的方式&#xff0c;也就是匿名字段&#xff0c;也称为嵌入字段。 同名字段的情况 所以自定义类型和内置类型都可以作为匿名字段使用 指针类型匿名字段 二.接口 接口定义了一个对象的行为规范&#xff0c;但是定义规范不实现&#xff…

MT3022 召唤神龙

思路&#xff1a;二分答案 。check():检查组p套卡是否成立&#xff0c;即检查r卡是否足够组成p套卡。 &#xff08;易错点&#xff1a;check的思路&#xff0c;开long long&#xff09; #include <bits/stdc.h> using namespace std; long long int n, m; long long int…

JavaScript逆向爬取实战——使用Python实现列表页内容爬取

JavaScript逆向爬取—使用Python实现列表页内容爬取 1. 案例介绍 案例网址&#xff1a;https://spa6.scrape.center/&#xff0c; 如图所示&#xff1a; 点击任意一步电影&#xff0c;观察一下URL的变化&#xff0c;如图所示&#xff1a; 看到详情页URL包含了一个长字符串&am…

力扣HOT100 - 189. 轮转数组

解题思路&#xff1a; 三次反转。 先反转一次&#xff0c;再根据 k 拆分成两部分各反转一次。 class Solution {public void rotate(int[] nums, int k) {k % nums.length;reverse(nums, 0, nums.length - 1);reverse(nums, 0, k - 1);reverse(nums, k, nums.length - 1);}pu…

使用Docker中构建Java jar包,并且实现开启自启

文章目录 1.创建Dockerfile2.构建Docker镜像3.运行Docker容器4.后台运行并且可以开机自启4.1 在后台运行Docker容器4.2 设置开机自启动容器4.3 在Docker守护程序启动时自动启动容器 Docker中构建Java JAR包 要在Docker容器中构建Java应用程序的JAR包&#xff0c;你可以遵循以下…

RISC-V GNU Toolchain 工具链安装问题解决(stdio.h 问题解决,pk fence.i 问题解决)

我的安装过程主要参照 riscv-collab/riscv-gnu-toolchain 的官方 Readme 和这位佬的博客&#xff1a;RSIC-V工具链介绍及其安装教程 - 风正豪 &#xff08;大佬的博客写的非常详细&#xff0c;唯一不足就是 sudo make linux -jxx 是全部小写。&#xff09; 工具链前前后后我装了…

Docker容器嵌入式开发:在Ubuntu上配置Postman和flatpak

在 Ubuntu 上配置 Postman 可以通过 Snap 命令完成&#xff0c;以下是所有命令的总结&#xff1a; sudo snap install postmansudo snap install flatpak在 Ubuntu 上配置 Postman 和 Flatpak 非常简单。以下是一些简单的步骤&#xff1a; 配置 Flatpak 安装 Flatpak&#x…

【Redis】底层跳表实现

先巩固Redis的数据类型以及底层的数据结构&#xff1a; ZSet&#xff08;有序集合&#xff09;可以使用两种不同的内部数据结构来表示&#xff1a;压缩列表&#xff08;ziplist&#xff09;和跳跃表&#xff08;skiplist&#xff09;。 跳表是redis底层SortedSet(ZSet)的数据…

PostgreSQL入门到实战-第九弹

PostgreSQL入门到实战 PostgreSQL数据过滤(二)官网地址PostgreSQL概述PostgreSQL中and操作理论PostgreSQL中and操作实操更新计划 PostgreSQL数据过滤(二) 了解PostgreSQL AND逻辑运算符以及如何使用它来组合多个布尔表达式。 官网地址 声明: 由于操作系统, 版本更新等原因, …