STL(Standard_Template_Library,标准模板库)
里面有 : containers algorithm iterator 其他辅助工具(仿函数/适配器/分配器...)
- 序列式containers
vector
string
deque
list - 关联式containers
map
set
multimap
multiset - 无序containers
unordered_map
unordered_set - 适配器containers
stack
queue
priority_queue - algorithm
全局模板函数,适配所有容器,核心 : 处理通用数据 eg : find() stable_sort() accumulate() max_element() reverse() - iterator
begin() end() - functors
cpp
//自定义仿函数
class Cmp{
public://public必须写,因为class默认是private权限
bool operator()(int a,int b){
return abs(a)<abs(b);
}
}
vector<int>arr{232,20,-23,-99,-457};
sort(arr.begin(),arr.end(),Cmp() );
- ...
C++标准
由国际标准化组织发布的,所有C++编译器/工具都要遵循的官方规则手册
eg : C++11 C++17 C++20
using namespace std;
使用std命名空间,后续代码中使用std里的名字时,都无需加std::前缀
- cout = std::cout
- endl = std::endl
- string = std::string
- vector = std::vector
所有 C++ 标准库的容器、函数、对象(如 vector、sort、cin)都在std命名空间中
C++标准库
C++标准库是由C++官方指定的,所有符合标准的编译器必须实现的核心功能合集 ,是C++的官方工具箱------你不用自己写基础功能(eg 容器,算法,输入输出...),直接用标准库的现成代码即可
注意 : 所有的标准库功能都封装在std命名空间中
(非标准库是厂商自己加的,或第三方写的工具库,竞赛中几乎禁用)
MinGW(Minimalist GNU for Windows)
是适配Windows系统的一套免费开源工具集,核心包含 :
- 编译器 :
根据你使用的C++标准(eg : C++11)解析代码 C++代码---->.exe程序 - 调试器 :
调试代码,打断点,看变量值,单步执行 - 标准库 :
预先实现好的函数/类(二进制库文件+头文件),你使用时只是调用 ,不能修改,编译器会根据你指定的-std=c++11参数,自动启动/禁用对应版本的特性
(注意 :
MinGW不包含C++标准库源码,而是内置标准库二进制实现文件,编译器编译时自动链接) - 链接器
include< iostream >
cpp
string s;
cin>>s;//标准输入流
cout<<"li xiang";//标准输出流
cerr<<"error info" ;//标准错误流
clog<<"log info" ;//标准日志流
getline(cin,s);//读取整行
cin.ignore();//忽略cin残留的换行符
// 关闭cin与stdio的同步(核心提速)
ios::sync_with_stdio(false);
// 解除cin与cout的绑定(进一步提速)cin.tie(nullptr);
include< vector >
cpp
vector<int>arr{12,243,3,5,45,4,5,4,89};
arr.push_back(1);//尾部插入
arr.pop_back();//尾部删除
arr.size();//元素个数
arr.resize();//重新调整大小
arr.empty();//判断为空
arr.reserve();//预留空间
arr.resize(n);//调整大小,不足补默认值
arr.clear();//清空容器
arr.begin(); arr.end();//迭代器
arr[i];//随机访问
arr.at(i);//随机访问
arr.insert(arr.begin()+index,val);//插入
arr.erase(arr.begin()+index);//删除
arr.erase(arr.begin()+i,arr.begin()+j );//删除区间
find(arr.begin(),arr.end(),val);//全局find函数查找值val,返回迭代器
include< string >
cpp
string s="li xiang";
//s[i]
cout<<s[i]<<endl;
//s.at(i)
cout<<s.at(i)<<endl;
//s.size()
cout<<s.size()<<endl;
//s.length()
cout<<s.length()<<endl;
//s.clear()
s.clear();
//s1.swap(s2)
s1.swap(s2);
//s.empty()
if(s.empty()){cout<<"s is empty!"<<endl;
//s.push_back(c)
char c;
s.push_back(c);
//s.insert(pos,str)
s.insert(1,"li");
s.insert(pos,n,c);
//s.find()
s.find("li")==string::npos
//
include< map >
cpp
map<string,int>mp;
mp["li xiang"]=1;//赋值
mp.find("li xiang");//查找键,返回迭代器
mp.erase("li xiang");//删除键
mp.count("li xiang");//统计键的数量
mp.size();//大小
mp.empty();//判空
//迭代mp
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
或者
for(auto &it:mp){
cout<<it.first<<" "<<it.second<<endl;
}
include< unordered_map >
include< set >
cpp
set<int>st;
st.insert(13);//插入元素
st.find(23);//查找元素
st.erase(11);//删除元素
st.count(23);//统计个数0/1
st.lower_bound(2);//第一个>=的元素迭代器
st.upper_bound(2);//第一个>的元素迭代器
include< utility >
竞赛中无需写#include
因为vector map algorithm 都已经隐式包含
cpp
pair<int,string>p1={666,"li xiang"};
pair<int,string>p2=make_pair(888,"acmer");
cout<<p1.first<<" "<<p1.second<<endl;
include< unordered_set >
include< sstream >
include< algorithm >
cpp
//sort()排序
sort(arr.begin(),arr.end() );//从小到大排序
sort(arr.begin(),arr.end(),greater<int>() );//从大到小排序
sort(arr.begin(),arr.end(),cmp);//自定义排序
sort(arr.begin(),arr.end(),[](int n1,int n2){ return abs(n1) > abs(n2);
});//lambda自定义
stable_sort(arr.begin(),arr.end(),cmp );//稳定排序,相等元素保持原顺序
accumulate(arr.begin(),arr.end() );//返回 区间和
upper_bound(arr.begin(),arr.end(),val );//返回迭代器 上界查找
upper_bound(arr.begin(),arr.end(),cmp );//比较规则需要与排序规则一致
lower_bound(arr.begin(),arr.end(),val );//返回迭代器 下界查找
lower_bound(arr.begin(),arr.end(),cmp );//比较规则需要与排序规则一致
// [ )
//下界是指第一个>=val的迭代器,上界是指第一个>val的迭代器
find(arr.begin(),arr.end(),val);//返回迭代器
max(n1,n2);//同类型任意值
min(n1,n2);//同类型任意值
swap(n1,n2);//同类型任意值
max_element(arr.begin(),arr.end() );//返回迭代器
min_element(arr.begin(),arr.end() );//返回迭代器
//如果要最大/小值,要*min/max_element(arr.begin(),arr.end() );
count(arr.begin(),arr.end(),val);//返回出现次数
reverse(arr.begin(),arr.end() );//反转容器
fill(arr.begin(),arr.end(),0 );//区间重新填充
include< iomanip >
(input/output manipulators,输入输出操作符)
是C++标准库中输入输出格式控制的核心头文件
cpp
cout<<setprecision(2)<< ;//控制有效数字
cout<<fixed<<setprecision(2)<< ;//控制小数点后有效数字
cout<<setw(2)<<setfill('0')<< ;//设置宽度,不足用字符填充
cout<<dec<<100 ;//输出10进制
cout<<<hex<<232 ;//输出16进制
cout<<oct<<234 ;//输出8进制
cout<<uppercase<<2323 ;//16进制输出大写字母
cout<<nouppercase<<232 ;//16进制输出小写字母
cout<<left<< ;//左对齐
cout<<right<< ;//右对齐(默认)
cout<<boolalpha<<1 ;//恢复bool输出true/false
cout<<setbase(8)<<2323 ;//设置进制
( 注意 : setw(2)是只对下一个生效 )
10进制,decimal
16进制,hexadecimal
8进制,octal
include< stack >
cpp
stack<int>st;//空栈
st.push(110);//入栈
st.pop();//出栈
st.top();//访问栈顶元素
st.empty();//判空
st.size();//大小
include< queue >
cpp
queue<int>que;//空队列
que.push(12);//入队
que.pop();//出队(删除队首)
que.front();//访问队首
que.back();//访问队尾
include< priority_queue >
cpp
priority_queue<int>pq;//空优先队列,默认大顶堆,队首最大
pq.push(23);//入队(堆排序)
pq.pop();//出队(删除堆顶)
pq.top();//访问堆顶
priority_queue<int,vector<int>,greater<int>>pq;//小顶堆构造
include< cmath >
cpp
//基本算数函数
abs(int x);//返回int
fabs(double x);//返回double
//三角函数
sin(double x);//返回double
cos(double x);//返回double
tan(double x);//返回double
asin(double x);//返回double
acos(double x);//返回double
atan(double x);//返回double
//幂函数
pow(double x,double y);//返回double
sqrt(double x);//返回double (sqrt root)
cbrt(double x);//返回double (cube root)
//指数 对数
exp(double x);//返回double
log(double x);//返回double
log10(double x);//返回double
log2(double x);//返回double
//取整函数
floor(double x);//返回double 向下取整
ceil(double x);//返回double 向上取整
round(double x);//返回double 四舍五入
trunc(double x);//返回double 截断小数
//比较
fmax(double x,double y);//返回double
fmin(double x,double y);//返回double
//距离 (hypotenuse,斜边/弦)
hypot(double x,double y);//返回double
hypot(double x,double y,double z);//返回double
include< cctype >
cpp
bool isalpha(char c);// A-Z/a-z
bool isdigit(char c);// 0-9
bool isalnum(char c);// 0-9/A-Z/a-z
bool isupper(char c);// A-Z
bool islower(char c);// a-z
char toupper(char c);
char tolower(char c);
include< climits >
C语言风格的宏
cpp
const int int_max=INT_MAX;
const int int_min=INT_MIN;
const long long ll_min=LLONG_MIN;
const long long ll_max=LLONG_MAX;
include< limits >
cpp
// numeric_limits 是 C++ 标准库 <limits> 头文件中的模板类(不是容器)
// 核心作用是查询数值类型的极限属性
// (如 int 的最大值、double 的精度等)
// 和 vector/map 等 "存储数据的容器" 完全无关
int int_max=numeric_limits<int>::max();
int int_min=numeric_limits<int>::min();
long long ll_max=numeric_limits<long long>::max();
long long ll_min=numeric_limits<long long>::min();
对map自定义排序
cpp
map<int,int>mp;
mp[12]=23;
mp[53]=1324;
mp[2]=13;
vector<pair<int,int>>arr(mp.begin(),mp.end() );
bool cmp(pair<int,int>&s1,pair<int,int>&s2){
return s1.second>s2.second;}
sort(arr.begin(),arr.end(),cmp);
PTA
PTA乙级
1024
1045
1055
1059
PTA团体程序设计天梯赛
L1-104
C++插件
C++插件贯穿编辑--->编译--->调试全过程
C++编译器
C++编译器有多种
- g++
配置简单,跨平台(Windows/Linux/MacOS) - Clang
是苹果的默认C++编译器 - MSVC(VS编译器)
编译器的标准 -std=C++17 或 -std=C++11 或者其他标准
编译器作用 : 根据选定的C++标准,C++代码--->二进制.exe程序
C++调试器
调试器仅仅在调试模式时使用,直接运行代码时完全不用
| 运行方式 | 是否使用调试器 | 核心目的 | 适用场景 |
|---|---|---|---|
| 调试模式(F5) | 是 | 带代码错误,看变量,断点,逐行执行 | 代码有bug,需要定位 |
| 直接运行 | 否 | 快速看代码运行结果 | 代码无错,验证功能是否正常 |
调试器的核心价值 : 不是"自动找语法错误"(语法错误由编译器和插件实时检查),而是找逻辑错误-------比如 : 代码能运行,但是结果不对,调试器能让你"一步一步看代码执行过程",找到哪里错了
调试器的配置文件launch.json
launch.json是调试模式的配置文件
它仅仅控制调试时的行为,不影响直接运行
bash
launch.json--->调试器的操作手册
E:\CppCode ← 这个文件夹放配置文件
├─ .vscode ← 隐藏文件夹,里面有配置文件 : launch.json/tasks.json
├─ test1.cpp
├─ test2.cpp
└─ acm/ ← 子文件夹
└─ acm1.cpp
(每一个配置文件管理所有与它同级的文件和文件夹)
.vscode里的核心文件:
- launch.json:调试器的 "操作手册";
- tasks.json:编译任务的 "规则"(用来自定义编译命令,比如固定加-std=c++17 -g)
在终端Shell运行C++文件
- 在记事本中编辑C++代码,保存为.cpp后缀
- 下载MinGW(Mininalist GNU for Windows,里面有g++编译器,gdb调试器,其他辅助工具)
- 把/bin目录添加到PATH环境变量中(为了能够使用g++/gdb命令)
- 使用命令 g++ --version 验证是否成功加入PATH中
成功显示MinGW版本
失败显示g++不是内部/外部命令 - 在终端 编译
bash
## 先切换到代码保存的路径
g++ test01.cpp -o test01.exe # 生成test01.exe可执行文件
## 无报错--->编译成功
## 有报错--->代码语法错误,重新编辑代码,并保存
- 在终端 运行
bash
./test01.exe # 直接运行文件
- 额外步骤 : gdb(GNU Debugger)调试文件
核心 : 控制程序的运行节奏---->逐行跑,断电停
bash
g++ test01.cpp -o test01.exe -g ## 编译后文件较大,但是能够调试
gdb test01.exe ## 启动gdb并加载要调试的程序
## 输入调试命令(下面说)
quit ## 退出gdb,简写为q
详细说gdb调试命令
下一章详细讲讲
bash
break 行号/函数名
run
next
step
print 变量名
continue
delete
list
quit
VSCode introduce
VSCode本质上是一个 : "空架子"编辑器
你写的C++代码是文字,要想编程能跑的代码,需要 :
- C++插件 :
语法高亮,代码补全,语法实时检查... - 编译器(eg : g++) :
把"文字代码"翻译为电脑能懂的二进制程序-->.exe文件 - 调试器(eg : gbd) :
帮你找代码中的错误 - 配置文件(eg : launch.json/task.json) :
告诉VSCode用哪个编译器,怎么编译,怎么运行,要不要弹CMD窗口...
run C++code in VSCode
使用教程
- 1.下载VSCode
- 2.下载MinGW(Minimalist GNU for Windows,Windows版的GNU组件)
包含C++编译器,C++调试器,其他辅助工具 - 3.设置环境变量
在Path环境变量中设置 MinGW/bin目录的位置值 - 4.下载VSCode的C++插件
在VSCode插件商店中下载**C++**插件 - 生成配置文件
每个文件夹的.vscode是独立的,里面的launch.json(调试配置)和tasks.json(编译配置)只对当前文件夹生效,不同文件夹的配置互不影响
bash
g++ test.cpp -o test.exe -g -std=c++17
## 编译调试 使用C++17标准语法规则编译