Compare commits
28 Commits
6bd91d4dca
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c986179b4 | |||
| 9290e4c051 | |||
| 82619cea98 | |||
| cfd8dd3992 | |||
| 166515cf82 | |||
| 8c46e7a977 | |||
| 606fbc6ff1 | |||
| 994963d919 | |||
| 15ae1803d7 | |||
| c127a3a81b | |||
| 5ab334d200 | |||
| aae9aba049 | |||
| 08a390b0b1 | |||
| e5577ed3e5 | |||
| f5c016c6bb | |||
| 7b786b9b92 | |||
| be4a556f0b | |||
| f956e9c5e2 | |||
| 6e18cf2118 | |||
| eb4944efe7 | |||
| 3320bf12d2 | |||
| 220ea31d68 | |||
| fd11f165fb | |||
| 9f331e0c58 | |||
| 2991bb5aeb | |||
| 4945f41af7 | |||
| ca6f2f9fe6 | |||
| 79430284ab |
@@ -32,3 +32,6 @@
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# 自定义忽略
|
||||
test
|
||||
.vscode
|
||||
@@ -1,3 +1,21 @@
|
||||
# qfedu-cpp-level
|
||||
|
||||
千锋C++阶段
|
||||
# 千锋 C++阶段
|
||||
|
||||
#### day1: C++简介, ::作用域, namespace 命名空间, using 声明, using 编译指令, 类型转换, struct 类型加强, bool 关键字, 三目运算符增强, const 增强
|
||||
|
||||
#### day2: const 和#define 的区别, 引用(reference) 【重要】, 内联函数, 函数的默认值参数, 函数的占位参数, 函数重载和 extern "c", 类与对象的概念, 面向对象程序设计案例
|
||||
|
||||
#### day3: 对象的构造与析构, 构造函数的分类与调用, 拷贝构造函数的调用时机, 构造函数的调用规则, 深拷贝和浅拷贝, 多个对象的构造和析构(初始化列表, 类对象作为成员), explicit 关键字(禁止隐式转换), 动态创建对象(malloc/realloc/calloc 在堆中创建空间, new 关键字), 扩展 new 和 delete,
|
||||
|
||||
#### day4: static 静态成员, 类的单例设计模式, 对象的存储(this 指针与链式编程, const 修饰成员函数与类对象), 友元, 运算符重载
|
||||
|
||||
#### day5: =运算符的重载, () 函数调用重载, `注意: &&和|| 无法重载`,
|
||||
|
||||
#### day6: 多继承(同属一个超级父类)产生的问题, 多态,抽象类, 虚函数(virtual)与纯虚函数, 接口类的多继承, override-overload-redefined 的区别, 函数模版, 普通函数与带泛型函数的区别
|
||||
|
||||
#### day7: 函数模板, 类模板, 类模板与友元一起使用的情况, 类型转换函数(static_cast, dynamic_cast, const_cast, reinterpret_cast)
|
||||
|
||||
#### day8: 异常处理, STL(容器、算法、迭代器)
|
||||
|
||||
#### day9: STL-> string, vector, deque, stack
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "Hello, World!" << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// bool 类型
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
bool flag = 2; // 非 0 即 true,0 为 false
|
||||
if (flag)
|
||||
cout << "true" << endl;
|
||||
else
|
||||
cout << "false" << endl;
|
||||
return 0;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// c 中三目运算表达式返回的是 变量的值
|
||||
// c++ 中三目运算表达式返回的是 变量 (对照 d11.cpp)
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10, b = 20;
|
||||
(a > b ? a : b) = 100; // 不能这样写,因为 c 语言中三目运算表达式返回的是变量的值
|
||||
printf("a = %d, b = %d\n", a, b);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// c 中三目运算表达式返回的是 变量的值 (对照 d11.c)
|
||||
// c++ 中三目运算表达式返回的是 变量
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 10, b = 20;
|
||||
(a > b ? a : b) = 100;
|
||||
cout << "a = " << a << endl;
|
||||
cout << "b = " << b << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// const
|
||||
// c++ 中 const 在定义时不会创建内存空间,取地址时会创建内存空间
|
||||
// 或者把它定义为 extern 时,也会创建内存空间
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
/*
|
||||
const int n = 10; // 不会创建内存空间,相当于宏定义
|
||||
printf("n addr = %p\n", &n); // 取 const 变量的地址时会创建内存空间
|
||||
return 0;
|
||||
*/
|
||||
|
||||
/*
|
||||
// C++ 中 const 的特性:在定义时不会创建内存空间,取地址时会创建内存空间
|
||||
const int x = 10; // 在符号表中创建 x,即没有在栈中开辟空间
|
||||
int *p = (int *)&x; // 在栈中开辟空间,p 指针指向,空间的值是 x 符号表中的数据
|
||||
*p = 100; // 修改的是栈中的空间,而不是符号表中的数据
|
||||
cout << "x = " << x << endl;
|
||||
cout << "*p = " << *p << endl;
|
||||
*/
|
||||
|
||||
// 如果 const 变量初始化为一个变量时,则会在栈中开辟空间
|
||||
int x = 20; // 在栈中开辟空间,存储常量 20
|
||||
const int X = x; // 在符号表中创建 X,并且赋值变量,此时在栈中开辟空间,存储常量 20
|
||||
int *p = (int *)&X; // p 指向了 x 的地址,但是 x 是 const,所以 p 不能修改 x 的值
|
||||
*p = 100; // 会修改栈中的空间,而不是符号表中的数据,因此 X 的值会改变
|
||||
cout << "x = " << x << endl;
|
||||
cout << "X = " << X << endl;
|
||||
cout << "*p = " << *p << endl; // *p = 100
|
||||
|
||||
return 0;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int x = 200;
|
||||
int main()
|
||||
{
|
||||
int x = 100;
|
||||
cout << "x = " << x << endl;
|
||||
// ::x 表示全局的 x
|
||||
cout << "全局的 x = " << ::x << endl;
|
||||
return 0;
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// 命名空间
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
namespace A
|
||||
{
|
||||
// 声明变量成员,可以指定初始化
|
||||
int x = 10;
|
||||
}
|
||||
|
||||
namespace B
|
||||
{
|
||||
int x = 20;
|
||||
}
|
||||
|
||||
namespace C
|
||||
{
|
||||
// 命名空间的嵌套
|
||||
namespace AA
|
||||
{
|
||||
int x = 100;
|
||||
}
|
||||
namespace BB
|
||||
{
|
||||
int x = 200;
|
||||
}
|
||||
}
|
||||
|
||||
namespace D
|
||||
{
|
||||
int x = 1;
|
||||
void show_x() // 定义函数
|
||||
{
|
||||
cout << "D namespace x: " << x << endl;
|
||||
}
|
||||
int add(int y); // 声明函数
|
||||
}
|
||||
|
||||
int D::add(int y)
|
||||
{
|
||||
// 可以返回当前命名空间的所有成员
|
||||
return x + y;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "A x = " << A::x << endl;
|
||||
cout << "B x = " << B::x << endl;
|
||||
cout << "C-AA x = " << C::AA::x << endl;
|
||||
cout << "C-BB x = " << C::BB::x << endl;
|
||||
// 调用 D 的 show_x() 函数
|
||||
D::show_x();
|
||||
// 调用 D 的 add(int) 函数
|
||||
cout << "D::add(100) = " << D::add(100) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// 无名命名空间
|
||||
// 无名命名空间的作用域为当前文件
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
int x = 10;
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
cout << "x = " << x << endl; // x 在当前文件中任意位置都可以访问
|
||||
return 0;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// 命名空间的使用
|
||||
#include <iostream>
|
||||
|
||||
using namespace std; // 当前位置向下,可以访问 std 命名空间中的所有成员
|
||||
|
||||
namespace A
|
||||
{
|
||||
int a = 10;
|
||||
}
|
||||
|
||||
namespace B
|
||||
{
|
||||
int a = 20;
|
||||
}
|
||||
|
||||
namespace C
|
||||
{
|
||||
int a = 30;
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
using namespace A;
|
||||
cout << "A::a = " << a << endl; // 10
|
||||
|
||||
// using namespace B;
|
||||
using B::a; // 替换了当前位置的 a
|
||||
cout << "B::a = " << a << endl; // 20
|
||||
|
||||
// using namespace C;
|
||||
cout << "C::a = " << C::a << endl; // 30
|
||||
|
||||
return 0;
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
// 函数的重载,和函数名、返回值类型、参数列表有关
|
||||
// 函数名相同,参数列表不同(个数、类型、顺序),构成重载
|
||||
namespace A
|
||||
{
|
||||
int add(int a, int b) { return a + b; }
|
||||
float add(int a, float b) { return a * 2.0f + b; }
|
||||
double add(int a, double b) { return a * 3.0 + b; }
|
||||
int add(int a, int b, int c) { return a + b + c; }
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 目的:调用 A 命名空间中的 add 函数
|
||||
using A::add;
|
||||
// 调用函数时,编译器会根据参数列表的类型,自动匹配对应的函数
|
||||
cout << "add(1, 1.5f) = " << add(1, 1.5f) << endl;
|
||||
cout << "add(1, 1.5) = " << add(1, 1.5) << endl;
|
||||
cout << "add(1, 3) = " << add(1, 3) << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// c 语言中可以使用无类型的函数参数
|
||||
// C++ 中不允许使用无类型的函数参数 (对照 d7.cpp)
|
||||
void show(x)
|
||||
{
|
||||
printf("x = %d\n", (int)x);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
show(20);
|
||||
show(15.0);
|
||||
return 0;
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
// c 语言中可以使用无类型的函数参数 (对照 d7.c)
|
||||
// C++ 中不允许使用无类型的函数参数
|
||||
void show(int x)
|
||||
{
|
||||
cout << "x = " << (int)x << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
show(20);
|
||||
show(15.0);
|
||||
return 0;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// C++ 中不同类型的变量之间赋值时,需要明确的使用强制类型转换
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef enum COLOR
|
||||
{
|
||||
GREEN = 1,
|
||||
RED = 5,
|
||||
BLUE // 6
|
||||
} color;
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 129;
|
||||
char b = a; // 隐式类型转换(大类型转换为小类型)(不安全)
|
||||
cout << "b = " << (int)b << endl; // -127
|
||||
|
||||
// C++ 中必须使用强制类型转换,明确数据类型
|
||||
char *p = (char *)malloc(32); // malloc 返回值是 void *,需要强制类型转换
|
||||
// char *p = malloc(32); // malloc 返回值是 void *,需要强制类型转换
|
||||
strcpy(p, "hello world");
|
||||
cout << "p = " << p << endl; // p 为指针,输出的是地址的内容
|
||||
return 0;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// C++ 中使用 结构体 不需要加 struct
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct S
|
||||
{
|
||||
int id;
|
||||
char name[30];
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// struct S s1 = {1, "张三"}; // C 语言中使用结构体需要加 struct
|
||||
S s1 = {1, "张三"}; // C++ 中使用结构体不需要加 struct
|
||||
cout << "s1.id = " << s1.id << "\ns1.name = " << s1.name << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Circle
|
||||
{
|
||||
float r;
|
||||
float s();
|
||||
}
|
||||
|
||||
float Circle::s()
|
||||
{
|
||||
return 3.14 * r * r;
|
||||
}
|
||||
|
||||
namespace Range
|
||||
{
|
||||
int w, h;
|
||||
int s();
|
||||
}
|
||||
|
||||
int Range::s()
|
||||
{
|
||||
return w * h;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "输入半径:";
|
||||
cin >> Circle::r;
|
||||
float s1 = Circle::s();
|
||||
cout << "面积: " << s1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef struct file_node_s
|
||||
{
|
||||
char filename[32];
|
||||
int filesize;
|
||||
|
||||
file_node_s *next;
|
||||
} FileNode;
|
||||
|
||||
int main()
|
||||
{
|
||||
FileNode *head = NULL;
|
||||
FileNode *fn1 = (FileNode *)malloc(sizeof(FileNode));
|
||||
strcpy(fn1->filename, "数学");
|
||||
fn1->filesize = 1000;
|
||||
FileNode *fn2 = (FileNode *)malloc(sizeof(FileNode));
|
||||
strcpy(fn2->filename, "语文");
|
||||
fn2->filesize = 1200;
|
||||
FileNode *fn3 = (FileNode *)malloc(sizeof(FileNode));
|
||||
strcpy(fn3->filename, "英语");
|
||||
fn3->filesize = 1150;
|
||||
head = fn1;
|
||||
fn1->next = fn3;
|
||||
fn3->next = fn2;
|
||||
fn2->next = NULL;
|
||||
|
||||
FileNode *p = head;
|
||||
while (p != NULL)
|
||||
{
|
||||
cout << "文件名: " << p->filename << ", 文件大小: " << p->filesize << endl;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
free(fn1);
|
||||
free(fn2);
|
||||
free(fn3);
|
||||
free(head);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
const float PI = 3.14159;
|
||||
|
||||
double Area(double a, double b)
|
||||
{
|
||||
return PI * pow(a, 2) * b / 360;
|
||||
}
|
||||
double Area(double a)
|
||||
{
|
||||
return PI * pow(a, 2);
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
double r, x;
|
||||
cout << "请输入半径和角度: " << endl;
|
||||
cin >> r >> x;
|
||||
cout << "半径为 " << r << ", 角度为 " << x << " 的扇形面积为: " << Area(r, x) << endl;
|
||||
cout << "半径为 " << r << ", 的圆的面积为: " << Area(r) << endl;
|
||||
return 0;
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 343 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
Executable
+289
@@ -0,0 +1,289 @@
|
||||
## 二、STL容器II
|
||||
|
||||
### 2.1 queue 容器
|
||||
|
||||
#### 2.1.1 queue概念
|
||||
|
||||
> Queue 是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口,queue
|
||||
> 容器允许从一端新增元素,从另一端移除元素。
|
||||
|
||||

|
||||
|
||||
#### 2.1.2 queue 没有迭代器
|
||||
|
||||
Queue 所有元素的进出都必须符合”先进先出”的条件,只有 queue 的顶端元素,才
|
||||
有机会被外界取用。Queue 不提供遍历功能,也不提供迭代器。
|
||||
|
||||
|
||||
|
||||
#### 2.1.3 常用API
|
||||
|
||||
##### 2.1.3.1 构造函数
|
||||
|
||||
```c++
|
||||
queue<T> queT; //queue 采用模板类实现,queue 对象的默认构造形式:
|
||||
queue(const queue &que);//拷贝构造函数
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.1.3.2 存取、插入和删除
|
||||
|
||||
```c++
|
||||
void push(elem); //往队尾添加元素
|
||||
void pop(); //从队头移除第一个元素
|
||||
T back(); //返回最后一个元素
|
||||
T front(); //返回第一个元素
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.1.3.3 赋值与大小
|
||||
|
||||
```c++
|
||||
queue& operator=(const queue &que);//重载等号操作符
|
||||
|
||||
empty();//判断队列是否为空
|
||||
size();//返回队列的大小
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.2 list 容器
|
||||
|
||||
#### 2.2.1 list 概念
|
||||
|
||||
list(链表)是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
|
||||
|
||||
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
|
||||
|
||||
每个结点包括两个部分:
|
||||
|
||||
```
|
||||
1)存储数据元素的数据域,
|
||||
2)存储下一个结点地址的指针域
|
||||
```
|
||||
|
||||
list与vector的比较:
|
||||
|
||||
```
|
||||
1) 相对于vector 的连续线性空间,list 就显得负责许多,每次插入或者删除一个元素,就是配置或者释放一个元素的空间。不浪费多余的空间,且插入与移除元素的操作是常数时间(稳定)。
|
||||
2)list和vector 是两个最常被使用的容器, 但list是由双向链表实现的。
|
||||
3)list插入操作和删除操作都不会造成原有 list 迭代器的失效。 【重要特性】
|
||||
```
|
||||
|
||||
<img src="./readme.assets/image-20230804075335829.png" width="400">
|
||||
|
||||
list特点:
|
||||
|
||||
```
|
||||
1)采用动态存储分配,不会造成内存浪费和溢出
|
||||
2)链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
|
||||
3)链表灵活,但是空间和时间额外耗费较大
|
||||
```
|
||||
|
||||
#### 2.2.2 list 的迭代器
|
||||
|
||||
List 不能像 vector 一样以普通指针作为迭代器,因为其节点不能保证在同一块连续的内存空间上。。List 迭代器必须有能力指向 list 的节点,并有能力进行正确的递增、递减、取值、成员存取操作。**递增**时指向下一个节点,**递减**时指向上一个节点,**取值**时取的是节点的数据值,**成员取用**时取的是节点的成员。
|
||||
|
||||
另外,list 是一个双向链表,迭代器必须能够具备前移、后移的能力,所以 list 容器提供的是 Bidirectional Iterators.(双向的迭代器)。
|
||||
|
||||
List 有一个重要的性质,插入操作和删除操作都不会造成原有 list 迭代器的失效。
|
||||
|
||||
<font color=red>【注意】list的迭代器,不支持`+n`操作。</font>
|
||||
|
||||
#### 2.2.3 list 数据结构
|
||||
|
||||
> list 容器不仅是一个双向链表,而且还是一个循环的双向链表。
|
||||
|
||||
#### 2.2.4 常用API
|
||||
|
||||
##### 2.2.4.1 构造函数
|
||||
|
||||
```c++
|
||||
list<T> lstT;//list 采用采用模板类实现,对象的默认构造形式:
|
||||
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
|
||||
list(n,elem);//构造函数将 n 个 elem 拷贝给本身。
|
||||
list(const list &lst);//拷贝构造函数
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.2.4.2 插入和删除
|
||||
|
||||
```c++
|
||||
push_back(elem);//在容器尾部加入一个元素
|
||||
pop_back();//删除容器中最后一个元素
|
||||
push_front(elem);//在容器开头插入一个元素
|
||||
pop_front();//从容器开头移除第一个元素
|
||||
insert(pos,elem);//在 pos 位置插 elem 元素的拷贝,返回新数据的位置。
|
||||
insert(pos,n,elem);//在 pos 位置插入 n 个 elem 数据,无返回值。
|
||||
insert(pos,beg,end);//在 pos 位置插入[beg,end)区间的数据,无返回值。
|
||||
clear();//移除容器的所有数据
|
||||
|
||||
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
|
||||
erase(pos);//删除 pos 位置的数据,返回下一个数据的位置。
|
||||
remove(elem);//删除容器中所有与 elem 值匹配的元素
|
||||
```
|
||||
|
||||
##### 2.2.4.3 大小
|
||||
|
||||
```c++
|
||||
size();//返回容器中元素的个数
|
||||
empty();//判断容器是否为空
|
||||
resize(num);//重新指定容器的长度为 num, 若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
|
||||
resize(num, elem);
|
||||
```
|
||||
|
||||
##### 2.2.4.4 赋值
|
||||
|
||||
```c++
|
||||
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
|
||||
assign(n, elem); //将 n 个 elem 拷贝赋值给本身。
|
||||
list& operator=(const list &lst); //重载等号操作符
|
||||
swap(lst); //将 lst 与本身的元素互换。
|
||||
```
|
||||
|
||||
##### 2.2.4.5 读取
|
||||
|
||||
```
|
||||
front();//返回第一个元素。
|
||||
back();//返回最后一个元素
|
||||
```
|
||||
|
||||
##### 2.2.4.6 反转和排序
|
||||
|
||||
```
|
||||
reverse(); //反转链表
|
||||
sort(); //list 排序
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.3 set/multiset 容器
|
||||
|
||||
#### 2.3.1 set概念
|
||||
|
||||
set 的特性是所有元素都会根据元素的键值自动被排序。
|
||||
|
||||
set 的元素即是键值又是实值, 不允许两个元素有相同的键值。
|
||||
|
||||
set 的 iterator 是一种 const_iterator, 不允许修改set的键值。
|
||||
|
||||
set 拥有和 list 某些相同的性质,当对容器中的元素进行插入操作或者删除操作的
|
||||
时候,操作之前的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
|
||||
|
||||
#### 2.3.2 set数据结构
|
||||
|
||||
multiset 特性及用法和 set 完全相同,唯一的差别在于它允许键值重复。set 和multiset 的底层实现是红黑树,红黑树为平衡二叉树的一种。
|
||||
|
||||
二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点:
|
||||
|
||||
<img src="./readme.assets/image-20230804083406386.png" width="300">
|
||||
|
||||
二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效:
|
||||
|
||||
<img src="./readme.assets/image-20230804083459911.png" width=400>
|
||||
|
||||
二叉搜索树的放置规则是:
|
||||
|
||||
任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于其右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直至无路可走,可得到最大值。那么在二叉搜索树中找到最大元素和最小元素是非常简单的事情。
|
||||
|
||||
如上图所示:那么当一个二叉搜索树的左子树和右子树不平衡的时候,那么搜索依据上图表示,搜索 9 所花费的时间要比搜索 17 所花费的时间要多,由于我们的输入或者经过我们插入或者删除操作,二叉树失去平衡,造成搜索效率降低。
|
||||
|
||||
<img src="./readme.assets/image-20230804083751044.png" width=400>
|
||||
|
||||
#### 2.3.3 常用API
|
||||
|
||||
##### 2.3.3.1 构造函数
|
||||
|
||||
```c++
|
||||
set<T> st;//set 默认构造函数:
|
||||
mulitset<T> mst; //multiset 默认构造函数:
|
||||
set(const set &st);//拷贝构造函数
|
||||
```
|
||||
|
||||
##### 2.3.3.2 赋值和大小
|
||||
|
||||
```c++
|
||||
set& operator=(const set &st);//重载等号操作符
|
||||
swap(st);//交换两个集合容器
|
||||
|
||||
size();//返回容器中元素的数目
|
||||
empty();//判断容器是否为空
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.3.3.3 插入和删除
|
||||
|
||||
```
|
||||
insert(elem); //在容器中插入元素。
|
||||
clear(); //清除所有元素
|
||||
erase(pos); //删除 pos 迭代器所指的元素,返回下一个元素的迭代器。
|
||||
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
|
||||
erase(elem); //删除容器中值为 elem 的元素。
|
||||
```
|
||||
|
||||
##### 2.3.3.4 查找
|
||||
|
||||
```c++
|
||||
find(key); //查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返
|
||||
回 set.end();
|
||||
count(key);//查找键 key 的元素个数
|
||||
lower_bound(keyElem);//返回第一个 key>=keyElem 元素的迭代器。
|
||||
upper_bound(keyElem);//返回第一个 key>keyElem 元素的迭代器。
|
||||
equal_range(keyElem);//返回容器中 key 与 keyElem 相等的上下限的两个迭代器。
|
||||
```
|
||||
|
||||
##### 2.3.3.5 set 排序规则
|
||||
|
||||
> set自动排序, 但可以改变它的排序规则,默认从小到大。
|
||||
|
||||
自定义排序规则,可以使用struct或class, 声明 `bool operator(v1, v2)`仿函数重载。
|
||||
|
||||
|
||||
|
||||
#### 2.3.4 对组(pair)
|
||||
|
||||
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可
|
||||
以分别用 pair 的两个公有属性 first 和 second 访问。
|
||||
|
||||
```
|
||||
类模板:template <class T1, class T2> struct pair
|
||||
```
|
||||
|
||||
用法一:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair1(string("name"), 20);
|
||||
cout << pair1.first << endl;
|
||||
cout << pair1.second << endl;
|
||||
```
|
||||
|
||||
用法二:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair2 = make_pair("name", 30);
|
||||
cout << pair2.first << endl;
|
||||
cout << pair2.second << endl;
|
||||
```
|
||||
|
||||
用法三:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair3 = pair2;
|
||||
cout << pair3.first << endl;
|
||||
cout << pair3.second << endl;
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.4 map/multimap 容器
|
||||
|
||||
Map 的特性是所有元素都会根据元素的键值自动排序。
|
||||
|
||||
Map 所有的元素都是pair,同时拥有实值和键值,pair 的第一元素被视为键值,第二元素被视为实值,map 不允许两个元素有相同的键值。
|
||||
|
||||
multimap 和 map 的操作类似,唯一区别 multimap 键值可重复。
|
||||
map 和 multimap 都是以红黑树为底层实现机制。
|
||||
@@ -0,0 +1,33 @@
|
||||
// 函数对象
|
||||
// 仿函数: 一元,二元仿函数
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 一元仿函数
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A(int n) : n(n) {}
|
||||
int n;
|
||||
// 重载 operator() 运算符,只要调用 A 对象的 (int x) ,就会给对象的对应成员对象加一个 x
|
||||
A &operator()(int i)
|
||||
{
|
||||
this->n += i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void print(A a, int n) // A a = A(30)
|
||||
{
|
||||
a(n);
|
||||
cout << "a.n = " << a.n << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 打印 a 对象的值加额外的值的结果
|
||||
print(A(20), 3); // A(20) 会创建一个匿名对象
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 谓词
|
||||
// gt 大于, ge 大于等于
|
||||
// lt 小于, le 小于等于
|
||||
// eq 等于, ne 小于等于
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class GTFive // 一元谓词
|
||||
{
|
||||
public:
|
||||
bool operator()(int n)
|
||||
{
|
||||
return n > 5;
|
||||
}
|
||||
};
|
||||
|
||||
class GT // 二元谓词
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n1, const int &n2)
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
};
|
||||
|
||||
void printGTF(GTFive gtf, int *p, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (gtf(p[i]))
|
||||
cout << p[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(int *p, int size, GT gt, int n)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (gt(p[i], n))
|
||||
cout << p[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int ms[] = {1, 2, 4, 7, 9, 20};
|
||||
cout << "大于 5 的元素" << endl;
|
||||
printGTF(GTFive(), ms, 6);
|
||||
|
||||
cout << "大于 7 的元素" << endl;
|
||||
print(ms, 6, GT(), 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 算术类函数对象
|
||||
// 算术类函数对象
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <typename T>
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, plus<int> pl, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << pl(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, multiplies<int> mul, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << mul(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
// set 会自动过滤重复,并排序
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
print(s.begin(), s.end(), plus<int>(), 1);
|
||||
print(s.begin(), s.end(), multiplies<int>(), 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <typename T>
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, plus<int> pl, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << pl(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, multiplies<int> mul, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << mul(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void show(int n)
|
||||
{
|
||||
cout << n << " ";
|
||||
}
|
||||
|
||||
// 二元仿函数
|
||||
class PrintPlus : public binary_function<int, int, void>
|
||||
{
|
||||
public:
|
||||
void operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
cout << n1 << "+" << n2 << " = " << n1 + n2 << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
// set 会自动过滤重复,并排序
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
// print(s.begin(), s.end(), plus<int>(), 1);
|
||||
// print(s.begin(), s.end(), multiplies<int>(), 3);
|
||||
|
||||
// for_each(s.begin(), s.end(), show);
|
||||
// cout << endl;
|
||||
|
||||
// PrintPlus 测试
|
||||
// for (int i = 0; i < 6; i++)
|
||||
for_each(s.begin(), s.end(), bind1st(PrintPlus(), i));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PrintGt5Adapter : public binary_function<int, int, void>
|
||||
{
|
||||
public:
|
||||
void operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
if (n1 > n2)
|
||||
cout << n1 << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
for_each(s.begin(), s.end(), bind2nd(PrintGt5Adapter(), 2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 取反适配器
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
// 自定义一个适配器,只需要容器中元素即可。
|
||||
class GT5 : public unary_function<int, bool>
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n) const
|
||||
{
|
||||
return n > 5;
|
||||
}
|
||||
};
|
||||
|
||||
class GTN : public binary_function<int, int, bool>
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
// find_if(start, end, _callback) 返回查找到的第一个迭代器的位置
|
||||
vector<int>::iterator ret = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 3)));
|
||||
cout << *ret << endl;
|
||||
|
||||
ret = find_if(v.begin(), v.end(), GT5());
|
||||
cout << *ret << endl;
|
||||
|
||||
ret = find_if(v.begin(), v.end(), bind2nd(GTN(), 3));
|
||||
cout << *ret << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// 函数指针适配
|
||||
// 使用 ptr_fun<>() 适配函数指针
|
||||
// <> 中的第一个参数是函数指针的类型,第二个参数是函数指针的参数类型,第三个参数是函数指针的返回值类型
|
||||
// bind1st() 和 bind2nd() 适配函数对象
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool gtn(int n1, int n2)
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
vector<int>::iterator ret = find_if(v.begin(), v.end(), bind2nd(ptr_fun<int, int, bool>(gtn), 3));
|
||||
cout << *ret << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// mem_fn 有两个重载版本:
|
||||
// 用法1:mem_fn(&MyClass::printMessage) 用于将成员函数转换为函数对象
|
||||
// 用法2:mem_fn(&MyClass::printMessage)(&obj, "hello world") 用于调用成员函数
|
||||
// mem_fn 是一个函数模板,它接受一个成员函数指针或成员函数引用,并返回一个函数对象,该对象可以调用相应的成员函数。
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Stu
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Stu(const string &name, int age) : name(name), age(age) {}
|
||||
|
||||
public:
|
||||
void show()
|
||||
{
|
||||
cout << "name is " << name << ", age is " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
vector<Stu> vs;
|
||||
vs.push_back(Stu("disen", 18));
|
||||
vs.push_back(Stu("lucy", 20));
|
||||
vs.push_back(Stu("jack", 15));
|
||||
vs.push_back(Stu("mack", 19));
|
||||
|
||||
// 遍历容器中所有成员,成员函数作为仿函数时,则通过容器成员调用它的仿函数
|
||||
for_each(vs.begin(), vs.end(), mem_fun_ref(&Stu::show));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
int target = 3;
|
||||
|
||||
// 使用 std::bind 适配 std::equal_to
|
||||
vector<int>::iterator ret = adjacent_find(v.begin(), v.end(), bind(equal_to<int>(), _1, 3));
|
||||
cout << *(++ret) << endl;
|
||||
|
||||
if (ret != v.end())
|
||||
{
|
||||
cout << "Found adjacent elements equal to " << target << "." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "No adjacent elements equal to " << target << " found." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
list<int> lst1(6, 5); // 6 个 5
|
||||
print(lst1);
|
||||
|
||||
string s1 = "abcdefg";
|
||||
|
||||
// 将 string 字符串转换为 list
|
||||
list<char> lst2(s1.begin(), s1.end());
|
||||
print(lst2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
|
||||
// 将 string 字符串转换为 list
|
||||
list<char> l(s.begin(), s.end());
|
||||
int size = l.size(); // 获取大小
|
||||
print(l);
|
||||
|
||||
// list 手写逆序
|
||||
list<char>::iterator it = l.begin(); // 迭代器指向第一个元素
|
||||
for (int i = 0; i < size; i++) // 逆序 size 次
|
||||
{
|
||||
it = l.insert(it, l.back()); // 将最后一个元素插入到第一个元素之前
|
||||
it++; // 迭代器指向下一个元素
|
||||
l.pop_back(); // 删除最后一个元素
|
||||
}
|
||||
|
||||
print(l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
list<char> l(s.begin(), s.end());
|
||||
|
||||
// 删除 cde
|
||||
// list<char>::iterator it = find(l.begin(), l.end(), 'c');
|
||||
// l.erase(it, find(l.begin(), l.end(), 'e'));
|
||||
|
||||
list<char>::iterator it = l.begin(); // 迭代器指向第一个元素
|
||||
for (int i = 0; i < 2; i++) // 迭代器指向第三个元素
|
||||
it++;
|
||||
list<char>::iterator it2 = it; // 迭代器指向第三个元素
|
||||
for (int i = 0; i < 3; i++) // 迭代器指向第六个元素
|
||||
it2++;
|
||||
l.erase(it, it2); // 删除第三个到第五个元素
|
||||
|
||||
print(l); // a b f g
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
list<char> l(s.begin(), s.end());
|
||||
print(l);
|
||||
l.reverse(); // 逆序
|
||||
print(l);
|
||||
|
||||
int m[] = {6, 4, 2, 0, 8, 6, 4};
|
||||
list<int> l2(m, m + 7);
|
||||
print(l2);
|
||||
l2.sort(); // 排序
|
||||
print(l2);
|
||||
l2.reverse(); // 逆序
|
||||
print(l2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> ms;
|
||||
|
||||
// 1. insert()函数
|
||||
// map 在插入时会自动根据 map 的键来排序
|
||||
ms.insert(pair<int, string>(1, "张三")); // pair<int, string>是map<int, string>::value_type的类型
|
||||
ms.insert(pair<int, string>(4, "李四"));
|
||||
ms.insert(make_pair(3, "王五")); // make_pair()函数可以自动推导出类型
|
||||
ms.insert(map<int, string>::value_type(2, "赵六")); // value_type是map<int, string>的类型
|
||||
ms[5] = "田七"; // 通过下标的方式插入数据
|
||||
|
||||
map<int, string>::iterator it = ms.begin();
|
||||
for (; it != ms.end(); it++)
|
||||
{
|
||||
// cout << "sid = " << it->first << ",name = " << it->second << endl;
|
||||
cout << "sid = " << (*it).first << ",name = " << (*it).second << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// 使用 map 来解决括号匹配
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string left_c = "{[(";
|
||||
map<char, char> map1;
|
||||
|
||||
bool valid(const char *p)
|
||||
{
|
||||
stack<char> stk;
|
||||
int max_depth = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
const char &cp = *p;
|
||||
|
||||
// if (left_c.find(cp) != string::npos) // 如果当前拿到的是左括号
|
||||
if (left_c.find(cp) != -1) // 如果当前拿到的是左括号
|
||||
{
|
||||
// 入栈
|
||||
stk.push(*p);
|
||||
}
|
||||
else // 如果当前拿到的是右括号
|
||||
{
|
||||
// 弹栈
|
||||
if (stk.empty())
|
||||
return false;
|
||||
|
||||
const char &top = stk.top();
|
||||
if (map1[cp] != top)
|
||||
return false;
|
||||
|
||||
// 当前左右匹配的后续操作
|
||||
// 求最大深度
|
||||
if (max_depth < stk.size())
|
||||
max_depth = stk.size();
|
||||
|
||||
// 弹栈前判断最大深度
|
||||
stk.pop();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
cout << "当前括号栈的最大深度为: " << max_depth << endl;
|
||||
|
||||
return stk.empty();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
map1.insert(make_pair('}', '{'));
|
||||
map1.insert(make_pair(']', '['));
|
||||
map1.insert(make_pair(')', '('));
|
||||
|
||||
cout << valid("{[()]}[[[[[()]]]]]") << endl;
|
||||
cout << valid("{[())}") << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> m;
|
||||
m.insert(make_pair(1, "disen"));
|
||||
m.insert(make_pair(2, "lucy"));
|
||||
cout << m.size() << endl;
|
||||
m.erase(1); // 删除键值为 1 的元素
|
||||
cout << m.size() << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> m;
|
||||
m.insert(make_pair(1, "disen"));
|
||||
m.insert(make_pair(2, "lucy"));
|
||||
m.insert(make_pair(3, "jack"));
|
||||
|
||||
map<int, string>::const_iterator it = m.find(3);
|
||||
|
||||
if (it == m.end())
|
||||
{
|
||||
cout << "未查找到" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
const pair<int, string> &p = *it;
|
||||
cout << p.first << ", " << p.second << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const set<T> &s)
|
||||
{
|
||||
for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print(const multiset<T> &s)
|
||||
{
|
||||
for (typename multiset<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 2, 3, 4};
|
||||
set<int> s(m, m + 6);
|
||||
print(s); // set 会自动去重,输出 1 2 3 4
|
||||
|
||||
multiset<int> ms(m, m + 6);
|
||||
print(ms); // multiset 不会自动去重,输出 1 2 2 3 3 4
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const set<T> &s)
|
||||
{
|
||||
for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {5, 12, 16, 21, 22, 27, 29, 30};
|
||||
set<int> s(m, m + 8);
|
||||
print(s); // set 键值自动排序,且不重复
|
||||
|
||||
// 查看大于等于 22 值的所有元素
|
||||
cout << "查看大于等于 22 值的所有元素: " << endl;
|
||||
set<int>::iterator it = s.lower_bound(22); // 返回第一个大于等于 22 的元素的迭代器
|
||||
while (it != s.end())
|
||||
{
|
||||
cout << *it << ' ';
|
||||
++it;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
// 查找小于等于 22 值的所有元素
|
||||
cout << "查找小于等于 22 值的所有元素: " << endl;
|
||||
// it = s.upper_bound(22); // 返回第一个大于 22 的元素的迭代器
|
||||
// for (; it != s.begin();)
|
||||
// {
|
||||
// --it;
|
||||
// cout << *it << ' ';
|
||||
// }
|
||||
// cout << endl;
|
||||
|
||||
// 查找小于等于 22 值的所有元素(另一种写法)
|
||||
it = s.lower_bound(22);
|
||||
while (it != s.begin())
|
||||
{
|
||||
--it;
|
||||
cout << *it << ' ';
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 自定义排序
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 自定义规则
|
||||
template <typename T>
|
||||
class MySort
|
||||
{
|
||||
public:
|
||||
bool operator()(const T &a, const T &b)
|
||||
{
|
||||
return a > b; // 从小到大排序
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 使用 set 时,添加自定义排序规则
|
||||
set<int, MySort<int> > s1;
|
||||
s1.insert(20);
|
||||
s1.insert(30);
|
||||
s1.insert(1);
|
||||
s1.insert(8);
|
||||
|
||||
set<int, MySort<int> >::iterator it = s1.begin(); // <int, MySort<int>> 可以省略
|
||||
while (it != s1.end())
|
||||
{
|
||||
cout << *it << ' ';
|
||||
++it;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 自定义排序
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 自定义规则
|
||||
template <typename T>
|
||||
class MySort
|
||||
{
|
||||
public:
|
||||
bool operator()(const T &a, const T &b)
|
||||
{
|
||||
return a > b; // 从小到大排序
|
||||
}
|
||||
};
|
||||
|
||||
class Student
|
||||
{
|
||||
public:
|
||||
string name;
|
||||
int age;
|
||||
float score;
|
||||
|
||||
public:
|
||||
Student(const string &name, int age, float score)
|
||||
{
|
||||
this->name = name;
|
||||
this->age = age;
|
||||
this->score = score;
|
||||
}
|
||||
};
|
||||
|
||||
class MyStudentByAgeSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const Student &s1, const Student &s2)
|
||||
{
|
||||
return s1.age > s2.age;
|
||||
}
|
||||
};
|
||||
|
||||
class MyStudentByScoreSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const Student &s1, const Student &s2)
|
||||
{
|
||||
return s1.score > s2.score;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Student[] *stus = new Student[3]{Student("张三", 18, 100), Student("李四", 20, 90), Student("王五", 19, 95)};
|
||||
set<Student, MyStudentByAgeSort> s2;
|
||||
s2............................
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// pair 是一个模板类,有两个模板参数,
|
||||
// 用于存储两个数据,可以分别指定两个数据的类型
|
||||
pair<int, string> p1(1, "张三");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 对组(pair)
|
||||
// 将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可
|
||||
// 以分别用 pair 的两个公有属性 first 和 second 访问。
|
||||
|
||||
// 类模板:template<class T1, class T2> class pair
|
||||
|
||||
// 用法一:
|
||||
|
||||
// pair<string, int> pair1(string("name"), 20);
|
||||
// cout << pair1.first << endl;
|
||||
// cout << pair1.second << endl;
|
||||
|
||||
// 用法二:
|
||||
|
||||
// pair<string, int> pair2 = make_pair("name", 30);
|
||||
// cout << pair2.first << endl;
|
||||
// cout << pair2.second << endl;
|
||||
|
||||
// 用法三:
|
||||
|
||||
// pair<string, int> pair3 = pair2; // 拷贝构造函数
|
||||
// cout << pair3.first << endl;
|
||||
// cout << pair3.second << endl;
|
||||
|
||||
// 如:
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
pair<int, string> p1(1, "disen");
|
||||
pair<int, string> p2 = make_pair(2, "lucy");
|
||||
cout << "id = " << p1.first << ", name = " << p1.second << endl;
|
||||
cout << "id = " << p2.first << ", name = " << p2.second << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Classroom exercises: 课堂练习
|
||||
// ce
|
||||
// 类的定义和使用
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Person
|
||||
{
|
||||
public:
|
||||
void init(const char *iname, int iage);
|
||||
void setName(const char sname[]);
|
||||
void setAge(int sage);
|
||||
const char *getname();
|
||||
const int getAge();
|
||||
const void show();
|
||||
|
||||
private:
|
||||
char name[32];
|
||||
int age;
|
||||
};
|
||||
|
||||
void Person::init(const char *iname, int iage)
|
||||
{
|
||||
strcpy(this->name, iname);
|
||||
if (iage > 0 && iage < 100)
|
||||
this->age = iage;
|
||||
else
|
||||
{
|
||||
this->age = 0;
|
||||
cout << "年龄超出范围,拒绝赋值!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Person::setName(const char sname[])
|
||||
{
|
||||
strcpy(this->name, sname);
|
||||
}
|
||||
|
||||
void Person::setAge(int sage)
|
||||
{
|
||||
if (sage > 0 && sage < 100)
|
||||
this->age = sage;
|
||||
else
|
||||
{
|
||||
cout << "年龄超出范围,拒绝赋值!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
const char *Person::getname()
|
||||
{
|
||||
return this->name;
|
||||
}
|
||||
|
||||
const int Person::getAge()
|
||||
{
|
||||
return this->age;
|
||||
}
|
||||
|
||||
const void Person::show()
|
||||
{
|
||||
cout << "name = " << this->name << ", age = " << this->age << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p1;
|
||||
p1.setAge(20);
|
||||
p1.setName("flykhan");
|
||||
p1.show();
|
||||
|
||||
Person p2;
|
||||
p2.init("hello", 0);
|
||||
p2.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// 引用的使用
|
||||
// 引用的本质是指针常量,所以引用的空间大小和指针相同,都是 8 个字节
|
||||
// 引用的本质是指针常量,所以引用的指向不能改变,但是指向的值可以改变
|
||||
// 引用的本质是指针常量,所以引用在定义时必须初始化,且不能再引用其他变量
|
||||
// int a = 10;
|
||||
// int &aa = a; // int * const aa = &a;
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// 定义引用时,必须给初始化值,另外,定义之后引用不能再引用其他变量
|
||||
int a = 10;
|
||||
int &b = a; // 对 a 的引用
|
||||
b += 20; // 相当于 a += 20
|
||||
cout << "a: " << a << " b: " << b << endl;
|
||||
|
||||
int &c = a;
|
||||
cout << "a: " << a << " b: " << b << " c: " << c << endl;
|
||||
|
||||
int &d = b;
|
||||
cout << "a: " << a << " b: " << b << " c: " << c << " d: " << d << endl;
|
||||
|
||||
int x = 100;
|
||||
c = x;
|
||||
cout << "c: " << c << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void f(int a, int)
|
||||
{
|
||||
cout << "f(int, int )" << endl;
|
||||
}
|
||||
|
||||
void f(double, int)
|
||||
{
|
||||
cout << "f(double, int)" << endl;
|
||||
}
|
||||
|
||||
void f(int a)
|
||||
{
|
||||
cout << "f(int)" << endl;
|
||||
}
|
||||
|
||||
void f(double a)
|
||||
{
|
||||
cout << "f(double)" << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f(1);
|
||||
f(1.0, 2);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "area.h"
|
||||
|
||||
double S(double r)
|
||||
{
|
||||
return r * r * 3.1415926;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __AREA_H__
|
||||
#define __AREA_H__
|
||||
|
||||
// 条件编译
|
||||
#if __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
double S(double r);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
#include "area.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
double r = 2.5;
|
||||
double s = S(r);
|
||||
cout << "S(2.5) = " << s << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 增强的结构体(c 中结构体中只有变量)
|
||||
struct Person
|
||||
{
|
||||
int pid;
|
||||
int age;
|
||||
void show() // C++ 的结构体中可以加函数
|
||||
{
|
||||
// 可以访问同一结构体内的成员变量
|
||||
cout << "pid = " << pid << ", age = " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p1 = {1001, 21};
|
||||
p1.show();
|
||||
|
||||
Person p2 = {1002, 19};
|
||||
p2.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// 类
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
|
||||
namespace SA
|
||||
{
|
||||
class Student
|
||||
{
|
||||
public:
|
||||
int sid = 14; // 默认值设定,需要 c++11 标准以上
|
||||
char name[32] = "hello";
|
||||
|
||||
private:
|
||||
float score = 90;
|
||||
|
||||
public:
|
||||
void showScore(); // 声明类方法
|
||||
void addScore(float n) { this->score = n; }
|
||||
};
|
||||
|
||||
// 实现类中的方法(函数)
|
||||
void Student::showScore()
|
||||
{
|
||||
cout << "sid = " << this->sid << ", name = " << this->name << ", score = " << this->score << endl;
|
||||
}
|
||||
};
|
||||
|
||||
using namespace SA;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
Student s1;
|
||||
strcpy(s1.name, "flykhan");
|
||||
s1.sid = 1001;
|
||||
s1.addScore(100);
|
||||
s1.showScore();
|
||||
|
||||
Student s2;
|
||||
s2.showScore();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// 立方体类与应用
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Cube
|
||||
{
|
||||
public:
|
||||
void init(int l, int w, int h)
|
||||
{
|
||||
this->a = l;
|
||||
this->b = w;
|
||||
this->c = h;
|
||||
}
|
||||
int S(); // 面积
|
||||
int V(); // 体积
|
||||
void show();
|
||||
bool isEqual(Cube &tmp);
|
||||
|
||||
private:
|
||||
int a; // 长
|
||||
int b; // 宽
|
||||
int c; // 高
|
||||
};
|
||||
|
||||
int Cube::S()
|
||||
{
|
||||
return 2 * (a * b + a * c + b * c);
|
||||
}
|
||||
|
||||
int Cube::V()
|
||||
{
|
||||
return a * b * c;
|
||||
}
|
||||
|
||||
void Cube::show()
|
||||
{
|
||||
cout << "S = " << S() << ", V = " << V() << endl;
|
||||
}
|
||||
|
||||
bool Cube::isEqual(Cube &tmp)
|
||||
{
|
||||
// if (this->a == tmp.a && this->b == tmp.b && this->c == tmp.c)
|
||||
if (this->S() == tmp.S() && this->V() == tmp.V())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool equalCube(Cube &c1, Cube &c2)
|
||||
{
|
||||
if (c1.S() == c2.S() && c1.V() == c2.V())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *resBool(bool b) // bool 数字值转换人类可读
|
||||
{
|
||||
if (b != 0)
|
||||
return "true";
|
||||
return "false";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Cube c1, c2, c3;
|
||||
c1.init(2, 3, 4);
|
||||
cout << "c1: " << endl;
|
||||
c1.show();
|
||||
|
||||
c2.init(3, 4, 5);
|
||||
cout << "c2: " << endl;
|
||||
c2.show();
|
||||
|
||||
c3.init(4, 2, 3);
|
||||
|
||||
cout << "Cube::isEqual(c2) = " << resBool(c1.isEqual(c2)) << endl;
|
||||
cout << "equalCube(c1, c2) = " << resBool(equalCube(c1, c3)) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// 点和圆的关系
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum Pos_e
|
||||
{
|
||||
onCircle = 4, // 点在圆上
|
||||
inCircle, // 点在圆内
|
||||
outCircle // 点在圆外
|
||||
};
|
||||
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
};
|
||||
|
||||
class AdvCircle
|
||||
{
|
||||
public:
|
||||
int init(int x0, int y0, int r)
|
||||
{
|
||||
this->r = r;
|
||||
o.x = x0;
|
||||
o.y = y0;
|
||||
}
|
||||
|
||||
Pos_e at(Point &point);
|
||||
|
||||
private:
|
||||
int r;
|
||||
Point o; // 圆心点
|
||||
};
|
||||
|
||||
Pos_e AdvCircle::at(Point &point)
|
||||
{
|
||||
int distence = pow((point.x - this->o.x), 2) + pow((point.y - this->o.y), 2);
|
||||
int rr = r * r;
|
||||
if (distence == rr)
|
||||
{
|
||||
return onCircle;
|
||||
}
|
||||
else if (distence < rr)
|
||||
{
|
||||
return inCircle;
|
||||
}
|
||||
else
|
||||
return outCircle;
|
||||
}
|
||||
|
||||
string posToString(Pos_e pos)
|
||||
{
|
||||
switch (pos)
|
||||
{
|
||||
case onCircle:
|
||||
return "在圆上";
|
||||
break;
|
||||
case inCircle:
|
||||
return "在圆内";
|
||||
break;
|
||||
case outCircle:
|
||||
return "在圆外";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
AdvCircle c1;
|
||||
c1.init(0, 0, 2);
|
||||
|
||||
Point p1;
|
||||
p1.x = 1;
|
||||
p1.y = 1;
|
||||
|
||||
cout << "c1.at(p1) " << posToString(c1.at(p1)) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// 引用相当于变量的别名
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
|
||||
// 给 arr 设置一个别名(引用)
|
||||
// 先定义 5 个元素数组类型的别名
|
||||
typedef int ArrRef[5];
|
||||
ArrRef &a = arr;
|
||||
|
||||
// 通过别名操作数组
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
cout << a[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// 数组引用的方法二
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
int arr[5] = {1, 2, 3, 4, 5};
|
||||
|
||||
// 直接定义 5 个元素数组类型的引用
|
||||
int(&a)[5] = arr;
|
||||
|
||||
// 通过别名操作数组
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
cout << a[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 引用传递: 会改变实参的值
|
||||
// 值传递: 不会改变实参的值
|
||||
void cumsum(int &total, int n) // total 是引用传递,n 是值传递
|
||||
{
|
||||
total += n;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int total = 0;
|
||||
int n = 0;
|
||||
while (cin >> n)
|
||||
{
|
||||
cumsum(total, n);
|
||||
cout << "total = " << total << endl;
|
||||
if (total > 100)
|
||||
break;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#define N 10 // 定义常量
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef int TenArr[N];
|
||||
|
||||
TenArr &new_arr()
|
||||
{
|
||||
static int m[N] = {0}; // 全局静态区存储,程序结束后才释放
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
m[i] = i;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TenArr &p = new_arr();
|
||||
int i = 0;
|
||||
while (i < N)
|
||||
{
|
||||
cout << "p[" << i << "] = " << p[i++] << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#include <iostream>
|
||||
|
||||
#define N 7
|
||||
|
||||
using namespace std;
|
||||
|
||||
void sort(int (&arr)[N])
|
||||
{
|
||||
for (int i = 0; i <= N - 1; i++)
|
||||
{
|
||||
for (int j = 0; j <= N - i - 1; j++)
|
||||
{
|
||||
if (arr[j] > arr[j + 1])
|
||||
{
|
||||
arr[j] ^= arr[j + 1];
|
||||
arr[j + 1] ^= arr[j];
|
||||
arr[j] ^= arr[j + 1];
|
||||
// int temp = arr[j];
|
||||
// arr[j] = arr[j + 1];
|
||||
// arr[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sort(int arr[], int size)
|
||||
{
|
||||
for (int i = 0; i < size - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < size - i - 1; j++)
|
||||
{
|
||||
if (arr[j] > arr[j + 1])
|
||||
{
|
||||
int temp = arr[j];
|
||||
arr[j] = arr[j + 1];
|
||||
arr[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int nums[] = {1, 5, 2, 0, 9, 10, 7};
|
||||
int size = sizeof(nums) / sizeof(nums[0]);
|
||||
|
||||
sort(nums);
|
||||
// sort(nums, size);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
cout << nums[i] << "\t";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// 指针的引用
|
||||
// 为指针取个别名,相当于'指针的指针'
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct STU
|
||||
{
|
||||
int sid;
|
||||
float score;
|
||||
};
|
||||
|
||||
void set_score(STU *&q, int sid, float score)
|
||||
{
|
||||
q->sid = sid;
|
||||
q->score = score;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
STU *p = (STU *)malloc(sizeof(STU));
|
||||
|
||||
set_score(p, 1, 99);
|
||||
|
||||
cout << "sid = " << p->sid << ", score = " << p->score << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// 指针的引用
|
||||
// 为指针取个别名,相当于'指针的指针'
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct STU
|
||||
{
|
||||
int sid;
|
||||
float score;
|
||||
};
|
||||
|
||||
// 指针的指针
|
||||
void set_score(STU **q, int sid, float score)
|
||||
{
|
||||
(*q)->sid = sid;
|
||||
(*q)->score = score;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
STU *p = (STU *)malloc(sizeof(STU));
|
||||
|
||||
set_score(&p, 2, 98);
|
||||
|
||||
cout << "sid = " << p->sid << ", score = " << p->score << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// 常量引用
|
||||
// 相当于 常量指针常量
|
||||
// 用法: const 数据类型 &变量名 = 其他变量或常量
|
||||
|
||||
// 注意:
|
||||
// 一般的引用不能赋值常量(字面量),但是 const 引用可以赋值常量
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int x = 10;
|
||||
const int &x1 = x;
|
||||
|
||||
// error: assignment of read - only reference ‘x1’
|
||||
x1 -= 5; // const 修饰的引用不能修改内容
|
||||
cout << "x = " << x << endl;
|
||||
|
||||
const int &x2 = 50;
|
||||
cout << "x2 = " << x2 << endl;
|
||||
|
||||
// error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
|
||||
int &x3 = 'a'; // 常量不能赋值给非常量引用
|
||||
cout << "x3 = " << x3 << endl;
|
||||
return 0;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// 内联函数
|
||||
// 函数前面添加了 inline 关键字,则此函数为内联函数
|
||||
// 内联函数只能在当前文件中使用,相当于函数前面加 static
|
||||
|
||||
// 内联函数一般用于替换 有参的宏,有参宏经常会出错,而且参数是无数据类型
|
||||
// 每一次使用内联函数时,都会像有参宏一样,展开一次(内联函数不入栈,运行效率高,编译时会提前处理)
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define ADD(x, y) x + y
|
||||
// 内联函数
|
||||
inline int add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int ret1 = ADD(10, 20) * 10;
|
||||
cout << "ret = " << ret1 << endl;
|
||||
|
||||
int ret2 = add(10, 20) * 10;
|
||||
cout << "ret = " << ret2 << endl;
|
||||
return 0;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// 函数的默认参数
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool isSs(int n = 10) // 判断 n 是否为质数
|
||||
{
|
||||
int i = 2;
|
||||
for (; i < n / 2; i++)
|
||||
{
|
||||
if (n % i == 0)
|
||||
return false; // 0 为假
|
||||
}
|
||||
return true; // 非 0 为真
|
||||
}
|
||||
|
||||
double area(double r = 1.0) // 求面积
|
||||
{
|
||||
return 3.14 * r * r;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "isSS(7) is " << isSs(7) << endl;
|
||||
cout << "isSS() is " << isSs() << endl;
|
||||
cout << "area() is " << area() << endl;
|
||||
cout << "area(2) is " << area(2) << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// 找错
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
const int n = 10;
|
||||
const int &p = n;
|
||||
// p++; // 错误,不能修改常量引用所引用的值
|
||||
cout << "n=" << n << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int func1(int a, int, int b = 20)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << func1(10, 30) << endl;
|
||||
cout << func1(10, 10, 100) << endl;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// 1. 2. 创建一个名为 Rectangle 的类,具有成员变量 width 和 height,以及成员函数 double calculateArea() ,用于计算矩形的面积。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Rectangle
|
||||
{
|
||||
public:
|
||||
double calculateArea()
|
||||
{
|
||||
return width * height;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 1. 2. 创建一个名为 Circle 的类,具有成员变量 radius 和 pi(圆周率),以及成员函数 double calculateArea() ,用于计算圆的面积。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Circle
|
||||
{
|
||||
public:
|
||||
double radius, pi = 3.1415926;
|
||||
double calculateArea()
|
||||
{
|
||||
return pi * radius * radius;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// 1. 2. 创建一个名为 BankAccount 的类,具有成员变量 accountNumber 和 balance,以及成员函数 void deposit(double amount) 和 void withdraw(double amount) ,用于存款和取款操作。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class BankAccount
|
||||
{
|
||||
public:
|
||||
long accountNumber, balance;
|
||||
void deposit(double amount)
|
||||
{
|
||||
this->balance += amount;
|
||||
}
|
||||
void withdraw(double amount)
|
||||
{
|
||||
this->balance -= amount;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// 创建一个名为 Student 的类,具有成员变量 name 和 grade,以及成员函数 void study(char *course) ,用于表示某班级的某学生正在学习某一门课程。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Student
|
||||
{
|
||||
public:
|
||||
char name[32]; // 学生姓名
|
||||
char grade[32]; // 班级名
|
||||
void study(char *course)
|
||||
{
|
||||
cout << this->grade << "班的" << this->name << "同学正在学习" << course << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// 创建一个名为 Car 的类,具有成员变量 brand 和 speed,以及成员函数 void accelerate() 和 void brake() ,用于加速和刹车操作。
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Car
|
||||
{
|
||||
public:
|
||||
string brand;
|
||||
int speed;
|
||||
void accelerate()
|
||||
{
|
||||
this->speed += 1;
|
||||
cout << "加速 1 码" << endl;
|
||||
}
|
||||
void brake()
|
||||
{
|
||||
if (this->speed > 0)
|
||||
{
|
||||
this->speed -= 1;
|
||||
cout << "减速中" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "车已经停下了" << endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// 1. 2. 创建一个名为 Employee 的类,具有成员变量 name、id 和 salary,以及成员函数 void displayInfo() ,用于显示员工的信息。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Employee
|
||||
{
|
||||
public:
|
||||
string name;
|
||||
int id;
|
||||
int salary;
|
||||
void displayinfo()
|
||||
{
|
||||
cout << "员工信息\nid: " << this->id << "\t姓名: " << this->name << "\t薪水: " << this->salary << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// 创建一个名为 Book 的类,具有成员变量 title、author 和 year,以及成员函数 void displayInfo() ,用于显示图书的信息。 创建Book类的数组,至少存放5本书,并设计全局函数,实现Book对象按year从大到小排序,并显示排序后信息。
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Book
|
||||
{
|
||||
public:
|
||||
string title, author;
|
||||
int year;
|
||||
// 使用 const 加 & 引用,避免不必要的拷贝
|
||||
void init(const string &title, const string &author, int year)
|
||||
{
|
||||
this->title = title;
|
||||
this->author = author;
|
||||
this->year = year;
|
||||
}
|
||||
void displayinfo()
|
||||
{
|
||||
cout << "书名: " << this->title << " , 作者: " << this->author << " , 出版年份: " << this->year << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void sortAndShow(Book book[], int n)
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < n; i++)
|
||||
{
|
||||
for (int j = 0; j < n - i - 1; j++)
|
||||
{
|
||||
if (book[j].year < book[j + 1].year)
|
||||
{
|
||||
Book tmp = book[j];
|
||||
book[j] = book[j + 1];
|
||||
book[j + 1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
book[i].displayinfo();
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Book books[5];
|
||||
books[0].init("数学", "张三", 1998);
|
||||
books[1].init("语文", "李四", 2009);
|
||||
books[2].init("英语", "王五", 1987);
|
||||
books[3].init("物理", "赵六", 2008);
|
||||
books[4].init("化学", "郑七", 1982);
|
||||
|
||||
sortAndShow(books, 5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
// 对象的构造与析构
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Animal
|
||||
{
|
||||
public:
|
||||
Animal();
|
||||
Animal(const char *name, const char *food);
|
||||
~Animal(); // 析构函数(对象回收时,清理资源)
|
||||
|
||||
public:
|
||||
void eat();
|
||||
void say(const char *msg);
|
||||
|
||||
private:
|
||||
char *name, *food;
|
||||
};
|
||||
|
||||
Animal::Animal()
|
||||
{
|
||||
name = (char *)malloc(32);
|
||||
food = (char *)malloc(32);
|
||||
strcpy(name, "小动物");
|
||||
strcpy(food, "水");
|
||||
}
|
||||
|
||||
Animal::Animal(const char *name, const char *food)
|
||||
{
|
||||
this->name = (char *)malloc(32);
|
||||
this->food = (char *)malloc(32);
|
||||
strcpy(this->name, name);
|
||||
strcpy(this->food, food);
|
||||
}
|
||||
|
||||
Animal::~Animal()
|
||||
{
|
||||
cout << name << "空间回收" << endl;
|
||||
|
||||
// 回收在构造函数(初始化)中动态分配的空间
|
||||
free(name);
|
||||
free(food);
|
||||
}
|
||||
|
||||
void Animal::eat()
|
||||
{
|
||||
cout << name << "吃: " << food << endl;
|
||||
}
|
||||
|
||||
void Animal::say(const char *msg)
|
||||
{
|
||||
cout << name << "遇到主人: " << msg << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 尽量使用堆空间创建类的对象: 使用 类指针 和 new 关键字
|
||||
Animal *anm1 = new Animal();
|
||||
anm1->eat();
|
||||
|
||||
// 使用栈空间的情况
|
||||
Animal anm2;
|
||||
anm2.say("小浣熊");
|
||||
|
||||
// 使用括号
|
||||
Animal anm3("小黄", "肉");
|
||||
anm3.eat();
|
||||
anm3.say("旺旺...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// 深拷贝和浅拷贝
|
||||
// 深拷贝举例
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Person
|
||||
{
|
||||
private:
|
||||
char *name;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Person(const char *name, int age)
|
||||
{
|
||||
this->name = (char *)malloc(32);
|
||||
strcpy(this->name, name);
|
||||
this->age = age;
|
||||
}
|
||||
Person(const Person &obj) // 深拷贝,重写构造方法
|
||||
{
|
||||
this->name = (char *)malloc(32);
|
||||
strcpy(this->name, obj.name);
|
||||
this->age = obj.age;
|
||||
}
|
||||
~Person()
|
||||
{
|
||||
if (name != NULL)
|
||||
{
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void setName(char *name)
|
||||
{
|
||||
strcpy(this->name, name);
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << this << " " << name << ", " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p1("disen", 20);
|
||||
Person p2 = p1;
|
||||
p2.setName("lucy");
|
||||
Person p3 = Person(p2);
|
||||
p3.setName("Jack");
|
||||
|
||||
p1.show();
|
||||
p2.show();
|
||||
p3.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 多个对象的构造和析构
|
||||
// 初始化列表
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x, y, z;
|
||||
// char *name;
|
||||
string name; // char * 建议替换为 string
|
||||
|
||||
public:
|
||||
A(int x, int y, int z, const string &name) : x(x), y(y), z(z), name(name) {}
|
||||
void show()
|
||||
{
|
||||
cout << x << ", " << y << ", " << z << ", " << name << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1(10, 20, 4, "disen");
|
||||
a1.show();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// 多个对象的构造和析构
|
||||
// 类对象作为成员
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A()
|
||||
{
|
||||
cout << "A()" << endl;
|
||||
}
|
||||
A(int x)
|
||||
{
|
||||
cout << "A(int x)" << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << "~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
B() // 构造函数用于初始化成员数据,说明成员变量先创建
|
||||
{
|
||||
cout << "B()" << endl;
|
||||
}
|
||||
B(int x)
|
||||
{
|
||||
cout << "B(int x)" << endl;
|
||||
}
|
||||
~B() // A 的对象在 B 的空间中,A 对象在 B 空间释放之后就失效,失效也会释放空间(调用析构函数)
|
||||
{
|
||||
cout << "~B()" << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
A a; // A 类的对象作为 B 类的成员
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
B b1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// 多个对象的构造和析构
|
||||
// 类对象作为成员
|
||||
// d12 的改造测试
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A()
|
||||
{
|
||||
cout << "A()" << endl;
|
||||
}
|
||||
A(int x)
|
||||
{
|
||||
cout << "A(int x)" << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << "~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
B() // 构造函数用于初始化成员数据,说明成员变量先创建
|
||||
{
|
||||
cout << "B()" << endl;
|
||||
}
|
||||
// 成员名:(参数名)
|
||||
B(int x) : a(x) // 指定 a 对象的构造函数进行数据初始化
|
||||
{
|
||||
cout << "B(int x)" << endl;
|
||||
}
|
||||
~B() // A 的对象在 B 的空间中,A 对象在 B 空间释放之后就失效,失效也会释放空间(调用析构函数)
|
||||
{
|
||||
cout << "~B()" << endl;
|
||||
}
|
||||
|
||||
private:
|
||||
A a; // A 类的对象作为 B 类的成员
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
B b1(1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// explicit 关键字(禁止隐式转换)
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Person
|
||||
{
|
||||
private:
|
||||
int age;
|
||||
string name;
|
||||
|
||||
public:
|
||||
Person(const char *name, int age = 18)
|
||||
{
|
||||
this->name = name;
|
||||
this->age = age;
|
||||
}
|
||||
// explicit 使得不存在从 "int" 转换到 "Person" 的适当构造函数
|
||||
explicit Person(int age) // 进制 Person p = 值
|
||||
{
|
||||
this->age = age;
|
||||
this->name = "disen";
|
||||
}
|
||||
|
||||
public:
|
||||
void show()
|
||||
{
|
||||
cout << name << ", " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p1 = "jack";
|
||||
Person p2 = Person("doken", 9);
|
||||
Person p3 = Person(1);
|
||||
// Person p4 = 2; // 不存在从 "int" 转换到 "Person" 的适当构造函数
|
||||
p1.show();
|
||||
p2.show();
|
||||
p3.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 动态创建对象(malloc / realloc / calloc 在堆中创建空间, new 关键字)
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
|
||||
public:
|
||||
A(int x)
|
||||
{
|
||||
this->x = x;
|
||||
cout << "A(int)" << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << "~A()" << endl;
|
||||
}
|
||||
|
||||
public:
|
||||
void init(int x)
|
||||
{
|
||||
this->x = x;
|
||||
cout << "init(int)" << endl;
|
||||
}
|
||||
void clean()
|
||||
{
|
||||
cout << "clean()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 1) 使用 malloc 方式创建
|
||||
// cout << "A size is " << sizeof(A) << endl;
|
||||
// A *a1 = (A *)malloc(sizeof(A));
|
||||
// // a1->A(20); // 不允许显式调用构造函数
|
||||
// a1->init(20); // 初始化数据
|
||||
// a1->clean(); // 释放数据的空间
|
||||
// a1->~A(); // 析构函数可以显式调用
|
||||
// free(a1);
|
||||
|
||||
// 2) new 方式创建,delete释放
|
||||
A *a1 = new A(1);
|
||||
delete a1; // 用完之后直接 delete 释放空间
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// 扩展 new 和 delete
|
||||
// 数组的 new 和 delete
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// 使用拓展的 new 创建类对象数组
|
||||
int *p = new int[6]{1, 2, 3, 4, 5, 6};
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
cout << *(p + i) << endl;
|
||||
}
|
||||
delete[] p; // 释放数组空间
|
||||
|
||||
cout << "--------------------" << endl;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
cout << *(p + i) << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
|
||||
public:
|
||||
A()
|
||||
{
|
||||
cout << "A()" << endl;
|
||||
name = "no name";
|
||||
}
|
||||
A(const string &name)
|
||||
{
|
||||
cout << "A(const string &name)" << endl;
|
||||
this->name = name;
|
||||
cout << "name: " << name << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << name << "~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// A *p = new A[5];
|
||||
// delete[] p;
|
||||
// A *p2 = new A[4]{A("a"), A("b"), A("c"), A("d")};
|
||||
// delete[] p2; // 释放数组中成员对象时,从高(地址)到低(地址)依次释放
|
||||
|
||||
A *a = new A("abc");
|
||||
free(a); // 只是放指针指向的堆空间,不会调用对象的析构函数
|
||||
|
||||
char *a2 = (char *)malloc(sizeof(A));
|
||||
delete a2; // 可以删除简单的 void* 指针
|
||||
|
||||
return 0;
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// 构造函数的分类与调用
|
||||
// 拷贝构造函数
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
|
||||
public:
|
||||
int x;
|
||||
|
||||
public:
|
||||
A() {}
|
||||
A(A &other) // 拷贝构造函数
|
||||
{
|
||||
this->x = other.x;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1; // 调用无参的构造函数进行初始化 a1 对象
|
||||
a1.x = 10;
|
||||
cout << "a1 x = " << a1.x << endl;
|
||||
|
||||
A a2(a1); // 使用拷贝构造
|
||||
cout << "a2 x = " << a2.x << endl;
|
||||
|
||||
A *a3 = new A(); // 使用指针和new,在堆空间创建对象
|
||||
// a3->x = 20;
|
||||
cout << "a3 x = " << a3->x << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// 构造函数的分类与调用
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class B
|
||||
{
|
||||
private:
|
||||
int n;
|
||||
|
||||
public:
|
||||
// B() { cout << "B()" << endl; }
|
||||
B(int n)
|
||||
{
|
||||
cout << "B(int n)" << endl;
|
||||
this->n = n;
|
||||
}
|
||||
B(const B &other)
|
||||
{
|
||||
cout << "B(B &other)" << endl;
|
||||
this->n = other.n;
|
||||
}
|
||||
|
||||
public:
|
||||
void showN()
|
||||
{
|
||||
cout << "n = " << n << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
B b1 = 20; // 隐式调用 B(int n), B(20), 只创建一个对象
|
||||
|
||||
B b2 = B(30); // 显式调用 B(int n)
|
||||
|
||||
B b3 = b2; // 隐式调用 B(B &other)
|
||||
|
||||
B &b4 = b3; // 不会创建空间,只是一个别名
|
||||
|
||||
B b5(b4); // 显式调用 B(B &other)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// 构造函数的分类与调用
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class C
|
||||
{
|
||||
private:
|
||||
int x, y;
|
||||
|
||||
public:
|
||||
C(int x)
|
||||
{
|
||||
this->x = x;
|
||||
}
|
||||
C(int x, int y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
C(const C &other)
|
||||
{
|
||||
this->x = other.x;
|
||||
this->y = other.y;
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << "x = " << x << ", y = " << y << endl;
|
||||
}
|
||||
~C()
|
||||
{
|
||||
cout << this << "释放资源" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "C(0,1) 之前" << endl;
|
||||
C(0, 1); // 匿名创建的类对象,创建完后就直接释放了
|
||||
cout << "C(0,1) 之后" << endl;
|
||||
|
||||
C c1(1, 2);
|
||||
c1.show();
|
||||
C c2 = (1, 5); // 使用单参数构造函数 C(int x), 然后将其改为 ", 运算" 后面的值
|
||||
// C c2 = 1;
|
||||
c2.show();
|
||||
C c3 = C(3, 4);
|
||||
c3.show();
|
||||
C c4(c3);
|
||||
c4.show();
|
||||
C &c5 = c4;
|
||||
c5.show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// 创建类对象的指针
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
char *msg;
|
||||
|
||||
public:
|
||||
A()
|
||||
{
|
||||
this->msg = (char *)malloc(30);
|
||||
strcpy(this->msg, "haha");
|
||||
}
|
||||
A(const char *msg)
|
||||
{
|
||||
this->msg = (char *)malloc(30);
|
||||
strcpy(this->msg, msg);
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << this << "release msg : " << this->msg << endl;
|
||||
free(this->msg);
|
||||
// free(this);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A *a1 = new A;
|
||||
cout << "a1->msg: " << a1->msg << endl;
|
||||
|
||||
A *a2 = new A("disen 666");
|
||||
cout << "a2->msg: " << a2->msg << endl;
|
||||
|
||||
// 【注意】指针释放空间时, 不会自动执行对象的析构函数
|
||||
// 可以通过手动调用 对象的析构方法 或使用 delete
|
||||
a1->~A();
|
||||
free(a1);
|
||||
// a2->~A();
|
||||
// delete a1;
|
||||
delete a2;
|
||||
|
||||
A a3;
|
||||
// 注意: delete 只能删除 new 出来的对象,即对象的指针
|
||||
// A &a4 = a3;
|
||||
// delete &a4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// 拷贝构造函数的调用时机
|
||||
// 编译器优化,不会调用拷贝构造函数,而是直接创建一个返回值的引用
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x = 0;
|
||||
|
||||
public:
|
||||
A()
|
||||
{
|
||||
cout << this << " A()" << endl;
|
||||
}
|
||||
A(const A &other)
|
||||
{
|
||||
this->x = other.x;
|
||||
cout << this << " A(const A &other)" << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << this << " ~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void test1(A a) // ?是否调用拷贝构造函数
|
||||
{
|
||||
cout << "test1(A a) a.x = " << a.x << endl;
|
||||
|
||||
// 当函数结束时,a 释放,会调用析构函数
|
||||
}
|
||||
|
||||
A test2()
|
||||
{
|
||||
A a1; // 局部的类对象, 没有执行拷贝构造函数
|
||||
a1.x = 1;
|
||||
cout << "test2() a1.x = " << a1.x << endl;
|
||||
return a1; // 释放局部对象 a1
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
A a2 = test2(); // 返回 A 类的对象,没有调用拷贝构造函数,只是创建了一个 test2() 返回值的引用
|
||||
cout << "test3() a2.x = " << a2.x << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A a0;
|
||||
// test1(a0); // 作为值传递,调用拷贝构造函数
|
||||
|
||||
test3();
|
||||
cout << "over" << endl;
|
||||
return 0;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// 拷贝构造函数的调用时机
|
||||
// 编译器优化,不会调用拷贝构造函数,而是直接创建一个返回值的引用
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x = 0;
|
||||
|
||||
public:
|
||||
A()
|
||||
{
|
||||
cout << this << " A()" << endl;
|
||||
}
|
||||
A(const A &other)
|
||||
{
|
||||
this->x = other.x;
|
||||
cout << this << " A(const A &other)" << endl;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
cout << this << " ~A()" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void test1(A &a) // ?是否调用拷贝构造函数
|
||||
// void test1(A a) // ?是否调用拷贝构造函数
|
||||
{
|
||||
cout << "test1(A a) a.x = " << a.x << endl;
|
||||
|
||||
// 当函数结束时,a 释放,会调用析构函数
|
||||
}
|
||||
|
||||
A test2() // 不要声明为 A &test2(), 因为返回对象时,会释放局部对象,导致返回的引用指向一个已经释放的对象
|
||||
{
|
||||
A a1; // 局部的类对象, 没有执行拷贝构造函数
|
||||
a1.x = 1;
|
||||
cout << "test2() a1.x = " << a1.x << endl;
|
||||
return a1; // 释放局部对象 a1
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
cout << "tsss = " << endl;
|
||||
|
||||
A a2 = test2(); // 返回 A 类的对象,没有调用拷贝构造函数,只是创建了一个 test2() 返回值的引用
|
||||
cout << "test3() a2.x = " << a2.x << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A a0;
|
||||
test1(a0); // 作为值传递,调用拷贝构造函数
|
||||
|
||||
// test3();
|
||||
cout << "over" << endl;
|
||||
return 0;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// 构造函数的调用规则
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
void show()
|
||||
{
|
||||
cout << this << " x = " << x << ", y = " << y << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
A a1;
|
||||
// A a2 = a1; // 自动调用拷贝构造函数 A(const A&obj)
|
||||
|
||||
a1.x = 20;
|
||||
A a2 = a1; // 自动调用拷贝构造函数 A(const A&obj)
|
||||
|
||||
a1.y = 30;
|
||||
// A a2 = a1; // 自动调用拷贝构造函数 A(const A&obj)
|
||||
|
||||
a1.show(); // 20,30 浅拷贝
|
||||
a2.show(); //
|
||||
return 0;
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// 深拷贝和浅拷贝
|
||||
// 浅拷贝举例
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Person
|
||||
{
|
||||
private:
|
||||
char *name;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Person(const char *name, int age)
|
||||
{
|
||||
this->name = (char *)malloc(32);
|
||||
this->age = age;
|
||||
}
|
||||
void release_name_pointer()
|
||||
{
|
||||
free(name);
|
||||
}
|
||||
|
||||
public:
|
||||
void setName(char *name)
|
||||
{
|
||||
strcpy(this->name, name);
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << name << ", " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Person p1("disen", 20);
|
||||
Person p2 = p1;
|
||||
Person p3 = Person(p2);
|
||||
p3.setName("Jack");
|
||||
|
||||
p1.show();
|
||||
p2.show();
|
||||
p3.show();
|
||||
|
||||
// p1.release_name_pointer();
|
||||
p2.release_name_pointer();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SLink
|
||||
{
|
||||
private:
|
||||
char *title;
|
||||
|
||||
public:
|
||||
SLink() {}
|
||||
SLink(const char *title)
|
||||
{
|
||||
this->title = (char *)malloc(50);
|
||||
strcpy(this->title, title);
|
||||
}
|
||||
~SLink();
|
||||
void show()
|
||||
{
|
||||
cout << title << endl;
|
||||
}
|
||||
};
|
||||
|
||||
SLink::~SLink() {}
|
||||
|
||||
int main()
|
||||
{
|
||||
SLink s1;
|
||||
SLink s2("disen 补课中");
|
||||
s2.show();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Color
|
||||
{
|
||||
private:
|
||||
int r, g, b;
|
||||
|
||||
public:
|
||||
explicit Color(int r, int g = 0, int b = 0) : r(r), g(g), b(b)
|
||||
{
|
||||
}
|
||||
void show()
|
||||
{
|
||||
cout << r << "," << g << "," << b << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Color c = Color(2, 3, 4);
|
||||
c.show();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Point
|
||||
{
|
||||
private:
|
||||
int x, y;
|
||||
|
||||
public:
|
||||
Point(int x, int y);
|
||||
void show()
|
||||
{
|
||||
cout << x << "," << y << endl;
|
||||
}
|
||||
};
|
||||
|
||||
Point::Point(int x, int y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Point *p1 = new Point[3]{Point(1, 2), Point(2, 3), Point(3, 4)};
|
||||
p1[2].show();
|
||||
delete[] p1;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// 设计一个学生类,包括学号、姓名、成绩,并设计接口函数用来输出这些学生数据并计算平均分。并编写main函数进行测试:
|
||||
// 输出如:
|
||||
// 学号 姓名 成绩 1 张XX 98 2 王XX 90 3 XXX 89 平均成绩: XX
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Student
|
||||
{
|
||||
private:
|
||||
int sid;
|
||||
string name;
|
||||
float score;
|
||||
|
||||
public:
|
||||
Student(int sid, const string &name, float score) : sid(sid), name(name), score(score)
|
||||
{
|
||||
}
|
||||
~Student() {}
|
||||
|
||||
public:
|
||||
static void avgAndShow(Student *stus, int n);
|
||||
};
|
||||
|
||||
void Student::avgAndShow(Student *stus, int n)
|
||||
{
|
||||
float avg = 0.0f;
|
||||
cout << "学号\t"
|
||||
<< "姓名\t"
|
||||
<< "成绩" << endl;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
cout << stus[i].sid << "\t" << stus[i].name << "\t" << stus[i].score << endl;
|
||||
avg += stus[i].score / n;
|
||||
}
|
||||
cout << "平均成绩: " << setprecision(3) << avg << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Student *stus = new Student[3]{
|
||||
Student(1, "张XX", 98),
|
||||
Student(2, "王XX", 90),
|
||||
Student(3, "XXX", 89)};
|
||||
|
||||
Student::avgAndShow(stus, 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
// 创建一个名为 LinkedList 的类,实现链表的基本操作,包括插入节点、删除节点和反转链表等。
|
||||
// 【提示】单向链表
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
int data;
|
||||
Node *next;
|
||||
|
||||
public:
|
||||
Node(int value)
|
||||
{
|
||||
this->data = value;
|
||||
this->next = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class LinkedList
|
||||
{
|
||||
private:
|
||||
Node *head;
|
||||
|
||||
public:
|
||||
LinkedList()
|
||||
{
|
||||
head = NULL; // 初始头结点
|
||||
}
|
||||
|
||||
public:
|
||||
Node *insertNode(int insValue);
|
||||
Node *deleteNode(int delValue);
|
||||
Node *reverseLinkedList();
|
||||
void print();
|
||||
};
|
||||
|
||||
Node *LinkedList::insertNode(int insValue)
|
||||
{
|
||||
Node *newNode = new Node(insValue);
|
||||
|
||||
if (NULL == head)
|
||||
head = newNode;
|
||||
|
||||
Node *p = head;
|
||||
while (p->next != NULL)
|
||||
{
|
||||
p = p->next;
|
||||
}
|
||||
p->next = newNode;
|
||||
return head;
|
||||
}
|
||||
|
||||
Node *LinkedList::deleteNode(int delValue)
|
||||
{
|
||||
if (NULL == head)
|
||||
{
|
||||
cout << "不存在链表,删除失败" << endl;
|
||||
return head;
|
||||
}
|
||||
|
||||
if (head->data == delValue) // 当删除的节点是头节点时
|
||||
{
|
||||
Node *temp = head;
|
||||
head = head->next;
|
||||
delete temp;
|
||||
return head;
|
||||
}
|
||||
|
||||
Node *p = head;
|
||||
while (p->next != NULL)
|
||||
{
|
||||
if (p->next->data == delValue)
|
||||
{
|
||||
Node *temp = p->next;
|
||||
p->next = temp->next;
|
||||
delete temp;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (p != NULL && p->data == delValue) // 处理最后一个节点的情况
|
||||
{
|
||||
delete p;
|
||||
p = NULL;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
Node *LinkedList::reverseLinkedList()
|
||||
{
|
||||
Node *p = head;
|
||||
Node *new_head = NULL;
|
||||
Node *p_next = NULL;
|
||||
while (p != NULL)
|
||||
{
|
||||
p_next = p->next;
|
||||
p->next = new_head;
|
||||
new_head = p;
|
||||
p = p_next;
|
||||
}
|
||||
|
||||
head = new_head; // 新头指针
|
||||
return head;
|
||||
}
|
||||
|
||||
void LinkedList::print()
|
||||
{
|
||||
Node *p = head;
|
||||
while (p != NULL)
|
||||
{
|
||||
cout << p->data << " ";
|
||||
p = p->next;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
LinkedList list;
|
||||
|
||||
// 插入节点
|
||||
list.insertNode(1);
|
||||
list.insertNode(3);
|
||||
list.insertNode(8);
|
||||
list.insertNode(2);
|
||||
|
||||
// 测试打印
|
||||
cout << "原始链表: ";
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
// 删除节点
|
||||
list.deleteNode(3);
|
||||
cout << "删除3后的链表: ";
|
||||
list.print();
|
||||
cout << endl;
|
||||
|
||||
// 反转链表
|
||||
list.reverseLinkedList();
|
||||
cout << "反序链表后: ";
|
||||
list.print();
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user