C++ 基础回顾(下)

news2024/11/26 0:41:34

C++ 基础回顾(下)

目录

  • C++ 基础回顾(下)
    • 前言
    • 模板和泛型编程
    • 动态内存与数据结构
      • 动态内存
      • 数据结构
    • 继承与多态
      • 继承
      • 多态
    • 简单的输入输出
    • 工具与技术
      • 命名空间
      • 异常处理
      • 多重继承与虚继承
      • 时间和日期

前言

C++之前学过一点,但是很长时间都没用过,翻出了书从头看了一遍,简短地做了笔记,以便自己之后查看和学习。这是下篇,上篇链接:C++基础回顾(上)

C++语言中代码复用主要有四种形式:

  1. 函数,同一个代码模块可以重复调用
  2. 类,同一个类的不同对象公用同一种数据结构和一组操作
  3. 继承和多态,派生类可以重复使用基类代码,多态保证代码复用的灵活性
  4. 模板,泛型编程的基础,不同的实例化版本公用同一份代码设计,是创建类和函数的蓝本

模板和泛型编程

const int& getMax(const int &a,const int &b){
	return a>b ?a:b;
}
const string& getMax(const string &a, const string &b){
	return a>b?a:b;
} //两段代码中只有数据类型不同

在类中重载函数时,不同的数据类型需要重新定义,要是能够避开参数类型,使用参数类型的时候填充进去就好了。

函数模板就能够解决上面的问题

//getMax函数模板
template <typename T> //模板以关键字template开始,紧跟一个模板参数列表
const T& getMax(const T &a, const T &b){
	return a>b?a:b;
}

使用上述函数模板时,需要实例化。

模板的参数类型可以自行推断或者自己显式指明

cout<<getMax(1.0,2.5)<<endl; //推断参数类型T为double
cout<<getMax<double>(1.0, 2.5)<<endl; //显式指明

类成员模板

类的成员函数也可以定义为函数模板

class X{
	void *m_p =nullptr;
public:
	templarte<typename T>
	void reset (T *t){m_p =t;} //成员函数reset定义为一个函数模板

};

可变参函数模板

template <typename...Args> //可变数目的参数称为参数包,用省略号“...”表示,可以包含0~任意个模板参数
void foo(Args ...args){
	cout<<sizeof...(args)<<endl; //打印参数包args中参数的个数
}
foo(); //0个参数,输出0
foo(1,1.5); //输出2
foo(1,1.5,"C++"); //输出3

类模板

// 类模板的定义以关键字template开始,后跟模板参数列表
template<typename T, size_t N> //size_t是无符号整数,常用于数组的下标
class Array{
	T m_ele[N];
public:
	Array(){} //默认构造函数
	Array(const std::initializer_list <T> &); //initializer_list是支持有相同类型但数量未知的列表类型,这里没有写形参,应该是一个initializer_list 类型的引用常量
	T& operator[](size_t i);
	constexpr size_t size() {return N;}
};
//实例化类模板
Array<char,5>a;
Array<int,5>b ={1,2,3};

动态内存与数据结构

内存在对象创建时分配,在相应的时候比如离开作用域时回收内存。但有时候内存大开小用,根本不需要给对象分配这么多的内存,因此动态内存分配技术派上了用场

动态内存

动态对象是在动态内存中创建的,动态内存也称为自由存储区

new用来分配创建动态对象的内存,delete用来释放动态内存。

int *pi =new int; //在堆中创建一个int类型的对象,把他的地址放到指针对象pi中
delete pi; //delete后跟一个指向动态对象的指针,用来释放动态对象的存储空间
pi = nullptr; //上面pi指向的内存已经被释放了,pi是一个空悬指针。通常是在delete之后重置指针指向nullptr

内存泄漏

使用的过程中,一定避免造成无法释放已经不再使用的内存的情况,这种情况也称为内存泄漏

int i,*q =new int(2); 
q =&i; //错误:发生内存泄漏

智能指针

用来解决产生空悬指针或内存泄漏等问题

三种智能指针:

1. unique_ptr 独占所指向的对象,采用直接初始化
2. shared_ptr 允许多个指针指向同一个对象,采用直接初始化
3. weak_ptr 一种不控制所指对象生命期的智能指针,指向shared_ptr所管理的对象

