C++语法
# 指针
常量指针:const int * p = &a;
指针指向可以修改,但是指针指向的值不可以修改;
指针常量:int * const p = &a;
指针指向不可以修改,指针指向的值可以修改;
数组指针:
数组名就是数组的首地址;
int arr[5] = {1,2,3,4,5};
int * p = arr;
cout<<"首元素: "<<*p<<endl;
p++;//让指针向后偏移4个字节
cout<<"第二个元素: "<<*p<<endl;
2
3
4
5
函数指针:
地址传递
void swap(int * p,int * q){
int tmp = *p;
*p = *q;
*q = tmp;
}
int main(){
int a=10;
int b=20;
swap(&a,&b);
}
2
3
4
5
6
7
8
9
10
冒泡排序案例:
#include<iostream>
using namespace std;
void bubbleSort(int* arr, int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main() {
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
int n = sizeof(arr) / sizeof(arr[0]);
bubbleSort(arr, n);
for (int i = 0; i < n; i++) {
cout << arr[i]<<" ";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
结构体指针:
利用操作符->通过结构体指针访问结构体属性
#include<iostream>
using namespace std;
struct Student{
string name;
int age;
int score;
};
int main() {
Student st = { "张三",18,60 };
Student * p = &st;
cout << "姓名: " << p->name;
cout << "年龄: " << st.age;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
常量结构体指针:const Student * s
不允许修改结构体里的值
# 引用
作用:给变量起别名
语法:数据类型 &别名 = 原名
引用必须初始化,不能更改只能赋值;
int a=10; int b=20; int &c = a; c = b;//这是赋值
1
2
3
4
引用传递:
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
int main() {
int a = 10;
int b = 20;
swap(a, b);
cout << "a=" << a << ",b=" << b;
}
2
3
4
5
6
7
8
9
10
11
12
引用做函数返回值:
不要返回局部变量的引用;
函数的返回值是引用,函数的调用可以作为左值;
引用的本质:指针常量
常量引用:修饰形参,防止误操作;
//编译器修改:
//int tmp = 10; const int & ref = tmp;
const int & ref = 10;//不加const错误,必须引用合法内存空间
2
3
函数重载问题:
void func(int &a){
}
void func(const int &a){
}
int main(){
int a = 10;
func(a);//调用无const;
func(10);//调用有const;
}
2
3
4
5
6
7
8
9
10
# 类和对象
class与struct区别:struct默认权限是public,class默认private
# 成员函数
指针调用成员函数:
class Person{
public:
void showPersonName(){
cout<<"name= "<<name<<endl;//this->name
}
String name;
}
void test(){
Person* p = NULL;
p->showPersonName();
}
2
3
4
5
6
7
8
9
10
11
报错:因为name省略了this->,指针指向为空;
类外写成员函数:
class Person{
public:
study();
};
Person::study();
2
3
4
5
# 构造函数
构造函数:类名(){}
class Person{ public: Person(){}//无参构造 //有参构造 Person(int a){ age = a; } //拷贝构造 Person(const Person &p){ age = p.age } int age; }; //调用 void test(){ //1.括号法 Person p0; Person p1(10); Person p2(p1); //2.显示法 Person p0; Person p1 = Person(10);//函数右侧为匿名对象,执行结束回收掉 Person p2 = Person(p1); //3.隐式转换法 Person p4 = 10; Person p5 = p4; }
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拷贝构造函数调用时机:
- 值传递方式给函数传参;
- 值方式返回局部对象;
调用规则:
- 如果手动定义了有参构造,编译器不会提供无参构造,但是会提供拷贝构造;
- 如果定义拷贝构造,不会再提供其它构造函数;
初始化列表:
Person(int a,int b,int c):m_A(a),m_B(b),m_C(c){ } int m_A; int m_B; int m_C; //调用 Person p(30,20,10);
1
2
3
4
5
6
7
8
9
# 析构函数
析构函数:~类名(){}
堆区开辟的数据释放
class Person{ public: Person(int age,int height){ m_Age = age; m_Height = new int(height); } ~Person(){ if(m_Height!=NULL){ delete m_Height; m_Height = NULL; } } int m_Age; int *m_Height; };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15浅拷贝问题:只是将指针引用又指向堆区内存,堆区内存重复释放;
深拷贝:堆区重开一块内存
//自己实现拷贝函数,解决浅拷贝问题 Person(const Person &p){ m_Age = p.m_Age; //m_Height = p.m_Height; 编译器默认这种 //深拷贝操作 m_Height = new int(*p.m_Height); }
1
2
3
4
5
6
7
# 静态成员变量/函数
静态成员变量:
class Person{
public:
static int m_A;//类内申明,类外初始化操作
};
int Person::m_A = 100;
2
3
4
5
两种访问:
- 通过对象 Person p; p.m_A;
- 通过类名 Person::m_A
静态成员函数:只能访问静态成员变量
# this指针
this指针:
- 参数与成员变量重名;
- 返回
Class Person{ public: Person(int age){ this->age = age; } Person& PersonAddAge(Person &p){ this->age += p.age; //返回对象本身 return *this; } int age; }; void test(){ Person p1(10); Person p2(10); //链式编程思想 p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 常函数/对象
常函数/对象:mutable
Class Person{
public:
void showPerson() const{
//this->m_A = 100; 报错,常量指针 值不可修改
//this = NULL; 报错,指针常量 指向不可修改
this->m_B = 100;
}
int m_A;
mutable int m_B;//特殊变量,即使常函数,也可以修改这个值
};
void test(){
Person p;
p.showPerson();
}
void test2(){
const Person p;
p.m_B = 100;
//p.m_A = 100;报错
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
this指针本质:指针常量
常函数相当于前面再加了个const :const Person * const this;
常对象只能调用常函数;
# 友元
友元:全局函数,友元类,成员函数
关键字friend,可以访问private成员;
成员函数访问私有属性案例:
#include<iostream> using namespace std; class Building; class GoodGay { public: GoodGay(); void visit(); Building* building; }; class Building { //告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员 friend void GoodGay::visit(); public: Building(); public: string m_SittingRoom; private: string m_BedRoom; }; //类外实现成员函数 Building::Building() { m_SittingRoom = "客厅"; m_BedRoom = "卧室"; } GoodGay::GoodGay() { building = new Building; } void GoodGay::visit() { cout << building->m_SittingRoom<<endl; cout << building->m_BedRoom << endl; } void test() { GoodGay gg; gg.visit(); } int main() { test(); }
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
# 重载
运算符重载:
加号
#include<iostream> using namespace std; class Person { public: //成员函数重载 //Person operator+(Person& p) { // Person tmp; // tmp.m_A = this->m_A + p.m_A; // tmp.m_B = this->m_B + p.m_B; // return tmp; //} int m_A; int m_B; }; //全局函数重载 Person operator+(Person& p1, Person& p2) { Person tmp; tmp.m_A = p1.m_A + p2.m_A; tmp.m_B = p1.m_B + p2.m_B; return tmp; } void test() { Person p1; p1.m_A = 10; p1.m_B = 10; Person p2; p2.m_A = 10; p2.m_B = 10; //成员函数重载本质调用 //Person p3 = p1.operator+(p2); //全局函数重载本质调用 //Person p3 = operator+(p1, p2); Person p3 = p1 + p2; cout << p3.m_A << p3.m_B << endl; } int main() { test(); return 0; }
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左移
只能全局函数重载
ostream operator<<(ostream &cout,Person &p){ cout<<"p.m_A="<<p.m_A<<"p.m_B="<<p.m_B; return cout; } void test(){ Person p; p.m_A = 10; p.m_B = 10; cout<<p<<endl; }
1
2
3
4
5
6
7
8
9
10
11递增
前置递增返回引用,后置递增返回值
#include<iostream>; using namespace std; class MyInteger { friend ostream& operator<<(ostream& out, MyInteger myint); public: MyInteger() { m_Num = 0; } //前置++,返回引用 MyInteger& operator++() { m_Num++; return *this; } //后置++ MyInteger operator++(int) { //先返回,记录当前本身的值,本身+1,返回以前的值 MyInteger tmp = *this; m_Num++; return tmp; } private: int m_Num; }; ostream& operator<<(ostream& out, MyInteger myint) { out << myint.m_Num; return out; } void test01() {//前置++ MyInteger myInt; cout << ++myInt << endl; cout << myInt << endl; } void test02() {//后置++ MyInteger myInt; cout << myInt++ << endl; cout << myInt << endl; } int main() { test01(); test02(); return 0; }
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赋值
类中有属性指向堆区,赋值操作可能出现深浅拷贝问题;
#include<iostream>; using namespace std; class Person { public: Person(int age) { m_Age = new int(age);//开辟到堆区 } Person& operator=(Person& p) { if (m_Age != NULL) { delete m_Age; m_Age = NULL; } //编译器提供的浅拷贝,内存重复释放 //m_Age = p.m_Age; //用深拷贝解决 m_Age = new int(*p.m_Age); return *this; } ~Person() { if (m_Age != NULL) { delete m_Age; m_Age = NULL; } } int* m_Age; }; void test() { Person p1(18); Person p2(20); Person p3(30); p3 = p2 = p1; cout << *p1.m_Age << endl; cout << *p2.m_Age << endl; cout << *p3.m_Age << endl; } int main() { test(); return 0; }
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关系运算符
class Person{ public: Person(string name,int age){ this.m_Name = name; this.m_Age = age; }; bool operator==(Person & p){ if(this->m_Name==p.m_Name && this->m_Age==p.m_Age){ return true; }else{ return false; } } string m_Name; int m_Age; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17函数调用运算符(仿函数)
class MyAdd{ public: int operator()(int v1,int v2){ return v1+v2; } }; void test(){ MyAdd add; //匿名对象调用 cout<<MyAdd()(100,100)<<endl; }
1
2
3
4
5
6
7
8
9
10
11
12
# 继承
语法:class A:public B
继承同名成员处理方式:
- 访问子类同名成员,直接访问;
- 访问父类同名成员,加作用域;
class Base{
public:
Base(){
m_A = 100;
}
void func(){}
int m_A;
};
class Son : public Base{
public:
Son(){
m_A = 200;
}
void func(){}//子类会隐藏父类中同名成员函数
int m_A;
};
void test(){
Son s;
cout<<s.m_A<<endl;//Son下的
cout<<s.Base::m_A<<endl;//Base下的
s.func();
s.Base::func();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
继承同名静态成员处理方式:
通过对象、类名访问成员
class Base{
public:
static void func(){}
static int m_A;
};
int Base::m_A = 100;
class Son : public Base{
public:
static void func(){}
static int m_A;
};
int Son::m_A = 200;
//同名成员属性
void test(){
//通过对象访问
Son s;
cout<<s.m_A<<endl;
cout<<s.Base::m_A<<endl;
//通过类名访问
cout<<Son::m_A<<endl;
cout<<Son::Base::m_A<<endl;
}
//同名成员函数
void test(){
Son s;
s.func();
s.Base::func();
Son::func():
Son::Base::func();
}
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
# 多态
静态多态:函数重载,运算符重载...复用函数名,编译阶段确定函数地址;
动态多态:派生类和虚函数实现运行时多态,运行阶段确定函数地址;
class Animal{
public:
//virtual:虚函数,编译期就不能确定函数调用
virtual void speek(){}
};
class Cat : public Animal{
public:
void speek(){}
};
class Dog : public Animal{
public:
void speek(){}
};
// 父类引用指向子类实例
void DoSpeek(Animal & animal){
animal.speek();
}
void test(){
Cat cat;
DoSpeek(cat);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
纯虚函数:virtual 返回类型 函数名 (参数列表) = 0;
类中有纯虚函数,这个类成为抽象类
class Base{
public:
//子类中必须重写父类中的虚函数
virtual void func() = 0;
};
class Son : public Base{
public:
virtual void func(){}
};
void test(){
Base * base = NULL;
base = new Son;
base->func();
delete base;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
虚析构与纯虚析构:
多态中,如果子类中有属性开辟到堆区,父类指针在释放时无法调用到子类的析构代码;
有纯虚构函数,此类为抽象类
虚析构:virtual ~类名(){}
纯虚析构:virtual ~类名()=0;
类名::~类名(){}
class Animal{
public:
Animal(){}
virtual void Speek()=0;
virtual ~Animal()=0;
};
//纯析构函数调用
Animal::~Animal(){}
class Cat : public Animal{
public:
Cat(String name){
m_Name = new string(name);
}
virtual void Speek(){}
~Cat(){
if(this->m_Name!=NULL){
delete m_Name;
m_Name = NULL;
}
}
string * m_Name;
};
void test(){
Animal *animal = new Cat("Tom");
animal->Speek();
//通过父类指针去释放导致子类对象清理不干净,内存泄露
//给基类一个虚析构函数
delete animal;
}
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
# 模板
# 函数模板
语法:template<typename T>
typename 可以用class代替
自动类型推导/显示指定类型:
func<T>();
func();
2
选择排序案例:
#include<iostream>;
using namespace std;
template<typename T>
void mySwap(T& a, T& b) {
T tmp = a;
a = b;
b = tmp;
}
template<class T>
void mySort(T arr[], int len) {
for (int i = 0; i < len; i++) {
int max = i;
for (int j = i + 1; j < len; j++) {
if (arr[max] < arr[j]) {
max = j;
}
}
if (max != i) {
mySwap(arr[max], arr[i]);
}
}
}
template<typename T>
void printArray(T arr[], int len) {
for (int i = 0; i < len; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
void test() {
char charArr[] = "bsfaserlil";
int num = sizeof(charArr) / sizeof(char);
mySort(charArr, num);
printArray(charArr, num);
}
int main() {
test();
return 0;
}
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
与普通函数区别:普通函数可以发生自动类型转换,模板函数需要<>中指定类型才能自动类型转换;
调用规则:
- 如果函数模板与普通函数都可以实现,优先普通函数;
- 通过空模板参数列表强制调用函数模板;
- 函数模板也能重载;
- 如果函数模板能更好匹配,优先调用函数模板;
void myPrint(int a,int b){}
template<typename T>
void myPrint(T a,T b){}
template<typename T>
void myPrint(T a,T b,T c){}
void test(){
int a = 10;
int b = 20;
//1.如果函数模板与普通函数都可以实现,优先普通函数;
myPrint(a,b);
//2.通过空模板参数列表强制调用函数模板;
myPrint<>(a,b);
//3.函数模板重载
int c = 30;
myPrint(a,b,c);
//4.如果函数模板能更好匹配,优先调用函数模板;
char c1 = 'a';
char c2 = 'b';
myPrint(c1,c2);
}
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
模板局限性:如果T是引用类型,无法正常运行,可以为特定类型提供具体化模板;
class Person {
public:
Person(string name, int age) {
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
//普通函数模板
template<class T>
bool myCompare(T& a, T& b) {
if (a == b)
return true;
else
return false;
}
//具体化模板
template<> bool myCompare(Person& p1, Person& p2) {
if (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age)
return true;
else
return false;
}
void test() {
Person p1("Tom", 10);
Person p2("Tom", 10);
bool ret = myCompare(p1, p2);
if (ret)
cout << "p1==p2" << endl;
else
cout << "p1!=p2" << endl;
}
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
# 类模板
类模板没有自动类型推导,可以有默认参数
template<class NameType,class AgeType=int>
class Person{
public:
Person(NameType name,AgeType age){
this->m_Name = name;
this->m_Age = age;
}
NameType m_Name;
AgeType m_Age;
}
void test(){
Person<string>P1("孙悟空",100);
}
2
3
4
5
6
7
8
9
10
11
12
13
创建时机:
- 普通类成员函数一开始就创建;
- 类模板中成员函数调用才创建;
类模板对象做函数参数:
- 指定传入类型,显示对象的数据类型;
- 参数模板化,将对象中的参数变为模板进行传递;
- 整个类模板化,将这个对象模板化进行传递;
template<class NameType,class AgeType=int>
class Person {
public:
Person(NameType name,AgeType age) {
this->name = name;
this->age = age;
}
void show() {
cout << this->name << this->age << endl;
}
NameType name;
AgeType age;
};
//1.指定传入类型,常用
void print(Person<string, int>& p) {
p.show();
}
void test1() {
Person<string>p("孙悟空", 100);
print(p);
}
//2.参数模板化
template<class T1,class T2>
void print2(Person<T1, T2>& p) {
p.show();
cout << "T1的类型为:" << typeid(T1).name() << endl;
}
void test2() {
Person<string>p("猪八戒",90);
print2(p);
}
//3.整个类模板化
template<class T>
void print3(T& p) {
cout << "T的类型为:" << typeid(T).name() << endl;
p.show();
}
void test3() {
Person<string>p("唐僧", 30);
print3(p);
}
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
类模板继承:
子类继承父类模板,声明时,指定父类中T类型;
template<class T>
class Base {
T m;
};
//必须指明类型,编译期需要给子类分配内存
class Son:public Base<int>{};
void test() {
Son s;
}
//类模板继承模板,T2指定父类中T类型
template<class T1,class T2>
class GrandSon :public Base<T2> {
public:
GrandSon() {
cout << typeid(T1).name() << endl;
cout << typeid(T2).name() << endl;
}
};
void test2() {
GrandSon<int, char> grandSon;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
类模板成员函数类外实现:
template<class T1,class T2>
class Person {
public:
Person(T1 name, T2 age);
void show();
T1 name;
T2 age;
};
//构造函数类外实现
template<class T1,class T2>
Person<T1, T2>::Person(T1 name, T2 age) {
this->name = name;
this->age = age;
}
//成员函数类外实现
template<class T1,class T2>
void Person<T1, T2>::show() {
cout << this->name << this->age << endl;
}
void test() {
Person<string, int>p("Tom", 20);
p.show();
}
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
类模板分文件编写:
方式1:包含.cpp源文件
方式2:.hpp文件
头文件为.hpp:
#pragma once #include<iostream> using namespace std; template<class T1,class T2> class Person { public: Person(T1 name, T2 age); void show(); T1 name; T2 age; }; //构造函数类外实现 template<class T1,class T2> Person<T1,T2>::Person(T1 name, T2 age) { this->name = name; this->age = age; } //成员函数类外实现 template<class T1,class T2> void Person<T1, T2>::show() { cout << this->name << this->age << endl; }
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.cpp文件:
#include<iostream> using namespace std; #include "person.hpp" void test() { Person<string, int>p("Tom", 10); p.show(); } int main() { test(); return 0; }
1
2
3
4
5
6
7
8
9
10
11
12
类模板友元:
建议类内实现
#include<iostream>
using namespace std;
//类外实现,先做函数模板声明
template<class T1, class T2> class Person;
//也可以先写函数声明,放到类后实现
template<class T1,class T2>
void printPerson2(Person<T1, T2>& p) {
cout << "类外实现:" << p.name << p.age << endl;
}
template<class T1,class T2>
class Person {
//1.全局函数配合友元 类内实现
friend void printPerson(Person<T1, T2>& p) {
cout << "类内实现:" << p.name << p.age << endl;
}
//2.全局函数配合友元 类外实现
//加空模板的参数列表,类外实现需要让编译器提前知道这个函数存在
friend void printPerson2<>(Person<T1, T2>& p);
public:
Person(T1 name, T2 age) {
this->name = name;
this->age = age;
}
private:
T1 name;
T2 age;
};
void test() {
Person<string, int>p("Tom", 20);
printPerson(p);
printPerson2(p);
}
int main() {
test();
return 0;
}
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
# STL容器
# string
构造
string s1;//空字符串,无参构造 const char* str = "hello"; string s2(str);//string(const char* s) string s3(s2);//拷贝构造string(const string& str); string s4(10, 'a');//n个字符初始化
1
2
3
4
5
6
7
8拼接
string str1 = "我"; str1 += "爱"; str1.append("LOL"); string str2 = "......."; str1.append(str2, 0, 1);//从下标0截取1字符
1
2
3
4
5
6查找替换
string str1 = "abcdefg"; int pos = str1.find("gf"); if (pos == -1) { cout << "未找到" << endl; } pos = str1.rfind("fg"); cout << pos << endl; str1.replace(1, 3, "1111"); cout << str1 << endl;//a1111efg
1
2
3
4
5
6
7
8
9
10字符串比较
string s1 = "abc"; string s2 = "bca"; int ret = s1.compare(s2); cout << ret << endl;//-1
1
2
3
4存取
string str = "hello world"; for (int i = 0; i < str.size(); i++) { cout << str[i] << " "; } cout << endl; for (int i = 0; i < str.size(); i++) { cout << str.at(i) << " "; } cout << endl;
1
2
3
4
5
6
7
8
9插入擦除
string str = "hello"; str.insert(1, "111");//h111ello cout << str << endl; str.erase(1, 3);//hello cout << str << endl;
1
2
3
4
5
6子串
string str = "hello"; string subStr = str.substr(1, 3); string email = "hello@sina.com"; int pos = email.find("@"); string username = email.substr(0, pos); cout << subStr << username << endl;//ellhello
1
2
3
4
5
6
# vector
单端数组,可以动态扩展
构造遍历
void printVector(vector<int>& v) { for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } cout << endl; } void test() { vector<int> v1;//无参构造 for (int i = 0; i < 10; i++) { v1.push_back(i); } printVector(v1); vector<int> v2(v1.begin(),v1.end());//拷贝 printVector(v2); vector<int> v3(3, 100);//n个ele拷贝给自己 printVector(v3); vector<int> v4(v3); printVector(v4); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23容量大小
- empty():是否为空
- capacity():容量,大于size
- size():个数
- resize(int num);resize(int num, elem):容器扩容后,默认值或elem填充;
插入删除
vector<int> v; //尾插 v.push_back(10); v.push_back(20); //尾删 v.pop_back(); printVector(v); //插入 v.insert(v.begin(), 100);//100 10 printVector(v); v.insert(v.begin(), 2, 8);//8 8 100 10 printVector(v); //删除 v.erase(v.begin()); printVector(v); //清空 v.erase(v.begin(), v.end()); v.clear(); printVector(v);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19存取
vector<int>v; for (int i = 0; i < 10; i++) { v.push_back(i); } for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; cout << v.at(i) << " "; } cout << endl; cout << v.front() << endl; cout << v.back() << endl;
1
2
3
4
5
6
7
8
9
10
11互换容器
vector<int>v1; for (int i = 0; i < 10; i++) { v1.push_back(i); } vector<int>v2; for (int i = 10; i > 0; i--) { v2.push_back(i); } v1.swap(v2); printVector(v1); printVector(v2);
1
2
3
4
5
6
7
8
9
10
11
12收缩内存
vector<int> v; for (int i = 0; i < 100000; i++) { v.push_back(i); } //138255 //100000 cout << v.capacity() << endl; cout << v.size() << endl; v.resize(3); //138255 //3 cout << v.capacity() << endl; cout << v.size() << endl; //收缩内存 vector<int>(v).swap(v);//匿名对象 //3,3 cout << v.capacity() << endl; cout << v.size() << endl;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20预留空间
reserve(int len):预留len个元素长度,不初始化,不可访问;
# deque
双端数组;
插入删除
push_back(ele);
push_front(ele);
pop_back();
pop_front();
insert(pos,ele);
返回新数据位置insert(pos,n,ele);
pos位置插入n个ele,无返回值insert(pos,begin,end);
clear
erase(begin,end);
返回下一个数据的位置erase(pos);
删除pos位置数据,返回下一个数据位置排序
#include<iostream> using namespace std; #include<deque> #include<algorithm> void printDeque(const deque<int>& d){ for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) { cout << *it << " "; } cout << endl; } void test() { deque<int> d; d.push_back(10); d.push_front(20); sort(d.begin(), d.end()); printDeque(d); } int main() { test(); return 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# stack
存取
push(ele)
pop()
top()
返回栈顶元素empty()
size()
# queue
存取
push(ele)
pop()
back()
返回最后一个元素front()
返回第一个元素
# list
链表
插入删除
void printList(const list<int>& l) { for (list<int>::const_iterator it = l.begin(); it != l.end(); it++) { cout << *it << " "; } cout << endl; } void test() { list<int> l; l.push_back(10); l.push_back(10); l.push_front(100); l.push_front(100); l.pop_back(); l.pop_front(); //插入 list<int>::iterator it = l.begin(); l.insert(++it, 8); printList(l);//100 8 10 //删除 it = l.begin(); l.erase(++it); printList(l);//100 10 l.push_back(1000); l.push_back(1000); l.push_back(1000); l.remove(1000); printList(l); l.clear(); printList(l); }
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存取
front()
back()
反转排序
bool myCompare(int v1, int v2) { return v1 > v2; } void test() { list<int> l; l.push_back(20); l.push_back(30); l.push_back(3); l.push_back(6); l.reverse(); printList(l); l.sort(); printList(l); l.sort(myCompare); printList(l); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# set/multiset
所有元素自动排序,multiset允许有重复元素
插入删除
#include<iostream> using namespace std; #include<set> void printSet(set<int>& s) { for (set<int>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } void test() { set<int> s; s.insert(10); s.insert(0); s.insert(20); s.insert(30); printSet(s); s.erase(s.begin()); printSet(s); s.erase(0); printSet(s); s.clear(); printSet(s); }
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查找统计
find(key)
:找到返回迭代器,找不到返回set.end();count(key)
:统计元素个数;void test() { set<int> s; s.insert(10); s.insert(0); s.insert(30); s.insert(20); set<int>::iterator pos = s.find(30); if (pos != s.end()) { cout << "找到了" << *pos << endl; } else { cout << "未找到" << endl; } //统计 int num = s.count(30); cout << num << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17排序
仿函数
class MyCompare { public: //从大到小排序 bool operator()(int v1, int v2) const { return v1 > v2; } }; void test() { set<int,MyCompare> s; s.insert(10); s.insert(80); s.insert(0); s.insert(30); for (set<int, MyCompare>::iterator it = s.begin(); it != s.end(); it++) { cout << *it << " "; } cout << endl; } int main() { test(); return 0; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class Person { public: Person(string name, int age) { this->name = name; this->age = age; } string name; int age; }; class comparePerson { public: bool operator()(const Person& p1, const Person& p2) const { return p1.age > p2.age; } }; void test() { set<Person, comparePerson> s; Person p1("zhangsan", 39); Person p2("lisi", 29); Person p3("wangwu", 49); s.insert(p1); s.insert(p2); s.insert(p3); for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++) { cout << it->name << it->age << endl; } }
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
# map/multimap
对组
void test() { pair<string, int>p(string("zhangsan"), 20); cout << p.first << p.second << endl; }
1
2
3
4
5插入删除
#include<map> void printMap(map<int,int>& m){ for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) { cout << it->first << " " << it->second << endl; } cout << endl; } void test() { map<int, int>m; m.insert(pair<int, int>(1, 10)); m.insert(make_pair(2, 20)); m.insert(map<int, int>::value_type(3, 30)); m[4] = 40; printMap(m); //删除 m.erase(m.begin()); printMap(m); //清空 m.erase(m.begin(), m.end()); m.clear(); printMap(m); }
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查找统计
void test() { map<int, int> m; m.insert(pair<int, int>(1, 10)); m.insert(pair<int, int>(2, 20)); m.insert(pair<int, int>(3, 30)); //查找 map<int, int>::iterator pos = m.find(3); if (pos != m.end()) { cout << (*pos).first << " " << (*pos).second << endl; } else { cout << "未找到" << endl; } int num = m.count(3); cout << num << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16排序
class MyCompare { public: bool operator()(int v1, int v2) const { return v1 > v2; } }; void test() { map<int, int, MyCompare> m; m.insert(make_pair(1, 10)); m.insert(make_pair(2, 20)); m.insert(make_pair(3, 30)); for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) { cout << it->first << " " << it->second << endl; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# STL算法
# 遍历
for_each
#include<algorithm> #include<vector> class MyPrint { public: void operator()(int val) { cout << val << " "; } }; void MyPrint2(int val) { cout << val << " "; } void test() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } for_each(v.begin(), v.end(), MyPrint()); cout << endl; for_each(v.begin(), v.end(), MyPrint2); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25transform
#include<algorithm> #include<vector> class Transform { public: int operator()(int val) { return val; } }; class MyPrint { public: void operator()(int val) { cout << val << " "; } }; void test() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector<int> target; target.resize(v.size()); transform(v.begin(), v.end(), target.begin(), Transform()); for_each(target.begin(), target.end(), MyPrint()); }
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
# 查找
find(iterator begin,iterator end,val);
find_if
返回第一个满足条件的
#include<vector> #include<algorithm> class thanFive { public: bool operator()(int val) { return val > 5; } }; void test1() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector<int>::iterator it = find_if(v.begin(), v.end(), thanFive()); if (it == v.end()) { cout << "未找到" << endl; } else { cout << *it << endl; } } //自定义数据类型 class Person { public: Person(string name, int age) { this->name = name; this->age = age; } string name; int age; }; class than20 { public: bool operator()(Person& p) { return p.age > 20; } }; void test2() { vector<Person> v; Person p1("a", 32); Person p2("aa", 2); Person p3("aaa", 322); v.push_back(p1); v.push_back(p2); v.push_back(p3); vector<Person>::iterator it = find_if(v.begin(), v.end(), than20()); if (it == v.end()) { cout << "未找到" << endl; } else { cout << it->name << it->age << endl; } }
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
59adjacent_find(iterator begin,iterator end);
返回相邻相同元素的第一个位置的迭代器;
bool binary_search(iterator begin,iterator end,val)
有序序列
count(iterator begin,iterator end,val);
count_if
#include<vector> #include<algorithm> class than4 { public: bool operator()(int val) { return val >= 4; } }; void test1() { vector<int>v; v.push_back(1); v.push_back(4); v.push_back(5); v.push_back(7); int num = count_if(v.begin(), v.end(), than4()); cout << num << endl; } class Person { public: Person(string name, int age) { this->name = name; this->age = age; } string name; int age; }; class than35 { public: bool operator()(const Person& p) { return p.age > 35; } }; void test2() { vector<Person> v; Person p1("a", 36); Person p2("aa", 36); v.push_back(p1); v.push_back(p2); int num = count_if(v.begin(), v.end(), than35()); cout << num << endl; }
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
# 排序
sort
#include<algorithm> #include<vector> void MyPrint(int val) { cout << val << " "; } void test() { vector<int> v; v.push_back(10); v.push_back(20); v.push_back(5); v.push_back(3); sort(v.begin(), v.end()); for_each(v.begin(), v.end(), MyPrint); cout << endl; //从大到小 sort(v.begin(), v.end(), greater<int>()); for_each(v.begin(), v.end(), MyPrint); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21random_shuffle
class MyPrint { public: void operator()(int val) { cout << val << " "; } }; void test() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } for_each(v.begin(), v.end(),MyPrint()); cout << endl; random_shuffle(v.begin(), v.end()); for_each(v.begin(), v.end(), MyPrint()); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19merge
class MyPrint { public: void operator()(int val) { cout << val << " "; } }; void test() { vector<int> v1; vector<int> v2; for (int i = 0; i < 10; i++) { v1.push_back(i); v2.push_back(i + 1); } vector<int> target; target.resize(v1.size() + v2.size()); merge(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin()); for_each(target.begin(), target.end(), MyPrint()); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21reverse
void test() { vector<int> v; v.push_back(10); v.push_back(40); v.push_back(20); v.push_back(30); for_each(v.begin(), v.end(), MyPrint()); cout << endl; reverse(v.begin(), v.end()); for_each(v.begin(), v.end(), MyPrint()); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
# 拷贝替换
copy(iterator begin,iterator end,iterator dest)
replace(iterator begin,iterator end,oldval,newval);
replace_if
class MyPrint { public: void operator()(int val) { cout << val << " "; } }; class than30 { public: bool operator()(int val) { return val > 30; } }; void test() { vector<int> v; v.push_back(10); v.push_back(40); v.push_back(20); v.push_back(30); replace_if(v.begin(), v.end(), than30(), 88); for_each(v.begin(), v.end(), MyPrint()); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24swap(container c1,container c2)
类型需要相同
# 算数
accumulate(iterator begin,iterator end,originalValue);
fill(iterator begin,iterator end,val);
# 集合
set_intersection
交集;
两个集合必须有序
void test() { vector<int> v1; vector<int> v2; for (int i = 0; i < 10; i++) { v1.push_back(i); v2.push_back(i + 5); } vector<int> target; target.resize(min(v1.size(), v2.size())); //返回目标容器最后一个元素迭代器地址 vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin()); for_each(target.begin(), itEnd, MyPrint()); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16set_union
void test() { vector<int> v1; vector<int> v2; for (int i = 0; i < 10; i++) { v1.push_back(i); v2.push_back(i + 5); } vector<int> target; target.resize(v1.size()+ v2.size()); //返回目标容器最后一个元素迭代器地址 vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin()); for_each(target.begin(), itEnd, MyPrint()); cout << endl; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16set_difference