返回

C++学习笔记02-语言基础

基础知识

数据类型

基本数据类型

基本数据类型:布尔型bool、字符型char、整型int、浮点型float、双浮点型double、无类型void、宽字符型wchar_t(实际为short int

一些基本类型可以使用一个或多个类型修饰符进行修饰

修饰符 描述 示例
signed 有符号类型(默认) signed int x = -10;
unsigned 无符号类型 unsigned int y = 10;
short 短整型 short int z = 100;
long 长整型 long int a = 100000;
const 常量,值不可修改 const int b = 5;
volatile 变量可能被意外修改(硬件、其他线程),禁止编译器优化 volatile int c = 10;
mutable 类成员可以在 const 对象中修改 mutable int counter;
  • 默认情况下,int、short、long 都是带符号的,即 signed
  • long int 8 个字节,int 都是 4 个字节
数据类型 描述 大小(字节) 范围/取值示例
bool 布尔类型,表示真或假 1 truefalse
char 字符类型,通常用于存储 ASCII 字符 1 -128 到 127 或 0 到 255
signed char 有符号字符类型 1 -128 到 127
unsigned char 无符号字符类型 1 0 到 255
wchar_t 宽字符类型,用于存储 Unicode 字符 2 或 4 取决于平台
char16_t 16 位 Unicode 字符类型(C++11 引入) 2 0 到 65,535
char32_t 32 位 Unicode 字符类型(C++11 引入) 4 0 到 4,294,967,295
short 短整型 2 -32,768 到 32,767
unsigned short 无符号短整型 2 0 到 65,535
int 整型 4 -2,147,483,648 到 2,147,483,647
unsigned int 无符号整型 4 0 到 4,294,967,295
long 长整型 4 或 8 取决于平台
unsigned long 无符号长整型 4 或 8 取决于平台
long long 长长整型(C++11 引入) 8 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long long 无符号长长整型(C++11 引入) 8 0 到 18,446,744,073,709,551,615
float 单精度浮点数 4 约 ±3.4e±38(6-7 位有效数字)
double 双精度浮点数 8 约 ±1.7e±308(15 位有效数字)
long double 扩展精度浮点数 8、12 或 16 取决于平台

C++11 新增类型

数据类型 描述 示例
auto 自动类型推断 auto x = 10;
decltype 获取表达式的类型 decltype(x) y = 20;
nullptr 空指针常量 int* ptr = nullptr;
std::initializer_list 初始化列表类型 std::initializer_list<int> list = {1, 2, 3};
std::tuple 元组类型,可以存储多个不同类型的值 std::tuple<int, float, char> t(1, 2.0, 'a');

派生数据类型

数据类型 描述 示例
数组 相同类型元素的集合 int arr[5] = {1, 2, 3, 4, 5};
指针 存储变量内存地址的类型 int* ptr = &x;
引用 变量的别名 int& ref = x;
函数 函数类型,表示函数的签名 int func(int a, int b);
结构体 用户定义的数据类型,可以包含多个不同类型的成员 struct Point { int x; int y; };
用户定义的数据类型,支持封装、继承和多态 class MyClass { ... };
联合体 多个成员共享同一块内存 union Data { int i; float f; };
枚举 用户定义的整数常量集合 enum Color { RED, GREEN, BLUE };

类型别名

别名 描述 示例
typedef 为现有类型定义别名 typedef int MyInt;
using 为现有类型定义别名(C++11 引入) using MyInt = int;

标准库类型

数据类型 描述 示例
std::string 字符串类型 std::string s = "Hello";
std::vector 动态数组 std::vector<int> v = {1, 2, 3};
std::array 固定大小数组(C++11 引入) std::array<int, 3> a = {1, 2, 3};
std::pair 存储两个值的容器 std::pair<int, float> p(1, 2.0);
std::map 键值对容器 std::map<int, std::string> m;
std::set 唯一值集合 std::set<int> s = {1, 2, 3};

类型转换

类型转换是将一个数据类型的值转换为另一种数据类型的值

C++ 中有四种类型转换:静态转换动态转换常量转换重新解释转换

静态转换(Static Cast)

  • 静态转换是将一种数据类型的值强制转换为另一种数据类型的值
  • 静态转换通常用于比较类型相似的对象之间的转换,例如将 int 类型转换为 float 类型
  • 静态转换不进行任何运行时类型检查,因此可能会导致运行时错误
1
int i = 10; float f = static_cast<float>(i); // 静态将int类型转换为float类型

动态转换(Dynamic Cast)

  • 动态转换(dynamic_cast)是 C++ 中用于在继承层次结构中进行向下转换(downcasting)的一种机制
  • 动态转换通常用于将一个基类指针或引用转换为派生类指针或引用
  • 动态转换在运行时进行类型检查。如果转换失败,对于指针类型会返回 nullptr,对于引用类型则会抛出 std::bad_cast 异常
1
dynamic_cast<目标类型>(表达式)
  • 目标类型:必须是指针或引用类型
  • 表达式:需要转换的基类指针或引用

常量转换(Const Cast)

  • 常量转换用于将 const 类型的对象转换为非 const 类型的对象
  • 常量转换只能用于转换掉 const 属性,不能改变对象的类型
1
const int i = 10; int& r = const_cast<int&>(i); // 常量转换,将const int转换为int

重新解释转换(Reinterpret Cast)

  • 重新解释转换是将一个数据类型的值重新解释为另一个数据类型的值,通常用于在不同的数据类型之间进行转换
  • 重新解释转换不进行任何类型检查,因此可能会导致未定义的行为
1
int i = 10; float f = reinterpret_cast<float&>(i); // 重新解释将int类型转换为float类型

静态转换与重新解释转换核心区别

静态转换 (static_cast) 重新解释转换 (reinterpret_cast)
本质 编译器的语义转换(有规律的类型互转) 底层二进制位的直接重新解释(“强行”解释)
安全性 相对安全,编译期会做类型检查,若完全无关会报错 不安全,完全依赖程序员保证正确性,编译器不检查语义
常见用途 基本数据类型转换、有继承关系的指针/引用转换 无关类型指针转换、指针与整数之间的相互转换
是否改变数值 会改变底层数值(如 intfloat 会重新计算存储形式) 不改变二进制位,只是换个视角看待这串内存

变量

  • 带有静态存储持续时间的变量(全局变量和静态变量)会被隐式初始化为 NULL(所有字节的值都是 0)
  • 其他所有变量的初始值是未定义的(不确定的随机值)
1
2
// type variable_list;
int a, b, c;

extern 是一个关键字,用于在多个文件之间共享全局变量或函数。例如:在一个文件 a.cpp中定义了全局变量 int count = 5;,在另一个文件 b.cpp中想用它,不能直接写 int count;(那会变成重复定义),而要写 extern int count; 告诉编译器去别处找

常量

  • 常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量
  • 常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值
  • 常量就像是常规的变量,只不过常量的值在定义后不能进行修改

在 C++ 中,有两种方式定义常量:使用 #define 预处理器、使用 const 关键字

1
2
#define LENGTH 10 
const int LENGTH = 10;

函数

1
2
3
4
5
6
7
8
9
// return_type function_name( parameter list )
// {
//    body of the function
// }

int main()
{
    
}
  • 单返回值:但可以通过结构体、std::tuplestd::vector、引用传参实现多返回值效果
  • C++ 默认使用值传递,函数内的代码不能改变用于调用函数的参数
  • 引用传递和指针传递会改变实际参数

函数声明

函数声明会告诉编译器函数名称及如何调用函数

1
return_type function_name( parameter list );

数组

1
2
// type arrayName [ arraySize ];
int array[10];
  • 默认值和上面变量一样

字符串

C++ 标准库提供了 string

指针

指针是一个变量,其值为另一个变量的内存地址(十六进制数)

1
2
// type* var-name;
int* a;

引用

  • 引用是变量的别名,是某个已存在变量的另一个名字
  • 一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量
  • 引用必须在定义时初始化,并且一旦绑定到一个变量后,就不能再绑定到其他变量
1
2
int a = 10;
int& ref = a;  // ref 是 a 的引用, 对 ref 的操作会直接作用于 a

输入输出

C++ 的 I/O 发生在流中,流是字节序列

I/O 库头文件

头文件 描述
<iostream> 标准输入流 cin、标准输出流 cout、……
<iomanip> 参数化流
<fstream> 文件流

cout

  • coutiostream 类的一个实例
  • cout 对象"连接"到标准输出设备,通常是显示屏
  • cout 是与流插入运算符 << 结合使用的
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <iostream>

using namespace std;

int main( )
{
   char str[] = "Hello C++";

   cout << "Value of str is : " << str << endl;
}
// Value of str is : Hello C++
  • C++ 编译器根据输出变量的数据类型,选择合适的流插入运算符来显示值
  • << 运算符被重载来输出内置类型(整型、浮点型、double 型、字符串和指针)的数据项
  • 流插入运算符 << 在一个语句中可以多次使用
  • endl 用于在行末添加一个换行符

cin

  • ciniostream 类的一个实例
  • cin 对象附属到标准输入设备,通常是键盘
  • cin 是与流提取运算符 >> 结合使用的
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <iostream>
 
using namespace std;
 
int main( )
{
   char name[50];
 
   cout << "请输入您的名称: ";
   cin >> name;
   cout << "您的名称是: " << name << endl;
 
}
// 请输入您的名称: cplusplus
// 您的名称是: cplusplus
  • C++ 编译器根据要输入值的数据类型,选择合适的流提取运算符来提取值,并把它存储在给定的变量中
  • 流提取运算符 >> 在一个语句中可以多次使用

结构体

  • 结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起
  • 与类(class)类似,结构体允许定义成员变量、成员函数、访问权限(默认 public)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// struct type_name {
// 	 member_type1 member_name1;
// 	 member_type2 member_name2;
// 	 member_type3 member_name3;
// 	 .
// 	 .
// } object_names;
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;
  • 最后一个分号之前,可以指定一个或多个结构体变量,这是可选的
  • 访问结构体的成员使用成员访问运算符.
  • 结构体作为函数参数时要写struct关键字
  • struct 和 class 唯一的区别在于默认的访问权限,struct => public、class => private

异常处理

异常是程序在执行期间产生的问题

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
try
{
   // 保护代码
}catch( ExceptionName e1 )
{
   // catch 块
}catch( ExceptionName ... ) // 捕获任何类型异常
{
   // catch 块
}

动态内存

C++ 程序中的内存分为两个部分:

  • :函数内部声明的所有变量都在栈上
  • :程序运行时动态分配

new 运算符可以分配堆内的内存,返回所分配的内存地址

delete 运算符用于删除 new 分配的内存

1
2
int* array = new int[4];
delete [] array; // 删除数组

命名空间

命名空间用于区分不同库中相同名称的函数、类、变量等

  • 调用带有命名空间的函数或变量,需要在前面加上命名空间的名称
  • 使用 using namespace 就可以不用加命名空间的名称,该指令会告诉编译器后续的代码将使用指定的命名空间
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
// 第一个命名空间
namespace first_space{
   void func(){
      cout << "Inside first_space" << endl;
   }
}
// 第二个命名空间
namespace second_space{
   void func(){
      cout << "Inside second_space" << endl;
   }
}
using namespace first_space;
int main ()
{
 
   // 调用第一个命名空间中的函数
   func();
   
   return 0;
}

using 指令也可以用来指定命名空间中的特定项目。例如,只使用 std 命名空间中的 cout 部分

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <iostream>
using std::cout;
 
int main ()
{
 
   cout << "std::endl is used with std!" << std::endl;
   
   return 0;
}

.::

符号 名字 左边是什么 能不能访问实例成员 能不能访问 static 静态
. 点运算符 对象 / 实例 / 引用 ✅实例成员 ✅语法允许,但不推荐
:: 作用域解析 类名、命名空间、全局 ❌不能访问普通实例成员 ✅静态成员、类外函数定义

预处理器

  • 预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理
  • 所有的预处理器指令都是以井号 # 开头
  • 预处理指令不以分号;结尾

#define

#define 预处理指令用于创建符号常量,该符号常量通常称为

1
2
// #define macro-name replacement-text 
#define PI 3.14159

可以使用 #define 来定义一个带有参数的宏

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
using namespace std;

#define MIN(a,b) (a<b ? a : b)

int main ()
{
    int i, j;
    i = 100;
    j = 30;
    cout <<"较小的值为:" << MIN(i, j) << endl;

    return 0;
}

条件编译

条件编译是有选择地对部分程序源代码进行编译

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
#define DEBUG
 
#define MIN(a,b) (a<b ? a : b)
 
int main ()
{
   int i, j;
   i = 100;
   j = 30;
#ifdef DEBUG
   cerr <<"Trace: Inside main function" << endl;
#endif

    return 0;
}

预定义宏

C++ 提供了下表所示的一些预定义宏:

描述
__LINE__ 这会在程序编译时包含当前行号。
__FILE__ 这会在程序编译时包含当前文件名。
__DATE__ 这会包含一个形式为 month/day/year 的字符串,它表示把源文件转换为目标代码的日期。
__TIME__ 这会包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间。

#include

  • #include 指令告诉编译器在编译时将指定的头文件内容插入到当前文件中
  • 头文件通常包含函数声明类定义宏定义等内容

STL

C++ 标准模板库(Standard Template Library,STL)是一套 C++ 模板类和函数的集合,它提供了一系列通用的、可复用的算法和数据结构

<vector>向量⭐

  • vector是最常用的标准模板库(Standard Template Library,STL)容器之一
  • vector本质上是一个可自动扩容的动态数组
 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
59
60
// 一、创建
// 1.使用 vector 前,需要包含头文件
#include <vector>
using namespace std;
// 2.创建 vector
vector<int> vec;
// 3.创建 vector 并指定初始大小
vector<int> vec(5);  // 默认值为 0
// 4.创建 vector 并指定初始大小和初始值
vector<int> vec(5, 10); // [10, 10, 10, 10, 10]
// 5.使用列表创建并初始化 vector
vector<int> vec = {1, 2, 3, 4};

// 二、添加【可能导致扩容=>重新分配内存=>原来的内存地址失效=>扩容前的变量值失败】
// 1.向尾部添加元素
vec.push_back(100);
// 2.向指定位置添加元素
vec.insert(vec.begin(), 100); // 向头部添加元素
// 3.emplace_back直接在vector内部原地构造对象(推荐)
vec.push_back(Person("Tom", 20));
vec.emplace_back("Tom", 20);

// 三、访问
// 1.使用下标访问元素(不检查越界,速度更快)
int x = vec[0];
// 2.使用 at() 访问元素(检查越界,更安全)
int y = vec.at(1);

// 四、长度和容量
// 1.获取长度:返回当前元素数量
vec.size();
// 2.获取容量:返回当前已分配的内存容量
vec.capacity();
// 3.设置容量:避免频繁扩容
vec.reserve(1000000);
// 4.判空:只看有无元素 返回布尔值
vec.empty();

// 五、遍历
// 1.使用下标 [vector::size()返回值原生类型是size_t(无符号)]
for (size_t i = 0; i < vec.size(); i++) { //
    cout << vec[i] << " ";
}
// 2.范围 for 循环
for (int element : vec) {
    cout << element << " ";
}
// 3.使用迭代器
for (auto it = vec.begin(); it != vec.end(); ++it) {
    cout << *it << " ";
}

// 六、删除元素【vector删除中间元素时,后面的元素会整体前移】
// 1.删除第三个元素
vec.erase(vec.begin() + 2);
// 2.清空所有元素(size变为0,capacity可能仍然保留)
vec.clear();
// 3.释放内存
std::vector<int>().swap(vec);
vec.shrink_to_fit();

<list>双向链表⭐

 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
// 一、创建
// 1.使用 vector 前,需要包含头文件
#include <list>
using namespace std;
// 2.创建
list<int> mylist
// 3.创建并指定初始大小
list<int> lst2(5);   // 有默认值
// 4.创建并指定初始大小和初始值
list<int> lst3(5, 10);
// 5.使用列表创建并初始化
list<int> lst4 = {1, 2, 3, 4};

// 二、添加
mylist.push_back(value);
mylist.push_front(value);
mylist.insert(3, value)

// 三、访问
mylist.front();
mylist.back();

// 四、长度
mylist.size();
mylist.empty();

// 五、遍历
for (auto it = mylist.begin(); it != mylist.end(); ++it) {
    cout << *it << " ";
}

// 六、删除元素
mylist.pop_back();
mylist.erase(iterator);
mylist.clear();
mylist.remove(val)
    
// 七、其他
mylist.sort() // 排序
mylist.merge(list& other) // 合并另一个已排序的链表
mylist.reverse()  

<forward_list> 是单向链表

<stack>

函数名称 功能描述
push() 在栈顶添加一个元素
pop() 移除栈顶元素
top() 返回栈顶元素的引用,但不移除它
empty() 检查栈是否为空
size() 返回栈中元素的数量

<deque>双端队列⭐

函数名称 功能描述
deque() 默认构造函数,创建一个空的 deque 容器
deque(size_type n) 创建一个包含 n 个默认值元素的 deque 容器
deque(size_type n, const T& value) 创建一个包含 n 个值为 valuedeque 容器
deque(initializer_list<T> il) 使用初始化列表 il 构造 deque 容器
operator= 赋值操作符,赋值给 deque 容器
assign() 用新值替换 deque 容器中的所有元素
at(size_type pos) 返回 pos 位置的元素,并进行范围检查
operator[](size_type pos) 返回 pos 位置的元素,不进行范围检查
front() 返回第一个元素的引用
back() 返回最后一个元素的引用
begin() 返回指向第一个元素的迭代器
end() 返回指向末尾元素后一位置的迭代器
rbegin() 返回指向最后一个元素的逆向迭代器
rend() 返回指向第一个元素之前位置的逆向迭代器
empty() 检查容器是否为空
size() 返回容器中的元素个数
max_size() 返回容器可容纳的最大元素个数
clear() 清除容器中的所有元素
insert(iterator pos, const T& value) pos 位置插入 value 元素
erase(iterator pos) 移除 pos 位置的元素
push_back(const T& value) 在容器末尾添加 value 元素
pop_back() 移除容器末尾的元素
push_front(const T& value) 在容器前端添加 value 元素
pop_front() 移除容器前端的元素
resize(size_type count) 调整容器大小为 count,多出部分用默认值填充
swap(deque& other) 交换两个 deque 容器的内容
get_allocator() 返回一个用于构造双端队列的分配器对象的副本

<queue> 单向队列

<priority_queue>优先队列⭐

默认是大顶堆,根元素值最大

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <queue>

// 1.声明一个整型优先队列(默认是大顶堆)
priority_queue<int> pq;

// 2.声明一个自定义类型的优先队列,需要提供比较函数
struct compare {
    bool operator()(int a, int b) {
        return a > b; // 这里定义了最小堆
    }
};
priority_queue<int, vector<int>, compare> pq_min;
函数名称 功能描述
push() 向队列添加一个元素
pop() 移除队列顶部的元素
top() 返回队列顶部的元素,但不移除它
empty() 检查栈是否为空
size() 返回队列中的元素数量

<map>字典⭐

key 唯一且有序,按「键 key 的大小升序」,不是插入顺序;底层红黑树

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
map<string, int> myMap;
myMap["apple"] = 10;
cout << myMap["apple"]; // 输出 10
for (auto &p : myMap) { // 遍历
    cout << p.first << " : " << p.second << endl; 
}
// 检查键是否存在
if (myMap.find(key) != myMap.end()) {
    // 键存在
}
myMap.erase(key); // 删除
myMap.clear(); // 清空
myMap.size(); // 大小
myMap.empty();      // 是否为空
myMap.count("Bob"); // key 是否存在(返回 0 或 1)
map<int, string, greater<int>> m;  // 降序

<unordered_map>:key 唯一但无序

1
2
3
unordered_map<string, int> hashTable;
hashTable["apple"] = 10;
cout << hashTable["apple"]; // 输出 10

<set> 集合⭐

元素唯一且有序,按「键 key 的大小排序」,不是插入顺序;底层红黑树

函数名称 功能描述
insert(元素值) 插入一个元素
erase(元素值) 删除一个元素
find(元素值) 查找一个元素
empty() 检查容器是否为空
size() 返回容器中元素的数量

<unordered_set>无序集合:元素唯一但无序,基于哈希表

<bitset>二进制位

 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
bitset<8> bits1;               // 默认初始化:00000000
bitset<8> bits2(42);           // 从整数初始化:00101010
bitset<8> bits3("10101010");   // 从字符串初始化:10101010

bitset<8> bits("00001111");
bits[0] = 1;          // 修改第 0 位:00001111 -> 00001111
bits.set(4);          // 设置第 4 位:00001111 -> 00011111
bits.reset(1);        // 重置第 1 位:00011111 -> 00011101
bits.flip();          // 翻转所有位:00011101 -> 11100010

bitset<8> bits("10101010");
cout << bits.count() << endl;  // 返回 1 的个数       输出 4
cout << bits.size() << endl;   // 返回位数            输出 8
cout << bits.test(3) << endl;  // 检查某一位是否为 1   输出 1 (true)
cout << bits.all() << endl;    // 检查是否所有位都为1  输出 0 (false)

bitset<8> bits("10101010");
unsigned long num = bits.to_ulong();  // bitset 转换为整数:170
std::string str = bits.to_string();   // bitset 转换为字符串:"10101010"

bitset<8> bits1("10101010");
bitset<8> bits2("11110000");

bitset<8> result_and = bits1 & bits2;  // 按位与:10100000
bitset<8> result_or = bits1 | bits2;   // 按位或:11111010
bitset<8> result_xor = bits1 ^ bits2;  // 按位异或:01011010
bitset<8> result_not = ~bits1;         // 按位取反:01010101
  • <bitset> 不支持动态调整大小,如果需要动态位集,可以考虑 vector<bool>

<algorithm>

  • C++ 标准库中的 <algorithm> 头文件提供了一组用于操作容器(如数组、向量、列表等)的算法
  • 这些算法包括排序、搜索、复制、比较等
  • <algorithm> 头文件定义了一组模板函数,这些函数可以应用于任何类型的容器,只要容器支持迭代器
  • 这些算法通常接受两个或更多的迭代器作为参数,表示操作的起始和结束位置
 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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 一、排序
// sort(container.begin(), container.end(), compare_function);
// compare_function 是一个可选的比较函数,用于自定义排序方式
vector<int> numbers = {5, 2, 9, 1, 5, 6};
sort(numbers.begin(), numbers.end());

// partial_sort: 对部分区间排序,前 n 个元素为有序
partial_sort(vec.begin(), vec.begin() + 3, vec.end());
// stable_sort: 稳定排序,保留相等元素的相对顺序
stable_sort(vec.begin(), vec.end());

// 二、搜索
// 在容器中查找与给定值匹配的第一个元素
// 如果找到,it 将指向匹配的元素;如果没有找到,it 将等于 container.end()
// auto it = find(container.begin(), container.end(), value);
vector<int> numbers = {1, 2, 3, 4, 5};
auto it = find(numbers.begin(), numbers.end(), 3);

if (it != numbers.end()) {
    cout << "Found: " << *it << endl; // 3
} else {
    cout << "Value not found." << endl;
}

// binary_search: 对有序区间进行二分查找
sort(vec.begin(), vec.end());  // 先排序
bool found = binary_search(vec.begin(), vec.end(), 4);

// find_if: 查找第一个满足特定条件的元素
auto it = find_if(vec.begin(), vec.end(), [](int x) { return x > 3; });

// 三、复制
// copy(source_begin, source_end, destination_begin);
vector<int> source = {1, 2, 3, 4, 5};
int destination[5];
copy(source.begin(), source.end(), destination);

// 四、比较
// bool result = equal(first1, last1, first2);
// bool result = equal(first1, last1, first2, compare_function);
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {1, 2, 3, 4, 5};
bool are_equal = equal(v1.begin(), v1.end(), v2.begin());

// 五、修改
reverse(vec.begin(), vec.end());
fill(vec.begin(), vec.end(), 0);  // 所有元素设为 0
replace(vec.begin(), vec.end(), 1, 99);  // 将所有 1 替换为 99

// 六、排列
// next_permutation/prev_permutation: 生成字典序的下/上一个排列,如果没有下/上一个排列则返回 false
next_permutation(vec.begin(), vec.end());

// 七、归并
// merge: 将两个有序区间合并到一个有序区间
merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), result.begin());
// inplace_merge: 在单个区间中合并两个有序子区间
inplace_merge(vec.begin(), middle, vec.end());

// 八、集合
// set_union/set_intersection/set_difference: 计算两个有序集合的并/交/差集
vector<int> result(10);
auto it = set_union(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), result.begin());
result.resize(it - result.begin());

// 九、其他
// accumulate(需要 <numeric> 库):计算范围内元素的累计和
#include <numeric>
int sum = accumulate(vec.begin(), vec.end(), 0);
// for_each: 对区间内的每个元素执行操作
for_each(vec.begin(), vec.end(), [](int& x) { x += 1; });
// min_element 和 max_element: 查找区间内的最小值和最大值
auto min_it = min_element(vec.begin(), vec.end());
auto max_it = max_element(vec.begin(), vec.end());

<cmath>

字符(串)

<string>字符串类

<codecvt>字符编码转换

<cctype>字符串处理

<cstring>字符串处理

最后更新于 Aug 19, 2026 23:19 UTC
Built with Hugo
Theme Stack designed by Jimmy