三个指针都是类模板,定义在memory头文件中。

{
unique_ptr <int> p2(new int(207)); //类模板,实例化为int类型的,采用直接初始化
}//p2离开作用域被销毁,同时释放其指向的动态内存,也就是说p2消亡时,其指向的对象也会消亡,动态内存自动释放。
shared_ptr<int> p1(new int(100)); //直接初始化
shared_ptr<int> p1=new int(100); //赋值初始化,错误,只能使用直接初始化

动态数组

int n=5;
int *pa =new int[n]; //方括号中必须是整型,不必是常量,返回第一个元素的地址
delete [] pa; //释放内存,逆向销毁,首先销毁最后一个元素

数据结构

线性链表

线性表在逻辑上和物理结构上都是相邻的。在随机访问数据的时候,可能需要移动很多数据。链式结构则不需要逻辑上相邻的元素在物理结构上也相邻。

线性链表也叫单链表。每个数据元素占用一个结点(node)。一个结点包含一个数据域和一个指针域,其中指针域中存放下一个结点的地址。

单链表的结构

单链表利用指针head指向单链表的第一个结点,通过head指针,可以遍历每一个元素,最后一个元素的指针指向为空,尾部的tail指向表尾的结点。

链表中一般有push_back、earse、clear、insert等成员函数。

链栈

栈(stack)只能在一端进行插入和删除操作的线性表。

链栈结构

栈中一般有进栈、出栈、清空、取栈顶元素等操作。

二叉树

一棵非空树有且仅有一个根结点。每个结点的子树的数量为该结点的度(degree)。如结点B的度为3。度为0的结点称为叶子结点,如D、E、H等。

树结构

二叉树的定义为每个结点的度不超过2,但是至少要有一个结点的度为2。如下为二叉树的结构。

二叉树

二叉搜索树,任意一个结点的左子树的数据值都小于该结点的数据值,任意一个结点的右子树的数据值都大于等于该结点的数据值。

继承与多态

继承

继承是代码重用的重要手段之一,可以很容易地定义一个与已有类相似但是又不完全相同的新类。

被继承的称为基类,产生的新类称为派生类。如果一个派生类只有一个基类,称为单继承,如果有多个基类,称为多重继承。

以一个代码例子来讲解其中的原理。

