在信息学奥赛(NOIP、CSP 等)中,C++ 是主流编程语言,相比 C 语言,它增加了面向对象特性、标准模板库(STL)、引用、函数重载等功能,这些特性能极大简化代码、提高效率,是解决复杂算法问题的核心工具。
以下是信奥赛中高频使用的 C++ 语法知识点,结合实例详细讲解:
一、C++ 基础(与 C 的兼容性与扩展)
C++ 兼容几乎所有 C 语言语法,但增加了更便捷的特性,是入门的基础。
1. 命名空间(namespace)
作用:解决同名标识符的冲突(如不同库中的函数名重复),信奥中主要用于std命名空间(STL 的所有内容都在std中)。
用法:
- using namespace std;:直接使用std中的内容(如cout、vector),无需加std::前缀(信奥中常用,简化代码)。
- 局部使用:std::cout(避免全局命名空间污染,大型项目常用)。
示例:
#include <iostream>
using namespace std; // 引入std命名空间
int main() {
cout << "Hello, OI!" << endl; // 直接使用cout(属于std)
return 0;
}
2. 输入输出流(iostream)
作用:替代 C 语言的scanf/printf,语法更简洁,无需记忆格式控制符(如%d/%s),但注意:大数据输入时效率略低,需用ios::sync_with_stdio(false);提速。
操作 | C++(iostream) | C(stdio) |
输出 | cout << 变量/常量 | printf("格式", 变量) |
输入 | cin >> 变量 | scanf("格式", &变量) |
换行 | endl(刷新缓冲区)或\n | \n |
示例:
#include <iostream>
using namespace std;
int main() {
int a;
double b;
cin >> a >> b; // 输入整数和小数,自动识别类型
cout << "a=" << a << ", b=" << b << endl; // 输出,自动拼接
return 0;
}
// 输入:3 3.14
// 输出:a=3, b=3.14
提速技巧:在main函数开头加一行,让cin/cout效率接近scanf/printf:
ios::sync_with_stdio(false);
cin.tie(0); // 解除cin与cout的绑定,进一步提速
3. 引用(&)
作用:给变量起 “别名”,作为函数参数时可直接修改原变量(替代 C 语言的指针,更安全、简洁)。
语法:类型 &引用名 = 原变量;(引用必须初始化,且一旦绑定不可更改)。
信奥应用场景:
- 函数参数传递(避免大型变量的拷贝,如数组、结构体);
- 函数返回引用(用于链式操作,如a = b = c)。
示例:用引用交换两个数(比指针更直观)
#include <iostream>
using namespace std;
// 引用作为参数:直接修改原变量
void swap(int &x, int &y) { // x是a的别名,y是b的别名
int temp = x;
x = y;
y = temp;
}
int main() {
int a = 3, b = 5;
swap(a, b); // 直接传变量,无需取地址
cout << a << " " << b << endl; // 输出:5 3
return 0;
}
二、函数增强(C++ 独有的函数特性)
C++ 对函数的扩展(重载、默认参数)能让代码更灵活,在处理多类型问题时非常实用。
1. 函数重载(Overload)
作用:允许同一作用域内定义多个函数名相同、参数列表不同(参数类型 / 个数 / 顺序不同)的函数,编译器会根据实参自动匹配。
信奥应用场景:实现同一功能的不同参数版本(如求和函数,可处理int、double、数组等)。
示例:重载求和函数
#include <iostream>
using namespace std;
// 1. 求两个int的和
int add(int a, int b) {
return a + b;
}
// 2. 求两个double的和(参数类型不同,构成重载)
double add(double a, double b) {
return a + b;
}
// 3. 求三个int的和(参数个数不同,构成重载)
int add(int a, int b, int c) {
return a + b + c;
}
int main() {
cout << add(2, 3) << endl; // 调用int版本,输出5
cout << add(2.5, 3.5) << endl; // 调用double版本,输出6
cout << add(1, 2, 3) << endl; // 调用三个int版本,输出6
return 0;
}
2. 函数默认参数
作用:定义函数时给参数指定默认值,调用时可省略该参数(简化调用,尤其参数较多时)。
规则:默认参数必须从右向左定义(即若某个参数有默认值,其右侧所有参数必须也有默认值)。
示例:计算长方形面积(默认宽为 2)
#include <iostream>
using namespace std;
// 宽的默认值为2(默认参数在右侧)
int area(int length, int width = 2) {
return length * width;
}
int main() {
cout << area(3) << endl; // 省略width,用默认值2,输出3*2=6
cout << area(3, 4) << endl; // 显式传参,输出3*4=12
return 0;
}
三、面向对象基础(类与结构体)
C++ 的类(class)和结构体(struct)用于封装数据和操作,在信奥中常用于定义复杂数据类型(如学生、点、边等),配合 STL 使用更高效。
1. 结构体(struct)
作用:C 语言也有结构体,但 C++ 的结构体可包含函数(方法),更灵活。信奥中常用结构体存储 “多字段数据”(如坐标、学生信息)。
示例:定义 “点” 结构体,计算两点距离
#include <iostream>
#include <cmath> // 用于sqrt
using namespace std;
// 定义点结构体:包含x、y坐标,及计算距离的方法
struct Point {
int x, y; // 成员变量
// 成员函数:计算与另一个点的距离
double distance(const Point &other) { // 用const引用避免拷贝
int dx = x - other.x;
int dy = y - other.y;
return sqrt(dx*dx + dy*dy); // 勾股定理
}
};
int main() {
Point p1 = {1, 2}; // 初始化点1
Point p2 = {4, 6}; // 初始化点2
cout << "两点距离:" << p1.distance(p2) << endl; // 输出5.0
return 0;
}
2. 类(class)与访问控制
作用:与struct类似,但默认成员为private(私有,仅类内可访问),需用public声明外部可访问的成员(更安全)。信奥中常用于封装复杂逻辑(如自定义栈、队列)。
示例:用类实现一个简单的栈
#include <iostream>
using namespace std;
class Stack {
private:
int data[100]; // 栈数据(私有,外部不可直接访问)
int top; // 栈顶指针(私有)
public:
// 构造函数:初始化栈
Stack() {
top = -1; // 栈空时top为-1
}
// 入栈
void push(int x) {
if (top < 99) { // 避免溢出
data[++top] = x;
}
}
// 出栈
int pop() {
if (top >= 0) { // 栈非空
return data[top--];
}
return -1; // 栈空时返回-1(简单处理)
}
// 判断栈是否为空
bool isEmpty() {
return top == -1;
}
};
int main() {
Stack s;
s.push(1);
s.push(2);
while (!s.isEmpty()) {
cout << s.pop() << " "; // 输出:2 1(栈是后进先出)
}
return 0;
}
四、标准模板库(STL)—— 信奥核心工具
STL 是 C++ 的 “武器库”,包含容器(存储数据)、算法(处理数据)、迭代器(遍历容器),能极大简化代码(如用vector替代数组,sort替代手动排序),是信奥必备。
1. 容器(Containers)
容器是存储数据的 “容器”,信奥中常用以下几类:
(1)动态数组vector
作用:替代 C 语言的静态数组,大小可动态扩展(无需预先指定长度),支持随机访问(效率高)。
常用操作:
- push_back(x):在末尾添加元素;
- pop_back():删除末尾元素;
- size():返回元素个数;
- []:访问第 i 个元素(如v[0]);
- clear():清空容器。
信奥应用场景:处理不确定长度的序列(如读入 n 个数,存储学生成绩)。
示例:用vector存储并排序成绩
#include <iostream>
#include <vector> // 引入vector
#include <algorithm> // 引入sort算法
using namespace std;
int main() {
vector<int> scores; // 定义一个存储int的vector(初始为空)
int n, x;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> x;
scores.push_back(x); // 动态添加元素
}
sort(scores.begin(), scores.end()); // 排序(从小到大)
// 遍历输出(用size()获取长度)
for (int i = 0; i < scores.size(); i++) {
cout << scores[i] << " ";
}
return 0;
}
// 输入:5 3 1 4 2 5
// 输出:1 2 3 4 5
(2)字符串string
作用:替代 C 语言的char数组,自动管理内存(避免越界),支持直接拼接、比较等操作。
常用操作:
- length()/size():返回长度;
- +/append():拼接字符串;
- substr(pos, len):截取子串(从 pos 开始,长度为 len);
- c_str():转换为 C 风格字符串(用于需要const char*的场景)。
信奥应用场景:字符串处理(如反转、查找子串、拼接)。
示例:字符串拼接与反转
#include <iostream>
#include <string> // 引入string
#include <algorithm> // 引入reverse算法
using namespace std;
int main() {
string s1 = "Hello";
string s2 = " OI!";
string s3 = s1 + s2; // 直接拼接,s3 = "Hello OI!"
reverse(s3.begin(), s3.end()); // 反转字符串,s3 = "!IO olleH"
cout << s3 << endl; // 输出:!IO olleH
cout << "长度:" << s3.size() << endl; // 输出:9
return 0;
}
(3)映射map
作用:存储 “键 - 值对”(如字典:key→value),自动按键排序(默认升序),支持快速查找(时间复杂度 O (logn))。
常用操作:
- insert({key, value}):插入键值对;
- []:访问或修改 value(如m["a"] = 1);
- find(key):查找键,返回迭代器(未找到则为m.end());
- count(key):判断键是否存在(返回 1 或 0)。
信奥应用场景:统计元素出现次数(如词频统计)、映射关系(如学号→姓名)。
示例:统计数字出现次数
#include <iostream>
#include <map> // 引入map
using namespace std;
int main() {
map<int, int> cnt; // key:数字,value:出现次数
int nums[] = {1, 2, 2, 3, 3, 3};
for (int x : nums) { // 范围for循环(C++11,遍历数组)
cnt[x]++; // 键x的计数+1(若不存在则自动初始化为0)
}
// 遍历map(自动按key升序)
for (auto &p : cnt) { // auto自动推断类型为pair<int, int>
cout << p.first << "出现了" << p.second << "次" << endl;
}
return 0;
}
// 输出:
// 1出现了1次
// 2出现了2次
// 3出现了3次
(4)其他常用容器
- queue:队列(先进先出),用于 BFS(广度优先搜索);
- stack:栈(后进先出),用于 DFS(深度优先搜索)、表达式求值;
- set:集合(存储不重复元素,自动排序),用于去重和快速查找;
- priority_queue:优先队列(默认大根堆),用于贪心算法、堆排序。
2. 算法(Algorithms)
STL 提供了大量现成算法,直接调用即可,无需重复编写,信奥中最常用的是排序和查找。
(1)排序sort
作用:对容器或数组进行排序,默认升序,可自定义排序规则(通过比较函数)。
语法:sort(起始迭代器, 结束迭代器, 比较函数)(结束迭代器是 “最后一个元素的下一个位置”)。
示例:降序排序与自定义排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 自定义比较函数:降序(a > b时a排在前)
bool cmp(int a, int b) {
return a > b;
}
// 对结构体排序:按x升序,x相同则按y降序
struct Point {
int x, y;
};
bool cmpPoint(Point a, Point b) {
if (a.x != b.x) return a.x < b.x; // x升序
return a.y > b.y; // x相同则y降序
}
int main() {
// 1. 降序排序数组
int arr[] = {3, 1, 4, 2};
sort(arr, arr + 4, cmp); // 传入比较函数cmp
for (int x : arr) cout << x << " "; // 输出:4 3 2 1
// 2. 排序结构体数组
Point ps[] = {{2, 5}, {1, 3}, {2, 4}};
sort(ps, ps + 3, cmpPoint);
for (auto &p : ps) {
cout << "(" << p.x << "," << p.y << ") "; // 输出:(1,3) (2,5) (2,4)
}
return 0;
}
(2)查找find与binary_search
- find:线性查找(遍历容器),返回找到的元素迭代器;
- binary_search:二分查找(仅对有序序列有效),返回bool表示是否存在。
示例:二分查找有序数组
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {1, 3, 5, 7, 9}; // 有序数组
int target = 5;
// 二分查找:返回是否存在
bool exists = binary_search(v.begin(), v.end(), target);
cout << (exists ? "存在" : "不存在") << endl; // 输出:存在
// 查找位置(配合lower_bound)
auto it = lower_bound(v.begin(), v.end(), target); // 返回第一个>=target的迭代器
int pos = it - v.begin(); // 计算下标
cout << "位置:" << pos << endl; // 输出:2
return 0;
}
五、其他重要特性
1. 范围 for 循环(C++11)
作用:简化容器 / 数组的遍历,无需手动控制下标或迭代器。
语法:for (元素类型 变量 : 容器/数组) { ... }
示例:遍历vector和string
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<int> v = {1, 2, 3};
for (int x : v) { // 遍历vector
cout << x << " "; // 输出:1 2 3
}
string s = "abc";
for (char c : s) { // 遍历string
cout << c << " "; // 输出:a b c
}
return 0;
}
2. 模板(Templates)
作用:定义 “通用函数 / 类”,支持多种数据类型(如一个求和函数同时支持int、double),STL 的容器和算法都是基于模板实现的。
示例:通用求和函数
#include <iostream>
using namespace std;
// 模板函数:支持任意类型的两个数求和
template <typename T> // T是类型参数(可替换为int、double等)
T add(T a, T b) {
return a + b;
}
int main() {
cout << add(2, 3) << endl; // T=int,输出5
cout << add(2.5, 3.5) << endl; // T=double,输出6
return 0;
}
总结:信奥赛 C++ 核心知识点
类别 | 核心内容 | 信奥应用场景 |
基础扩展 | 命名空间、输入输出流、引用 | 简化代码,替代 C 的指针和scanf/printf |
函数增强 | 函数重载、默认参数 | 处理多类型 / 多参数场景 |
面向对象 | 结构体、类 | 定义复杂数据类型(如点、学生) |
STL 容器 | vector、string、map、queue、stack | 动态存储数据,替代手动实现的数据结构 |
STL 算法 | sort、find、binary_search | 排序、查找,节省代码量 |
语法糖 | 范围 for 循环、模板 | 简化遍历和通用逻辑实现 |
掌握这些知识点后,能显著提高信奥赛中的编程效率 —— 例如,用vector处理动态数组避免越界,用sort快速实现排序,用map统计频率,这些都是解决信奥题的 “利器”。建议结合真题练习,熟练运用 STL 和 C++ 特性,为复杂算法(如图论、动态规划)打下基础。