自己曾经的C++笔记【在c盘爆满的时候找到的回忆】
文章目录
- **C与C++的区别** (二)
- 类和对象
- 构造函数和析构函数
- C++特殊成员
- C++友元
- C++类的继承
- C++虚函数和多态
- C++模板
- C++可变参模板
- C++STL容器篇
- C++迭代器
- C++仿函数
- C++函数适配器
- C++STL算法
- C++智能指针
- C++类型推断
- C++IO流
- C++正则表达式
- 具有特殊意义的元字符
- 量词元字符
- 校验数字的表达式
- 校验字符的表达式
- 特殊需求表达式
C与C++的区别 (一)
-
命名空间
- 基本语法
//空间名 namespace 标识符 {//变量//函数//结构体//类 } namespace MM {int age;char name[20]; }- 如何访问空间中的东西: 空间名::空间中的成员
//基本访问方式 //相对于C语言来说,需要一个前缀 //:: 作用域分辨符 MM::age=1001; strcpy(MM::name,"灰姑凉"); //省略前缀 using namespace 空间名; //省略当前这个空间名使用using 语法注意点是: 防止空间变量或者函数不要和空间外的变量或者函数名字相同
- 命名空间的嵌套
namespace A {int num;namespace B{int age;} } //如何访问: 剥洋葱 A::num=1001; A::B::age=18; //省略前缀 using namespace A; using namespace A::B; num=1991; age=1992 -
C++最简单的程序
#include <iostream> #include <stdio.h> #include <ctime> #include <cstdlib> using namespace std; int main() {return 0; }- 头文件的改变
- 标准输入输出头文件: #include
- 包含C语言的文件: #include 当然用#include <xxx.h>
- 自己写的头文件还是用C语言的方式包含 #include ”myhead.h“
- 基本输出的改变: cout 加上<<
- 不再需要格式控制字符
- 依然支持转移字符
- 换行: endl替换\n
- 基本输入的改变: cin 加上>>
- 不再不需要格式空字符
#include <iostream> #include <stdio.h> #include <ctime> #include <cstdlib> void testPrint() {int age=1;char name[20]="老babay";double dNum=1.1;std::cout << age << "\n";std::cout << age << "\t" << name << "\t\t" << dNum << "\n";using namespace std; //一般情况这句话会写头文件下面cout << age << "\t" << name << "\t\t" << dNum << "\n";cout << age << "\t" << name << "\t\t" << dNum << endl;//cout.put('A'); IO流中讲 } void testInput() {char name[20];int age;int num;//单个数据输入std::cout << "请输入一个整数:";std::cin >> age;std::cout << "请输入name,age,num:";std::cin >> name >> age >> num;std::cout << name << "\t" << age << "\t" << num << std::endl; } int main() {testPrint();testInput();return 0; } - 头文件的改变
-
C++数据类型的改变
- 空指针的改变: NULL 改为nullptr
- bool类型引入
- 赋值为: true ,false
- 非零值非空值表示成立,只有0和空表示不成立
- bool占用字节数是1
- 打印结果只有两个值: true:1 false: 0
- 一般条件表达式或者逻辑表达式,或者充当开关变量,标记变量
-
引用类型: C++极其重要的类型
- 基本用法: 起别名
类型& 标识符1=标识符2 //标识符2有一个别名字的叫做标识符1, 他们是一个东西- 常引用: 给常量起别名
const 类型& 标识符=常量;- 右值引用: 给右值起别名
类型&& 标识符=右值-
引用的用法
- 当做函数参数:防止拷贝本的产生
- 当做函数返回值: 增加左值使用用法(等效返回值一个变量)
-
自动推断类型: auto类型
#include <iostream> using namespace std; bool empty(int size) {return size == 0; } //Reference types 引用类型 int returnValue(int num) {return num; } int num = 0; int& returnValueReference() {return num; //warning C4172: 返回局部变量或临时变量的地址: num } void SwapC(int a, int b) //int a=实参1 int b=实参2 {int temp = a;a = b;b = temp; } void SwapCpp(int& a, int& b) //int &a =实参1 ,int &b=实参2 {//以后想要在子函数中修改什么,传入相应的引用int temp = a;a = b;b = temp; } void modify(int* &p) {p = # } //const在C++上面更为严格,类型需要严重性的一致 //如果你想要既可以传入常量也可以传入变量,需要const修饰 void printConstValue(const char* str) {cout << str << endl; } //只需要传入常量 void printOnlyConstValue(int&& num) {cout << num << endl; } void testReferenceTypes() {//3.1 基本用法int a = 1;int& b = a; //a就是b b就是ab = 100;cout << a << endl;cout << b << endl;//int& constNum = 12; //常量的引用,这样是错误的 const int& constNum = 12;//右值引用也可以表示常量int&& rightValue = 1001;//3.2 引用的用法//充当函数参数:防止拷贝本产生//当做函数返回值: 增加左值使用 不能返回局部变量引用//返回值是一个值//returnValue(num) = 12; //错误//1 = 2;returnValueReference() = 1111;cout << num << endl;//充当函数int aa = 1;int bb = 2;SwapC(aa, bb);cout << aa << "\t" << bb << endl;SwapCpp(aa, bb); //注意不需要取地址传参cout << aa << "\t" << bb << endl;int* p = nullptr;modify(p);cout << *p << endl;//常引用传参printConstValue("ILoveyou");//右值引用当做函数参数,只能传入右值printOnlyConstValue(1212);//move可以把左值变成右值printOnlyConstValue(move(num)); }//auto类型 int Max(int a, int b) {return a > b ? a : b; } void printMax(int(*p)(int, int), int a, int b) {cout << p(a, b) << endl; }void testAuto() {//5.1 不能单独定义变量//auto a; 错误//5.2 auto一般结合赋值使用auto intNum = 1;cout << intNum << endl; //intint (*pMax)(int, int) = Max;auto ppMax = Max;cout << ppMax(1, 2) << endl;auto pp = printMax;pp(ppMax, 1, 2); }int main() {//1.基本数据类型的改变int* p = nullptr;//2.bool类型引入bool bNum = true; //正常赋值,用true和false//非正常的赋值bNum = -111;cout << bNum << endl; //1//3.引用类型testReferenceTypes();//4. :: 作用分辨符//就近原则int num = 100000;cout << num << endl;cout << ::num << endl; //代表是全局区变量//5.自动推断类型testAuto();return 0; } -
C++函数的改变
-
内联思想: 函数以二进制形式存在,去提高效率
-
内联函数:用inline修饰的函数
-
短小精悍
-
在结构体中或者类型实现的函数,默认为内联
-
-
重载思想: C++允许同名不同参的函数存在
- 参数个数不同
- 参数类型不同
- 参数顺序不同(建立在存在不同类型)
- 常属性的成员函数和类中的普通函数重载 (类中会讲)
-
缺省思想: 给函数形参初始化,达到不同形态的函数调用
- 缺省的顺序 必须是从右往左,连续缺省
- 缺省时候,要避免存在普通函数,防止存在二义性
-
Lambda表达式: 函数的定义 并且返回一个函数指针,所以一般在C++中会结合auto使用
[捕获方式](函数参数)能否修改 是否存在异常->函数返回值类型{函数体;}; 捕获方式: 理解使用函数外面的变量的方式 1.[] 2.[=] 3.[&] 4.[&x,=] 5.[this] 类中数据成员的捕获 函数参数: 自己写函数的时候的函数参数 能否修改: mutable 是否存在异常: throw() 不存在异常 函数返回值类型:自己写函数的时候的函数返回值 函数体: 原来函数的函数体 //注意点: 一般在用的时候,能否修改 是否存在异常->函数返回值类型 是可以省略 [捕获方式](函数参数){函数体;};
#include <iostream> using namespace std; inline int Max(int a, int b) {return a > b ? a : b; } //1.参数的数目不同 void print(int a, int b, int c) {cout << a + b + c << endl; } void print(int a, int b) {cout << a + b << endl; } //2.参数的类型不同 void print(char a, char b) {cout << a + b << endl; } //3.顺序不同 //错误,不可以跟上面函数构成重载 //void print(char b, char a) //{ // cout << a + b << endl; //} void print(int age, double num) {cout << age << "\t" << num << endl; } void print(double num, int age) {cout << age << "\t" << num << endl; } //const属性不构成重载 //void print(int a) //{ // cout << a << endl; //} //void print(const int a) //{ // cout << a << endl; //} //4.缺省:不传入参数使用默认参数 void printValue(int a=1, int b=2, int c=3,int d=4) {cout << a + b + c + d << endl; } //5.Lambda表达 void printMax(int(*p)(int, int), int a, int b) {cout << p(a, b) << endl; } void testLambda() {//最完整的Lambda表达式//int Max(int a, int b) int(*pMax)(int, int) = [](int a, int b)mutable throw()->int {return a > b ? a : b; };//一般用的时候,怎么简单怎么来,结合auto+省略的Lambda表达式去使用auto p= [](int a, int b){return a > b ? a : b; };cout << p(1, 2) << endl;//进阶一下: 函数的定义和调用写在一起cout << [](int a, int b) {return a > b ? a : b; }(1, 3) << endl;printMax([](int a, int b) {return a + b; }, 3, 4);printMax([](int a, int b) {return a - b; }, 3, 4);//捕获方式int num = 1;//[]() {cout << num << endl; };错误 没有捕获方式,表示没用权力auto p1=[=]() {cout << num << endl; };auto p2 = [&]() {cout << num << endl; };p1(); //打印1p2();num = 1001;p1(); //不会因为值的改变而改变调用 ,打印1p2();//[this] 后面讲了类的时候在讲 } int main() {cout << Max(1, 2) << endl;print(1, 2, 3);print(1, 2);print('A', 'B');print(1, 1.1);print(1.1, 1);printValue(); //a=1,b=2,c=3,d=4;printValue(11); //a=11,b=2,c=3,d=4;printValue(11, 22); //a=11,b=22,c=3,d=4testLambda();return 0; } -
C与C++的区别 (二)
-
动态申请内存的区别
- C语言中申请内存: realloc malloc calloc C++中只有new
- C语言释放内存: free C++中 delete
#include <iostream> #include <cstdio> #include <assert.h> #include <cstring> //和#include <string>有区别 using namespace std; struct MM {char name[20];int age; }; void testNewMemory() {//1.申请单个变量内存int* pC = (int*)malloc(sizeof(int));assert(pC);*pC = 123;free(pC);pC = nullptr;int* cpp = new int;*cpp = 123;cout << *cpp << endl;delete cpp;cpp = nullptr;//2.申请一段内存 一维数组int* pcArray = (int*)malloc(sizeof(int) * 3); //int pcArray[3];assert(pcArray);pcArray[0] = 1;cout << pcArray[0] << endl;free(pcArray);pcArray = nullptr;int* cppArray = new int[3]; //int cppArray[3];cppArray[0] = 1;cout << cppArray[0] << endl;delete[] cppArray;cppArray = nullptr;//3.申请内存并做初始化//C语言有一个calloc//3.1 单个数据用()int* pNum = new int(100); //*pNum=100cout << pNum << endl;delete pNum;pNum = nullptr;//3.2 多个数据用{}int* pArray = new int[3]{ 1,2,3 }; //int pArray[3]={1,2,3};for (int i = 0; i < 3; i++) {cout << pArray[i] << "\t";}cout << endl; } //C++允许你重新管理申请堆内存 void testReNew() {char* sum = new char[100];//前面十六个字节存放4个整数//(sum + 0)代表是从那个位置开始申请int* pInt = new(sum + 0) int[4]{1,2,3,4};//来10个字节存储字符串char* pstr = new(pInt + 4) char[10]{"ILoveyou"};//等效:char* pstr = new(sum + 16) char[10]{"ILoveyou"};cout << sum + 16 << endl;cout << pstr << endl;//....delete[] sum;sum = nullptr; } void testUserData() {//结构体不需要struct关键字//单一结构体也是{}初始化MM* pMM = new MM { "张三", 18 };cout << pMM->name << "\t" << pMM->age; } int main() {testNewMemory();testReNew();testUserData();return 0; } -
C++结构体的基本区别
-
类型上: 不在需要struct ,直接结构体名可以充当类型,.c文件必须struct关键字
-
访问方式和C语言没区别
- 必须要用结构体变量访问
- 变量访问的方式: 变量.成员
- 指针表示,访问: 指针->成员
-
C++结构体中允许存在函数
- 结构体中的函数如何访问数据:直接访问
- 结构体中函数如何在类外实现:函数名必须要用:结构体名::函数名
- 通过结构体中的函数去设置结构体数据
- C++结构体申请内存
#include <cstring> #include <iostream> using namespace std; struct MM {//数据成员char name[20];int age;//成员函数void print() {cout << name << "\t" << age << endl;}void printData();void setData(const char* mmName, int mmAge); }; void MM::printData() {cout << name << "\t" << age << endl; } void MM::setData(const char* mmName, int mmAge) {strcpy_s(name,20, mmName); //"宝宝"age = mmAge; //19 } void testCppStruct() {//1.基本的访问方式MM mm = { "张三",19 };cout << mm.name << "\t" << mm.age << endl;MM* pMM = &mm;cout << pMM->name << "\t" << pMM->age << endl;//2.C++结构体中的函数的访问mm.print(); //打印就是mm.name,mm.agepMM->print();MM baby = { "baby",19 };baby.print(); //baby.name, baby.agebaby.printData();//3.通过函数去描述行为MM boy;boy.setData("宝宝", 19); //boy.name="宝宝",boy.age=19boy.print(); //boy.name ,boy.age//4.C++结构体申请内存//这种写法是建立在没有构造函数的基础下是对的MM* p = new MM;p->setData("申请内存", 199);p->print();delete p;p = nullptr;MM* pArray = new MM[3]; for (int i = 0; i < 3; i++) {pArray[i].setData("数组", i + 19);pArray[i].print();}delete[] pArray;pArray = nullptr; } int main() {testCppStruct();return 0; } -
-
C++中string: 本节课只需要知道如何使用C++string即可,不需要知道为什么这样用
-
首先需要知道C++string 是一个类,头文件是#include
-
如何使用C++string
-
string 中的一些函数操作 basic_string 类 | Microsoft Docs
#include <string> #include <iostream> #include <cstdio> using namespace std; void testCppString() {//1.常用的创建方式//1.1常用的创建方式string str1; //类似创建变量的方式std::string noStd; //没有using namespace std ,也需要加前缀str1 = "ILoveyou";cout << str1 << endl;string str2("ILoveyou");cout << str2 << endl;string str3(str2);cout << str3 << endl;//1.2不常用string str4(5, 'O'); //str4="OOOOO";cout << str4 << endl;string str5("Iloveyou", 1, 5); //从0开始,用第一个到第五个字符初始化cout << str5 << endl;//2.基本操作//2.1string里面有一个函数可以表示字符串属性cout << str5.size() << endl; //元素个数cout << str5.length() << endl; //长度cout << str5.capacity() << endl; //容量string longStr = "12345678910123423";cout << longStr.capacity() << endl;//2.2 常规操作//比较,直接比即可 所有条件运算符直接用//运算符重载cout << (longStr > str5) << endl;cout << (longStr == str5) << endl;cout << (longStr != str5) << endl;//连接直接用+string strF = "First";string strS = "Second";string result = strF + strS;cout << result << endl;//3.string与char* 转换//不能用%s方式直接打印string//调用string类中两个函数//data() ,c_str()string info("C++中的string");printf("%s\n", info.c_str());printf("%s\n", info.data());char name[20] = "";string strName = "张三";strcpy_s(name, 20, strName.c_str());printf("%s\n", name);//4.下表法访问stringstring pStr = "ILoveyou";for (int i = 0; i < pStr.length(); i++) {cout << pStr.at(i);}cout << endl;cout << pStr << endl; } int main() {testCppString();return 0; } -
-
C++类型转换
- 基本数据类型转换: 类型(变量)
- static_cast
- 可以用做基本数据类型转换
- 把空类型的指针转换为目标指针类型
- 不能转换带有const属性指针
- const_cast: const属性指针的一些转换操作
- reinterpret_cast:指针转整数,整数转指针
- dynamic_cast :后续讲完多态在给同学们讲解
类和对象
-
类和对象
- 什么是类? 类是一些具有共同属性和行为的事物的抽象
- 什么是对象? 类的具体化(实例化),明确属性和行为
- 属性: 数据成员(int,float,char…)描述, 一系列事物公有特征
- 行为: 成员函数(类中函数)描述,一系列公有事物共同操作
-
类的特点
- 封装性
- 继承性
- 多态性
- 抽象性
- 隐藏性
-
学会创建类的语法
- 权限限定词:public,protected,private,在结构体中也是可以使用
- 类中默认是private属性,结构体中默认是public属性
- 权限限定词作用是用来限定类外对类中数据访问
- 一般情况类外访问类中数据必须通过对象来访问,所以我们写C++程序,做的第一件事是创建对象
- 权限限定词是可以多个,或者没有
class 类名
{
public: //公有
protected: //保护
private: //私有
}; //分号必须要有的
-
明白类中的权限问题
- 静态数据成员和静态成员也受权限限定,可以不需要对象也可以调用
- 类外只能访问public属性,别的属性都不能被访问,类中没有权限限定
- protected和private 在继承中有区别,目前不需要知道
-
学会如何访问类中的数据
- 类中数据可以直接初始化
- 接口的概念,C++当中一般指是public属性下方法(成员函数)
- 两种修改类中数据的方式
- 通过提供一个带参的函数去修改数据成员
- 通过返回引用的方式修改数据成员
-
C++各种对象的形式对类中数据的访问
-
普通对象
- 注意权限问题,类外只能访问public属性下内容
- 对象用: 对象.成员
-
对象数组
-
对象指针
- 可以用指针指向运算符(->)访问 :指针->成员
- 也可以用(*指针).成员
-
对象本身就是一个数据,所以普通数据能做他都可以做
- 当做函数返回值
- 当做函数参数
- 当做变量赋值
-
this指针
- this指针可以解决形参名和数据成员名字相同的问题
- 可以函数充当函数返回值
-
类的成员函数的表示方式
- 如何定义一个类的成员函数的指针
- 如果通过成员函数的函数指针调用函数
-
构造函数和析构函数
-
构造函数
- 没有返回值
- 函数名和类名相同
- 构造对象的时候被调用
- 构造函数一般情况都是用来数据成员初始化
- 一般情况构造函数是public属性
- 默认的拷贝构造函数是没有参数,无参构造函数,一旦自己写构造函数,默认的就不存在
-
拷贝构造函数
- 拷贝构造函数也是构造函数,具有构造函数相同属性
- 拷贝构造函数只有一个参数,就是对对象的引用
- 拷贝构造主要是为了实现通过一个对象去创建对象
-
析构函数
- 函数名: ~类名
- 析构函数没有参数
- public属性
- 不写析构存在一个默认的析构
- 析构函数是对象死亡的时候(生命周期结束),自动调用,不需要人调用
- 什么时候需要手动写析构函数,当类中的数据成员做到了内存申请的时候,需要手动写析构函数
-
深拷贝和浅拷贝: 当数据成员是指针的时候,并做内存申请
-
默认的函数的相关操作
- 我们可以删除默认的函数,用delete删除
- 我们使用默认的函数,用default函数
C++特殊成员
-
const成员
-
常数据成员: const修饰的数据成员
-
const属性代表只读(不可以修改)
-
常数据成员的初始化必须要采用初始化参数列表
//初始化参数列表 类名(变量1,变量2,...):数据成员1(变量1),数据成员2(变量2)...{} -
-
常成员函数: const修饰的成员成员函数,注意写法,const是放在函数后面
- 在当前常成员函数中不能修改数据成员
- 常成员可以和普通同时存在
-
常对象: const 修饰对象
- 常对象只能调用常成员函数
-
-
static成员
- static数据成员
- 必须在类外做初始化
- 静态数据成员是属于类的,不属于对象,是所有对象共有,也就是说所有对象用的是一个数据
- 静态数据成员访问不需要对象,可以直接用类名限定访问: 类名::成员
- 静态数据成员也受权限限定
- static成员函数
- 访问可以不需要对象,用对象访问也可以的
- 也受权限限定
- 静态成员函数不能直接访问非静态数据成员,只能通过指定访问
- static对象
- 保留上一次运行的结果,初始化操作只做一次
- static数据成员
-
类的组合 :一个类是另一个类一部分
- 构造函数的的写法:必须采用初始化参数列表
- 构造的顺序(考试)
- 组合类中构造顺序和初始化参数列表写的顺序无关,只和声明顺序有关
C++友元
- 友元函数:单纯提供一个场所给予类的对象具有无视权限的功能
- 普通函数成为友元: 再类中用friend 声明即可
- 以另一个类的成员函数成为友元函数
- 友元类
C++类的继承
- 继承基本语法
class 子类名: 继承方式 父类名
{};
//继承方式: 权限限定词
//public 公有
//protected: 保护
//private: 私有继承
class 派生类名:继承方式 基类名
{//生成新的属性和行为
};
继承的实质: 父类(基类)当中的属性,子类(派生类)中也有一份,这一份的属性是由继承方式的决定的。
- 继承权限问题
| public | protected | private | |
|---|---|---|---|
| public :继承 | public | protected | 不可访问 |
| protected:继承 | protected | protected | 不可访问 |
| private:继承 | private | private | 不可访问 |
- 继承具有遗传性
继承的属性是一值存在的,无论被继承多少代,都是存在,所以一般类的击沉不会写太多层数,导致类很冗长。
-
继承中的构造函数
- 子类构造函数必须要调用父类的构造函数
- 子类的构造函数必须采用初始化列表的写法去初始化继承下来的属性
-
继承的分类
- 单继承:只有一个父类
- 多继承: 2个或者以上的父类
- 菱形继承
-
继承中的同名访问问题 //21:20继续
- 正常赋值的访问: 默认访问方式采用就近原则,当然可以采用类名限定指定的方式
- 非正常赋值的访问: 没有virtual看指针类型
-
继承的作用:
抽象中的抽象。其实大家在使用继承的时候,更多的是继承别人的东西
自己设计代码采用继承的方式,更多增加代码的重用性
C++继承作业: 抽象画图工具的工具类
C++虚函数和多态
- 虚函数与虚函数表
- 纯虚函数和抽象类
- 多态
- ADT过程和虚析构函数
- dynamic下行转换和交叉转换
- 类中类的访问
C++模板
- 函数模板
- 类模板
- 模板特化
C++可变参模板
- 可变参函数模板
- 折叠参数类型的定义 : typename …Arg
- 折叠参数的定义: Arg …arg;
- 如何展开折叠参数
- 递归的方式去展开参数包
- 通过列表({}的数据)展开参数包
- 可变参类模板: 类模板用到可变参数
- 继承+模板特化的方式展开
- 递归的方式展开参数包
- 标准库中的可变参模板
- 包含头文件:#include
- 如何创建
- 如何获取数据
- 其他操作
C++STL容器篇
- array:定长数组
- vector:动态数组
- list
- stack
- queue/deque/priority_queue
- initializer_list
- bitset
- set/multiset
- map/multimap
C++迭代器
-
迭代器是什么? 用来访问容器一个桥梁 ,本质就是类中类的对象,去模仿指针行为
-
按照定义方式分类:
-
正向迭代器
容器类名::iterator 迭代器名;
begin();
end();
-
常正向迭代器
容器类名::const_iterator 迭代器名;
cbegin();
cend()
-
反向迭代器
容器类名::reverse_iterator 迭代器名;
rbegin();
rend();
-
常反向迭代器
容器类名::const_reverse_iterator 迭代器名;
crbgin();
crend();
-
-
按照功能分类
- 正向迭代器
- 双向迭代器
- 随机访问迭代器
-
所有容器的迭代器的分布情况
容器 迭代器 array 随机访问 vector 随机访问 deque 随机访问 list 双向 set/multiset 双向 map/multimap 双向 stack/queue/priority_queue 不支持迭代器 -
迭代器的相关辅助函数
- advance(iterator iter,size_t n); 等效指针的p+n操作
- distance(iterator begin,iterator end); 检测距离
- iter_swap(iterator first,iterator second); 交换first与second指向的元素
-
流型迭代器(了解一下)
- 输出流型迭代器
- ostream_iterator iter(ostreamObject);
- ostream_iterator iter(ostreamObject,char* str);
- iter=3; 实际含义是把3打印到屏幕上
- 输入流型迭代器
- istream_iterator object; //错误流, END_OF_STREAM;
- istream_iterator object(istreamObject)
- *object 等效于cin操作
- 输出流型迭代器
-
copy算法
copy(iterator begin,iterator end,iterator newBegin);
C++仿函数
-
仿函数什么? 仿函数就是类中的成员函数,这个成员函数可以让对象模仿函数调用的行为
- 函数调用行为? 函数名(函数参数)
- C++中可以让类实现: 类名(函数参数) 调用函数
-
自己写一个仿函数
- 重载()运算符
-
接触比较多的仿函数是两个排序准则: greater(), less()
C++函数适配器
- bind函数
C++函数包装器
- function 类
C++STL算法
-
STL查找算法
-
基本查找
- find:区间查找
- find_if:条件查找
- find_firt_of: 查找区间第一次出现值
- adjacent_find: 查找第一次重复的数
- search:子序列查找
- search_n: 子序列查找出现次数
-
统计查找
- count: 区间统计
- count_if: 条件统计个数
- equal:比较
-
有序查找
- binary_search:二分查找
- upper_bound: 查找最后一个大于查找的值
- lower_bound: 大于等于查找的值
- equal_range:区间比较—有序序列
-
-
STL排序通用算法
-
merge: 归并排序,存于新容器
-
inplace_merge: 归并排序,覆盖原区间
-
sort: 排序,更改原容器顺序
-
stable_sort: 排序,保存原容器数据顺序
-
nth_element: 关键字排序
-
partition:范围排序
-
partial_sort:范围排序
-
partial_sort_copy:范围排序外加复制操作
-
stable_partition: 范围排序,保存原容器顺序
-
random_shuffle: 随机排序
-
reverse:逆序原容器
-
reverse_copy: 逆序容器保存到新容器
-
rotate:移动元素到容器末尾
-
rotate_copy:移动元素到新容器
-
-
STL删除替换算法
- copy: 拷贝函数
- copy_backward: 逆序拷贝
- iter_swap: 交换
- remove: 删除
- remove_copy: 删除元素复制到新容器
- remove_if:条件删除
- remove_copy_if:条件删除拷贝到新容器
- replace:替换
- replace_copy: 替换,结果放到新容器
- replace_if: 条件替换
- replace_copy_if:条件替换,结果另存
- swap: 交换
- swap_range:区间交换
- unique:去重
- unique_copy:去重,结果另存
-
STL排列组合算法
-
next_permutation:下一个排序序列的组合
-
prev_permutation:上一个排序序列的组合
-
-
STL 算术算法
-
accumulate:区间求和
-
partial_sum:相邻元素的和
-
inner_product:序列内积运算
-
adjacent_difference:相邻元素的差
-
-
STL 生成异变算法
-
for_each:迭代访问
-
fill:填充方式初始容器
-
fill_n:指定长度填充容器
-
generate_n:填充前n个位置
-
transform:一元转换和二元转换
-
-
STL 关系算法
-
equal:两容器元素是否都相同
-
includes:是否是包含关系
-
lexicographical_compare:比较两个序列
-
max:求最大值
-
max_element:返回最大值的iterator
-
min:求最小值
-
min_element:求最小值的iterator
-
mismatch:找到第一个不同的位置
-
-
STL 集合算法
-
set_union:差集
-
set_intersection:并集
-
set_difference:保存第一个中有第二个没有的元素
-
set_symmetric_difference:对称差集
-
-
STL堆算法
-
make_heap:生成一个堆
-
pop_heap:出堆
-
push_heap:入堆
-
sort_heap:堆排序
-
C++智能指针
智能指针本质就是一个模板类,通过类的对象生命周期的自动结束效果,实现内存的自动释放。也就是把指针当做对象去处理,所以一般不会去new一个智能指针,自己new还是需要自己手动释放,一般都是创建一个智能指针对象,去管理堆区的变量。
- shared_ptr
- weak_ptr
- unique_ptr
C++类型推断
- auto
- decltype
C++IO流
- 输入输出流
- 字符流
- 文件流
C++正则表达式
正则是一种规则,它用来匹配(进而捕获、替换)字符串。这种规则需要“模式”、“字符串”这两样东西,“模式”根据正则规则,来处理“字符串”。这种规则被许多语言支持,C++11以后才支持正则。
具有特殊意义的元字符
\:\字符能够改变字符原本的含义
:字符指示字符串的头,且要求字符串以字符开头,不占位。^表示一个真正的^符号。
$:$字符指示字符串的尾,且要求字符串以字符结尾,不占位。$表示一个真正的$符号。
():分组,大正则中包含小正则。可以改变默认的优先级。在模式中可以使用\1来表示第一组已然捕获到的东西。
//ydpatjj@163.com
\b:指示字符串的边界(头/尾/空格左/空格右),字符\b要求边界的左边是字符,\b字符要求边界的右边是字符。
.:表示一个除了\n以外的任意一个字符。\.表示一个真正的.符号。
|:a|b a或b之一
[abc]:abc之中的任意一个
[^abc]: abc之外的
[a-z]: 任意小写字母
[^a-z]: 除了小写字母之外的
\w:任意一个字母数字下划线,等价于[(0-9)(a-z)(A-Z)(_)]
\W:字母数字下划线之外的,等价于[]
\d: 任意一个数子
\D: 除了数字之外的
\s: 空白符(空格、制表符、换页符)
量词元字符
*:字符*要求字符出现0到多次 {0,}
+:字符+要求字符出现1到多次 (\w) {1,}
?:字符?要求字符出现0次或1次 {0,1}
{n}:字符{n}要求字符出现n次
{n,}:字符{n,}要求字符出现n到多次 {0,}
{n,m}:字符{n,m}要求字符出现n到m次、
所以含有\的元字符,在C++定义时,都要写成\\
校验数字的表达式
数字:^ [0 - 9] * $
n位的数字:^ \d{ n }$
至少n位的数字:^ \d{ n, }$
m - n位的数字: ^ \d{ m,n }$
零和非零开头的数字: ^ (0 | [1 - 9][0 - 9] )$
非零开头的最多带两位小数的数字: ^ ([1 - 9][0 - 9] ) + (.[0 - 9]{ 1,2 }) ? $
带1 - 2位小数的正数或负数: ^ (\ - ) ? \d + (.\d{ 1,2 }) ? $
正数、负数、和小数: ^ (\ - | \ + ) ? \d + (.\d + ) ? $
有两位小数的正实数: ^ [0 - 9] + (.[0 - 9]{ 2 }) ? $
有1~3位小数的正实数: ^ [0 - 9] + (.[0 - 9]{ 1,3 }) ? $
非零的正整数: ^ [1 - 9]\d * $ 或 ^ ([1 - 9][0 - 9] ) { 1, 3 }$ 或^ \ + ? [1 - 9][0 - 9] * $
非零的负整数: ^ \ - [1 - 9][]0 - 9"$ 或 ^-[1-9]\d$
非负整数: ^ \d + $ 或 ^ [1 - 9]\d * | 0$
非正整数: ^ -[1 - 9]\d * | 0$ 或 ^ ((-\d + ) | (0 + ))$
非负浮点数: ^ \d + (.\d + ) ? $ 或 ^ [1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * | 0 ? .0 + | 0$
非正浮点数: ^ ((-\d + (.\d + ) ? ) | (0 + (.0 + ) ? ))$ 或 ^ (-([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d)) | 0 ? .0 + | 0$
正浮点数: ^ [1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * $ 或 ^ (([0 - 9] + .[0 - 9] * [1 - 9][0 - 9] *) | ([0 - 9] * [1 - 9][0 - 9] * .[0 - 9] + ) | ([0 - 9] * [1 - 9][0 - 9] ))$
负浮点数: ^ -([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d)$ 或 ^ (-(([0 - 9] + .[0 - 9] * [1 - 9][0 - 9] *) | ([0 - 9] * [1 - 9][0 - 9] * .[0 - 9]) | ([0 - 9] * [1 - 9][0 - 9] *)))$
浮点数: ^ (-? \d + )(.\d + ) ? $ 或 ^ -? ([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * | 0 ? .0 + | 0)$
校验字符的表达式
汉字: ^ [\u4e00 - \u9fa5]{ 0, }$
英文和数字: ^ [A - Za - z0 - 9] + $ 或 ^ [A - Za - z0 - 9]{ 4,40 }$
长度为3 - 20的所有字符: ^ .{3, 20}$
由26个英文字母组成的字符串: ^ [A - Za - z] + $
由26个大写英文字母组成的字符串: ^ [A - Z] + $
由26个小写英文字母组成的字符串: ^ [a - z] + $
由数字和26个英文字母组成的字符串: ^ [A - Za - z0 - 9] + $
由数字、26个英文字母或者下划线组成的字符串: ^ \w + $ 或 ^ \w{ 3,20 }$
中文、英文、数字包括下划线: ^ [\u4E00 - \u9FA5A - Za - z0 - 9_] + $
中文、英文、数字但不包括下划线等符号: ^ [\u4E00 - \u9FA5A - Za - z0 - 9] + $ 或 ^ [\u4E00 - \u9FA5A - Za - z0 - 9]{ 2,20 }$
可以输入含有 ^ %&‘,;=?$"等字符:[^%&’, ; = ? $\x22] + 12 禁止输入含有~的字符:[^ ~\x22] +
特殊需求表达式
Email地址: ^ \w + ([-+.]\w + ) * @\w + ([-.]\w + ) * .\w + ([-.]\w + ) * $
域名:[a - zA - Z0 - 9][-a - zA - Z0 - 9]{ 0,62 }(/ .[a - zA - Z0 - 9][-a - zA - Z0 - 9]{ 0,62 }) + / . ?
InternetURL:[a - zA - z] + 😕/[^\s]* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=])?$
手机号码: ^ (13[0 - 9] | 14[5 | 7] | 15[0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9] | 18[0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9])\d{ 8 }$
电话号码(0511 - 4405222、021 - 87888822):\d{ 3 } - \d{ 8 } | \d{ 4 } - \d{ 7 }
身份证号(15位、18位数字): ^ \d{ 15 } | \d{ 18 }$
短身份证号码(数字、字母x结尾): ^ ([0 - 9]) { 7, 18 }(x | X) ? $ 或 ^ \d{ 8,18 } | [0 - 9x]{ 8,18 } | [0 - 9X]{ 8,18 } ? $
帐号:(字母开头,允许5 - 16字节,允许字母数字下划线): ^ [a - zA - Z][a - zA - Z0 - 9_]{ 4,15 }$
密码:(以字母开头,长度在6~18之间,只能包含字母、数字和下划线): ^ [a - zA - Z]\w{ 5,17 }$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8 - 10之间): ^ (? = .\d)(? = .[a - z])(? = .[A - Z]).{8, 10}$
日期格式: ^ \d{ 4 } - \d{ 1,2 } - \d{ 1,2 }
一年的12个月(01~09和1~12): ^ (0 ? [1 - 9] | 1[0 - 2])$
一个月的31天(01~09和1~31): ^ ((0 ? [1 - 9]) | ((1 | 2)[0 - 9]) | 30 | 31)$
xml文件: ^ ([a - zA - Z] + -? ) + [a - zA - Z0 - 9] + \.[x | X][m | M][l | L]$
中文字符的正则表达式:[\u4e00 - \u9fa5]
双字节字符:[^ \x00 - \xff](包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s * \r(可以用来删除空白行)
HTML标记的正则表达式:<(\S ? )[^ > ] >. ? < / \1> | <.* ? / > (复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式: ^ \s * | \s * $或(^ \s*) | (\s * $) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等))
腾讯QQ号:[1 - 9][0 - 9]{ 4, } (腾讯QQ号从10000开始)
中国邮政编码:[1 - 9]\d{ 5 }(? !\d) (中国邮政编码为6位数字)
IP地址:\d + .\d + .\d + .\d + (提取IP地址时有用)
IP地址:((? : (? : 25[0 - 5] | 2[0 - 4]\d | [01] ? \d ? \d)\.) { 3 }(? : 25[0 - 5] | 2[0 - 4]\d | [01] ? \d ? \d))
相关文章:
自己曾经的C++笔记【在c盘爆满的时候找到的回忆】
文章目录**C与C的区别** (二)类和对象构造函数和析构函数C特殊成员C友元C类的继承C虚函数和多态C模板C可变参模板CSTL容器篇C迭代器C仿函数C函数适配器CSTL算法C智能指针C类型推断CIO流C正则表达式具有特殊意义的元字符量词元字符校验数字的表达式校验字符的表达式特…...
Nginx 实战-负载均衡
一、负载均衡今天学习一下Nginx的负载均衡。由于传统软件建构的局限性,加上一台服务器处理能里的有限性,在如今高并发、业务复杂的场景下很难达到咱们的要求。但是若将很多台这样的服务器通过某种方式组成一个整体,并且将所有的请求平均的分配…...
本周大新闻|128GB版Quest 2再降价,Mojo Vision完成“新A轮”融资
本周XR大新闻,AR方面,DigiLens推出SRG表面浮雕光栅衍射光波导;索尼成立Sony Research;NuEyes推出牙医场景AR眼镜NuLoupes;苹果EMG手环、AR/VR眼球追踪专利公布。 VR方面,128GB版Quest 2降至349美元&#x…...
【论文阅读】如何给模型加入先验知识
如何给模型加入先验知识 1. 基于pretain模型给模型加入先验 把预训练模型的参数导入模型中,这些预训练模型在另一个任务中已经p retrain好了模型的weight,往往具备了一些基本图片的能力 2. 基于输入给模型加入先验 比如说鸟类的头部是一个重要的区分部分&#x…...
arm系列交叉编译器各版本区别
目录交叉编译器命名规则具体编译器举例crosstool-ng交叉编译工具样本arm交叉编译器举例几个概念ABI与EABIgnueabi与gnueabihf参考交叉编译器命名规则 交叉编译器的命名规则:arch [-vendor] [-os] [-(gnu)eabi] [-language] arch - 体系架构, 如arm&…...
随笔记录工作日志
工作中遇到的问题随笔记录 1、将map集合中的key/value数据按照一定的需求过滤出来,并将过滤出来的map的key值存到list集合中 首先想到的是stream流,但是我对stream流的用法基本不熟,记不住方法,如果坚持用stream流去实现这个需求…...
LinkedHashMap源码分析以及LRU的应用
LinkedHashMap源码分析以及LRU的应用 LinkedHashMap简介 LinkedHashMap我们都知道是在HashMap的基础上,保证了元素添加时的顺序;除此之外,它还支持LRU可以当做缓存中心使用 源码分析目的 分析保持元素有序性是如何实现的 LRU是如何实现的…...
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
交换一次的先前排列【LC1053】 给你一个正整数数组 arr(可能存在重复的元素),请你返回可在 一次交换(交换两数字 arr[i] 和 arr[j] 的位置)后得到的、按字典序排列小于 arr 的最大排列。 如果无法这么操作,…...
Canal增量数据订阅和消费——原理详解
文章目录 简介工作原理MySQL主备复制原理canal 工作原理Canal-HA机制应用场景同步缓存 Redis /全文搜索 ES下发任务数据异构简介 canal 翻译为管道,主要用途是基于 MySQL 数据库的增量日志 Binlog 解析,提供增量数据订阅和消费。 早期阿里巴巴因为杭州和美国双机房部署,存…...
为什么要使用线程池
Java线程的创建非常昂贵,需要JVM和OS(操作系统)配合完成大量的工作: (1)必须为线程堆栈分配和初始化大量内存块,其中包含至少1MB的栈内存。 (2)需要进行系统调用,以便在OS(操作系统)…...
在云服务部署前后端以及上传数据库
1.上传数据库(sql文件) 首先建立一个目录,用于存放要部署的sql文件,然后在此目录中进入mysql 进入后建立一个数据库,create database 数据库名 完成后,通过select * from 表名可以查到数据说明导入成功。 2.部署Maven后端 将Ma…...
Onedrive for Business迁移方案 | 分享一
文章目录 前言 一、Onedrive for Business迁移方案应用范围? 1.准备目标平台 2.导出源平台数据 <...
pt01数据类型、语句选择
python01 pycharm常用快捷键 (1) 移动到本行开头:home键 (2) 移动到本行末尾:end键盘 (3) 注释代码:ctrl / (4) 复制行:ctrl d #光标放行上 (5) 删除行:shift delete (6) 选择列:shift alt 鼠标左键…...
ChatGPT 存在很大的隐私问题
当 OpenAI 发布时 2020 年 7 月的 GPT-3,它提供了用于训练大型语言模型的数据的一瞥。 根据一篇技术论文,从网络、帖子、书籍等中收集的数百万页被用于创建生成文本系统。 在此数据中收集的是您在网上分享的一些关于您自己的个人信息,这些数据现在让 O…...
图的迭代深度优先遍历
图的深度优先遍历(或搜索)类似于树的深度优先遍历(DFS)。这里唯一的问题是,与树不同,图可能包含循环,因此一个节点可能会被访问两次。为避免多次处理一个节点,请使用布尔访问数组。 例子: 输入: n = 4, e = 6 0 -> 1, 0 -> 2, 1 -> 2, 2 -> 0, …...
华为OD机试-开放日活动-2022Q4 A卷-Py/Java/JS
某部门开展Family Day开放日活动,其中有个从桶里取球的游戏,游戏规则如下:有N个容量一样的小桶等距排开,且每个小桶都默认装了数量不等的小球, 每个小桶装的小球数量记录在数组 bucketBallNums 中,游戏开始时,要求所有…...
两亲性聚合物:Lauric acid PEG Maleimide,Mal-PEG-Lauric acid,月桂酸PEG马来酰亚胺,试剂知识分享
Lauric acid PEG Maleimide,Lauric acid PEG Mal| 月桂酸PEG马来酰亚胺 | CAS:N/A | 端基取代率:95%一、试剂参数信息: 外观(Appearance):灰白色/白色固体或粘性液体取决于分子量 溶解性&am…...
FB使用入口点函数例子
一、DLL的入口点 1.1 VFB的自带DLL模式入口 FB是把代码转成C(GCC编译)或者汇编(GAS编译)后编译的,本身就有一个main函数,所以在程序里其实不需要入口点,直接写就可以顺序执行,而有的…...
学习周报4/9
文章目录前言文献阅读摘要简介方法结论时间序列预测总结前言 本周阅读文献《Improving LSTM hydrological modeling with spatiotemporal deep learning and multi-task learning: A case study of three mountainous areas on the Tibetan Plateau》,文章主要基于…...
49天精通Java,第14天,Java泛型方法的定义和使用
目录一、基本介绍1、Java泛型的基本语法格式为:2、在使用泛型时,还需要注意以下几点:二、泛型的优点1、类型安全2、消除强制类型转换3、更高的效率4、潜在的性能收益三、常见泛型字母含义四、使用泛型时的注意事项五、泛型的使用1、泛型类2、…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