class Person {  //基类
protected:  //而由protected限定符继承的可以访问其中的受保护成员,但是在派生类外不可访问。
	string m_name;//名字
	int m_age;	//年龄
public:
	Person(const string &name = ", int age = 0) :m_name (name), m age(age){}
    virtual ~Person()= default; //虚函数,下面有
    const string& name ()const{return m name;}
    int age()const{ return m_age;}
    void plusOneYear(){++m_age;}
	void plusOneYear() ++m age; //年龄自增
};
           
           
 //派生类,需指明基类,形式为" class 派生类名:访问限定符 基类名称{};"
class Student:public Person{ //学生类,公有继承Person 私有的和protected的无法访问,
private:
    Course m_course; //课程信息,也是一个类
public:
    Student(const string &name, int age, const Course &c):Person(name,age),m_course(c){}
    Course course(){return m_course;}
};
 

派生类对象的构造

Student::Student(const string &name, int age,const course &c):
	Person(name,age) /*初始化基类成员*/
    m_course(c)/*初始化自有成员*/
    {}

多态

多态性包括:编译时多态性和运行时多态性。编译时多态性指的是在程序编译时决定调用哪一个版本的函数,通过函数重载和模板实例化实现。运行时多态是属于一个接口,多种实现。**具体什么意思?**也就是说下面的虚函数,在基类中声明为虚函数是一个接口,在不同的派生类中却有着不同的实现。

虚函数

虚函数表明在不同的派生类中该函数需要不同的实现,因此将该基类中的该函数声明为虚函数。

内联函数、静态成员和模板成员都不能声明为虚函数 。因为这些成员的行为必须在编译时确定,不能实现动态绑定。

简单的输入输出

输入输出过程中,程序在内存中为每一个数据流开辟一个内存缓冲区。在输入操作过程中,从键盘输入的数据先放在键盘的缓冲区中,按回车键时,键盘缓冲区中的数据流到程序的输入缓冲区,形成cin流,然后用输入运算符>>从输入缓冲区中提取数据并将他们保存到与对象相关联的内存中去。输出操作过程中cout<<首先向控制台窗口输出数据时,先将这些数据送到程序中的输出缓冲区保存,知道缓冲区执行刷新操作,缓冲区中的全部数据送到控制台窗口显示出来。

输出缓冲区刷新的原因:缓冲区满、程序正常结束、遇到endl等。endl、flush、ends等都可以强制刷新缓冲区。

cout<<"endl"<<endl; //输出endl和一个换行,然后刷新缓冲区
cout<<"flush"<<flush; //输出flush(无额外字符),然后刷新缓冲区
cout<<"ends"<<ends; //输出ends和一个空字符('\0'),然后刷新缓冲区
//显然他们三个还是有所不同的

空白字符(空格符、制表符、回车符等)

这些字符会在输入时被系统过滤掉,想要获取这些这些字符,可以使用cin.get()

for(char c;(c=cin.get())!='\n') //只要不遇到'\n',就能继续输入
	cout<<c;
cout<<endl;

getline(cin,s); //该函数可以获取一行字符序列,遇到回车符结束,不包括回车符

格式化控制

格式化控制可以包括数据的进制、精度和宽度等

//数据进制控制
cout<<showbase<<uppercase; //showbase设置数据输出时显示进制信息,uppercase设置16进制以大写输出并且包含前导字符X
cout<<"default:"<<26<<endl; //默认
cout<<"octal:"<<oct<<26<<endl; //8进制
cout<<"decimal"<<dec<<26<<endl; //10进制
cout<<"hex"<<hex<<26<<endl; //16进制
cout<<noshowbase<<nouppercase<<dec; //输出形式恢复到默认

//上述输出的结果:
default:26
octal:032
decimal:26
hex:0X1A

浮点数格式控制:打印精度、表示形式、没有小数点部分的浮点值是否打印小数点

默认情况下,浮点数按照6位数字精度打印,并以舍入方式而不是截断方式打印。

可以利用setprecision函数或者IO对象的precision函数来指定打印精度。

//设置打印精度
double x = 1.2152;
cout.precision(3);  //此处precision接受整型值3,设置精度为3
cout<<"precision:"<<cout.precision()<<",x="<<x<<endl; //此处precision参数为空,返回当前精度
cout<<setprecision(4);
cout<<"precision:"<<cout.precision()<<",x="<<x<<endl;

//输出
precision:3, x=1.22 //四舍五入,不是截断
precision:4, x=1.215

设置输出格式,科学计数法,定点十进制等

cout <<"default format:"<<10*exp(1.0)<<endl;  //默认格式
cout <<"scientific:"<<scientific<<10*exp(1.0) <<endl; //科学计数法
cout <<"fixed decimal:"<<fixed<<10*exp(1.0)<<endl; //定点表示
cout <<"default float:"<<defaultfloat <<10*exp(1.0)<<endl; //恢复到默认状态

//输出
default format:27.1828
scientific:2.718282e+01
fixeddecimal:27182818
default float:27.1828

宽度控制setw可以指定输入输出数据占用的宽度,setw接受一个int值,若数据宽度大于设定int值,则按照实际输出,若小于,则采用右对齐,左边补空的方式输出。setfill则可以指定字符填补空白。

int i=-10;
double x=1.2152;
cout <<"i:"<<setw(10)<<i<<endl;
cout <<"x:"<<setw(10)<<x<<endl;
cout <<setfill('*')<<"x:"<<setw(10)<<x<<endl;

//输出
i:       -10
x:    1.2152
x:****1.2152

文件流

从键盘(cin)和控制台窗口(cout)是使用的IO流对象,如果要从磁盘读取数据或者向磁盘写入数据则需要文件流。

ifstream //从指定文件读取数据
ofstream //向指定文件写入数据
fstream //可以读写数据
ifstream in(ifname); //创建输入文件流对象in,提供文件名ifname初始化
ofstream out; //创建输出文件流对象,没有提供文件名
out.open(ofname); //没提供文件名的话,可以使用open函数关联一个文件。
if (out) //最好检测open操作是否成功
out.close(); //记得关闭文件

ios::in 以读方式打开文件。
ios::out 以写方式打开文件(默认方式)。如果已有此文件,则将其原有内容全部擦除;如果文件不存在,则建立新文件。
ios::app 以写方式打开文件,写人的数据追加到文件末尾。
ios::ate 打开一个已有的文件,并定位到文件末尾。
ios::binary 以二进制方式打开一个文件,如不指定此方式则默认为 ASCII方式。

工具与技术

命名空间

避免命名冲突,全局作用域分割成为许多子作用域,每个子域为一个命名空间。

namespace Foo {
	//放置任何可以放在全局作用域中的声明
}
//命名空间可以是不连续的,在这个文件中命名一点,在另一个文件中再命名一点也可以
//命名空间也可以嵌套
namespace Wang{
	namespace Li{
		int dosomething(int x,int y);
	}
}

//访问时则需要先访问外面的命名空间
int x =Wang::Li::dosomething(1,2);

内联命名空间

内联命名空间可以直接在全局作用域直接访问,而不需要加上命名空间名字

namespace FirstVersion {
	void fun(int);
}
inline namespace SecondVersion {
	void fun (int);
	void fun(double);
}


//调用
FirstVersion::fun(1);  //调用早期版本fun函数
fun(1);  //调用当前版本fun函数 即second
fun(1.0); //调用当前版本中新增的fun函数,即second

全局命名空间

定义在全局作用域的也就是在全局命名空间的,可以直接使用::来访问全局命名空间的成员

::memeber_name

异常处理

程序运行过程中可能会出现错误,为了保证大型程序在运行过程中不会出现错误,C++提供了异常的内部处理机制。包含try、catch、throw三个关键字

throw 抛出异常

try 检测可能会出现异常的代码

catch 捕获异常并处理

try检测异常出现后,系统则检查与try对应关联的catch子句,如果找不到则调用标准库中的函数。

double divide (int a, int b){
	if(b==0)
		throw "Error,division by zero!"; //抛出异常
	return a / b;
}


int a=1,b=0;
try {
	int c=divide(a,b); //异常检测
}
catch(const string &str){ //异常处理
	cerr <<str <<endl;  //cerr为标准错误ostream对象,常用于输出程序错误信息
}
catch(const char *str){  //匹配到这个异常处理,但是为什么匹配到这个不太懂,好像懂了,不对,还是不懂,好像是匹配到throw的异常时char风格的字符串
	cerr <<str<<endl;
}

标准库异常类,需要包含头文件exception

标准异常类的继承关系

try{
	throw MyException(); //抛出MyException类型的异常对象
}
catch(exception &ex){
	cerr <<ex.what() <<endl; //捕获
}

多重继承与虚继承

上文中已经提到多重继承,即一个派生类有多种基类,这也很正常,比如一个“学生”首先可以继承“人”这个类,他也可以继承“孩子”这个类,拥有多重身份。蝙蝠可以继承哺乳类,也可以继承飞行类。

多重继承有可能出现二义性问题。二义性而难题被称为死亡钻石问题。

class Animal{protected: //基类Animal
	int m_age;
public:
	Animal(int n =0):m_age(n){}
	virtual void eat(){}
};
class WingedAnimal:public Animal{ //继承Animal 
public:
	virtual void feedMilk(){}
};
class Mammal: public Animal{ //继承Animal
public:
	virtual void flap(){}
};

class Bat:public WingedAnimal,public WingedAnimal{}; //Bat多重继承
Bat b;
b.eat(); //二义性访问,继承的两个类中都继承了Animal中的eat(),该访问哪一个那

通过虚继承可以解决这样的问题

虚继承是将某派生类的基类声明为基类,那么该基类无论被其他人继承多少次,只共享唯一一份的虚基类成员

class WingedAnimal:virtual public Animal{/*...*/};
class Mammal :virtual public Animal[/* ...*/);

时间和日期

C++提供了对日期和时间进行操作的库chrono。该库中提供三个时钟类system_clock steady_clock high_resolution_clock

时钟类名称实时性
system_clock实时时钟
(随着真实世界的时间调整改变,比如夏令时会把标准时间拨早一小时,有吗?)
steady_clock单调时钟(不随外时间调整而改变)
high_resolution_clock实时时钟(精度更高)
using namespace chrono; 
time_t tt = system clock::to_time_t(system_clock::now());
//to_time_t函数将获取的时间点转换成time_t类型
//now获取其数据成员的时间点time_point

cout <<put time(gmtime(&tt),"F")<<endl; 
//gmtime函数将time_t类型函数转换为日历时间
//put_time函数将日历函数转换为时间标准输出流

//输出
2017-12-09 20:15:08
//输出时间间隔
auto start = steady_clock::now();
doSomething();  //执行某种算法
auto end = steady_clock::now();
auto interval = duration_cast <milliseconds > (end - start);
cout <<interval.count () <<endl;

本文的回顾并没有结束,还有一小部分内容没有写出,基本是一些具体函数的使用。
如果您觉得我写的不错,麻烦给我一个免费的赞!如果内容中有错误,也欢迎向我反馈。

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

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

相关文章

进销存管理系统是什么?进销存管理系统优点?

库存管理不当导致物资浪费/过期/损坏&#xff0c;增加企业成本和风险&#xff1b; 无法有效监控销售和采购流程&#xff0c;交易的准确性和时效性不到位&#xff1b; 财务管理混乱&#xff1b; ...... 你是否遇到过以上问题&#xff1f; 进销存管理系统&#xff08;Inventory …

Softing FG-200——将FF H1现场总线集成到工业以太网

基金会现场总线FF&#xff08;FOUNDATION Fieldbus&#xff09;是专为过程自动化设计的通信协议&#xff0c;包含低速总线H1&#xff08;31.25kbits/s&#xff09;标准和高速以太网HSE&#xff08;High Speed Ethernet&#xff0c;100Mbits/s&#xff09;标准。FF H1主要针对于…

200左右蓝牙耳机有哪些推荐?质量好的平价蓝牙耳机分享

现在蓝牙耳机基本上都是人手必备的存在了&#xff0c;对比上千元的蓝牙耳机&#xff0c;两百左右价位蓝牙耳机才是更多人的优先选择、废话不多说&#xff0c;下面我就来为大家推荐几款200元上下&#xff0c;质量和口碑都好的蓝牙耳机&#xff0c;准备入手蓝牙耳机的小伙伴可以作…

Mac配置QT

Mac配置QT 前言&#xff1a; 系统版本&#xff1a;Ventura 13.2.1 (22D68) 先安装homebrew&#xff0c;参考&#xff1a; https://blog.csdn.net/ZCC361571217/article/details/127333754 Mac配置&#xff1a; 安装Qt与Qt Creator&#xff1a; 通过Homebrew安装(若没Homeb…

VL817S与之前其他型号的区别与改动

相对于VL817C0以及VL817B0来说&#xff0c;VL817S使用外部供电不需要接入5V&#xff0c;HUB 5V 请参考参考设计接地。内部3.3 LDO输出请悬空。1。2V LX和FB请悬空。如下所示&#xff0c;详见参考设计。 1、3.3V和1.2V之间的时序要求是怎么样的&#xff1f; 下图是VL817(S) 上电…

无线技术有哪些专业术语,看完本文=半个无线专家

无线技术是指通过无线电波或光波等无线传输媒介&#xff0c;实现信息、数据或信号的传递和通信的技术领域。在无线技术领域中&#xff0c;有许多专业术语用于描述和标识不同的技术和概念。 以下是常见的无线技术专业术语的简介&#xff1a; Wi-Fi&#xff08;无线局域网&#…

磁盘这列(Raid)

RAID介绍 RAID技术通过把多个硬盘设备组合成一个容量更大的、安全性更好的磁盘阵列。把数据切割成许多区段后分别放在不同的物理磁盘上&#xff0c;然后利用分散读写技术来提升磁盘阵列整体的性能&#xff0c;同时把多个重要数据的副本同步到不同的物理设备上&#xff0c;从而…

ImageNet使用方法(细节)自用!

学习记录&#xff0c;自用。 1. 下载数据集 点击以下链接下载种子文件&#xff0c;然后使用迅雷进行下载&#xff0c;仅下载勾选的文件即可。 https://hyper.ai/datasets/4889/c107755f6de25ba43c190f37dd0168dbd1c0877e 2. 解压 找到下载好的ILSVRC2012_img_train.tar 和…

移动端布局rem与vw的区别

目录 1. rem 2. rem的弊端与优点 3. rem布局前注意点 4. vw 5. vw单位和%单位对比 6. vw布局前注意点 7. vue项目中使用vw 1. rem 先简单说下rem&#xff0c;官当文档是这样说的&#xff1a; rem是css中的长度单位&#xff0c;1rem 根元素html的font-size值。当页面…

【笔试强训选择题】Day6.习题(错题)解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、Day6习题&#xff08;错题&#xff09;解析 二、Day6习题&#xff08;原题&#xff09;练习 总结 前言 一、Day6习题&#xff08;错题&#xff09;解析…

chatgpt智能提效职场办公--ppt怎么做

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 导入PPT有 1.通过菜单导入 打开PowerPoint 找到菜单栏中的 点击"插入" 总结 最后的最后 以上是chatgpt能力的冰山一角。…

<Linux> 常用指令

文章目录ls 指令pwd命令cd 指令touch指令mkdir指令&#xff08;重要&#xff09;&#xff1a;rmdir指令 && rm 指令man指令cp指令mv指令cat指令more指令less指令&#xff08;重要&#xff09;head指令tail指令date指令Cal指令find指令&#xff1a; -namegrep指令zip/un…

Springboot —— 根据docx填充生成word文件,并导出pdf

文章目录前言将docx模板填充数据生成doc文件1、依赖引入2、doc文件转换docx&#xff0c;并标注别名3、编写java代码实现数据填充docx文件填充数据导出pdf(web)1、依赖引入2、字体文件3、编写工具类4、编写测试接口请求测试参考资料前言 在项目中碰见一个需求&#xff0c;需要将…

[4] 实现无头单向非循环链表

目录 一、框架 二、实现各个方法 三、测试各个方法 四、源码 一、框架 一个单向链表的节点&#xff0c;有数值域和下一个节点的地址 我们可以设计一个链表类&#xff0c;在这个链表类设计一个节点内部类&#xff0c;这里设计成内部类的形式&#xff0c;因为链表是由节点组…

《论文阅读》SetGNER:General Named Entity Recognition as Entity Set Generation

0.总结 不知道是不是大模型的流行还是什么其他原因&#xff0c;导致现在网上都没有人来分享NER模型的相关论文了~本文方法简单&#xff0c;代码应该也比较简单&#xff08;但是没见作者放出来&#xff09;。推荐指数&#xff1a;★★☆☆☆ 1. 动机 处理三种不同场景的NER 与…

python笔记:datetime

处理日期和时间 1 常量 MINYEAR datetime允许的最小年份 MAXYEAR datetime允许的最大年份 2 数据类型 datetime.date带有属性year,month,daydatetime.time带有属性hour,minute,second,microsecond,tzinfodatetime.datetime带有属性year,month,day,hour,minute,second,m…

【网络安全】文件包含漏洞

文件包含漏洞文件包含漏洞原理文件包含漏洞经常出现的函数尝试查看etc/passwd敏感文件渗透过程上传phpinfo和webshell到服务器并使用工具连接其他方式包含日志文件getshell包含环境变量getshell文件包含漏洞原理 文件包含漏洞是指&#xff0c;程序开发人员一般会把重复使用的函…

【C语言学习4——整型数据类型】

C语言学习4——整型数据类型整型数据类型用sizeof关键词来测量大小三位二进制表示的数值范围数值的补码表示法各种整型类型的数值范围是多少无符号整型整型数据类型 在上一节当中&#xff0c;我们遇到了用int关键词&#xff08;整数integer的缩写&#xff09;来表示一个整数的…

Python Qt5 入门教程

Python Qt5 入门教程 Python Qt5是一个强大的GUI工具包&#xff0c;可以用来设计各种桌面应用程序&#xff0c;包括图形用户界面、数据库应用程序等。本教程将带你入门Python Qt5&#xff0c;从安装开始到图形界面的设计以及常见的控件和事件。 安装 Python Qt5需要使用PyQt5…

好用的便签APP排行榜前十名?

我是一名时间管理与自律达人&#xff0c;而便签应用程序就是必备与理想的时间管理工具。经过自己长期的总结认为好用的电脑手机云便签APP应用程序应该具备以下功能。 1、多设备同步&#xff1a;可以方便地将电脑和手机之间的数据同步&#xff0c;随时随地管理便签内容。 2、分…