- admin 的博客
C++语言基础
- @ 2025-11-11 10:24:52
C++ 快速入门指南
本文针对初学者,介绍 C++ 的基本使用,包括控制语句、标准库的常用数据结构等,以便快速上手编程和算法练习。
目录
标准输出
C++ 的标准输出是 cout,用 << 运算符把需要打印的内容传递给 cout,endl 是换行符。
#include <iostream>
using namespace std;
int main() {
int a = 10;
// 输出:10
cout << a << endl;
// 可以串联输出
// 输出:Hello, World!
cout << "Hello" << ", " << "World!" << endl;
string s = "abc";
// 输出:abc 10
cout << s << " " << a << endl;
return 0;
}
C 语言的 printf 函数也可以用,但 cout 更加方便,推荐使用。
控制语句
条件判断
int a = 10;
if (a > 5) {
cout << "a > 5" << endl;
} else if (a == 5) {
cout << "a == 5" << endl;
} else {
cout << "a < 5" << endl;
}
// 输出:a > 5
循环
for 循环一般用于已知循环次数的情况,while 循环一般用于未知循环次数的情况。
// 0 1 2 3 4
for (int i = 0; i < 5; i++) {
cout << i << " ";
}
int num = 100;
// 100 50 25 12 6 3 1
while (num > 0) {
cout << num << " ";
num /= 2;
}
基本数据结构
动态数组 vector
vector 是 C++ 标准库的动态数组,比 C 语言的静态数组更加方便和安全。
初始化方法
#include <vector>
int n = 7, m = 8;
// 初始化一个 int 型的空数组
vector<int> nums;
// 初始化一个大小为 n 的数组,默认值为 0
vector<int> nums(n);
// 初始化包含指定元素的数组
vector<int> nums{1, 3, 5};
// 初始化大小为 n 且值都为 2 的数组
vector<int> nums(n, 2);
// 初始化二维数组
vector<vector<int>> dp;
// 初始化大小为 m * n 的布尔数组,初始值为 true
vector<vector<bool>> dp(m, vector<bool>(n, true));
常用操作
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n = 10;
vector<int> nums(n);
// 检查是否为空
cout << nums.empty() << endl; // 0 (false)
// 获取大小
cout << nums.size() << endl; // 10
// 尾部插入元素
nums.push_back(20);
cout << nums.size() << endl; // 11
// 获取最后一个元素
cout << nums.back() << endl; // 20
// 删除最后一个元素
nums.pop_back();
cout << nums.size() << endl; // 10
// 通过索引访问和修改
nums[0] = 11;
cout << nums[0] << endl; // 11
// 在指定位置插入元素
nums.insert(nums.begin() + 3, 99);
// 删除指定位置元素
nums.erase(nums.begin() + 2);
// 交换元素
swap(nums[0], nums[1]);
// 遍历数组
for (int i = 0; i < nums.size(); i++) {
cout << nums[i] << " ";
}
cout << endl;
return 0;
}
双链表 list
list 是 C++ 标准库中的双向链表容器。
初始化方法
#include <list>
int n = 7;
// 初始化空链表
std::list<int> lst;
// 初始化大小为 n 的链表,默认值为 0
std::list<int> lst(n);
// 初始化包含指定元素的链表
std::list<int> lst{1, 3, 5};
// 初始化大小为 n 且值都为 2 的链表
std::list<int> lst(n, 2);
常用操作
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> lst{1, 2, 3, 4, 5};
// 检查是否为空
cout << lst.empty() << endl; // false
// 获取大小
cout << lst.size() << endl; // 5
// 头部插入
lst.push_front(0);
// 尾部插入
lst.push_back(6);
// 获取头尾元素
cout << lst.front() << " " << lst.back() << endl; // 0 6
// 删除头尾元素
lst.pop_front();
lst.pop_back();
// 在指定位置插入
auto it = lst.begin();
advance(it, 2); // 移动到第三个位置
lst.insert(it, 99); // 插入元素
// 删除指定位置元素
it = lst.begin();
advance(it, 1); // 移动到第二个位置
lst.erase(it); // 删除元素
// 遍历链表
for (int val : lst) {
cout << val << " ";
}
cout << endl;
return 0;
}
队列 queue
queue 基于先进先出(FIFO)原则,适用于从队尾添加、队头移除元素的场景。
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q;
// 添加元素
q.push(10);
q.push(20);
q.push(30);
// 检查是否为空
cout << q.empty() << endl; // false
// 获取大小
cout << q.size() << endl; // 3
// 获取队头和队尾元素
cout << q.front() << " " << q.back() << endl; // 10 30
// 删除队头元素
q.pop();
cout << q.front() << endl; // 20
return 0;
}
栈 stack
栈基于后进先出(LIFO)原则,适用于在栈顶添加或移除元素的场景。
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
// 向栈顶添加元素
s.push(10);
s.push(20);
s.push(30);
// 检查是否为空
cout << s.empty() << endl; // false
// 获取大小
cout << s.size() << endl; // 3
// 获取栈顶元素
cout << s.top() << endl; // 30
// 删除栈顶元素
s.pop();
cout << s.top() << endl; // 20
return 0;
}
哈希表 unordered_map
unordered_map 提供基于键值对的存储,支持常数时间复杂度的查找、插入和删除操作。
初始化方法
#include <unordered_map>
using namespace std;
// 初始化空哈希表
unordered_map<int, string> hashmap;
// 初始化包含键值对的哈希表
unordered_map<int, string> hashmap{{1, "one"}, {2, "two"}, {3, "three"}};
常用操作
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
unordered_map<int, string> hashmap{{1, "one"}, {2, "two"}, {3, "three"}};
// 检查是否为空
cout << hashmap.empty() << endl; // 0 (false)
// 获取大小
cout << hashmap.size() << endl; // 3
// 查找键是否存在(C++20)
if (hashmap.contains(2)) {
cout << "Key 2 -> " << hashmap[2] << endl; // Key 2 -> two
}
// 访问不存在的键会自动创建(重要!)
cout << hashmap[4] << endl; // 空字符串,同时创建了键4
// 插入键值对
hashmap[4] = "four";
// 删除键值对
hashmap.erase(3);
// 遍历哈希表
for (const auto &pair : hashmap) {
cout << pair.first << " -> " << pair.second << endl;
}
return 0;
}
重要提醒:访问不存在的键会自动创建该键,这可能导致意外的行为。
哈希集合 unordered_set
unordered_set 用于存储不重复的元素,常用于元素去重。
初始化方法
#include <unordered_set>
using namespace std;
// 初始化空集合
unordered_set<int> uset;
// 初始化包含元素的集合
unordered_set<int> uset{1, 2, 3, 4};
常用操作
#include <iostream>
#include <unordered_set>
using namespace std;
int main() {
unordered_set<int> hashset{1, 2, 3, 4};
// 检查是否为空
cout << hashset.empty() << endl; // 0 (false)
// 获取大小
cout << hashset.size() << endl; // 4
// 查找元素是否存在
if (hashset.contains(3)) {
cout << "Element 3 found." << endl;
}
// 插入元素
hashset.insert(5);
// 删除元素
hashset.erase(2);
// 遍历集合
for (const auto &element : hashset) {
cout << element << endl;
}
return 0;
}
函数参数传递
传值
传值将参数的副本传递给函数,函数内的修改不会影响原始数据。
#include <iostream>
using namespace std;
void modifyValue(int x) {
x = 10; // 只修改副本
}
int main() {
int num = 5;
modifyValue(num);
cout << "After modifyValue, num = " << num << endl; // 5
return 0;
}
传引用
传引用将参数的地址传递给函数,函数可以直接操作原始数据。
#include <iostream>
using namespace std;
void modifyReference(int &x) {
x = 10; // 修改原始数据
}
int main() {
int num = 5;
modifyReference(num);
cout << "After modifyReference, num = " << num << endl; // 10
return 0;
}
使用建议
- 基本类型(int、bool 等):通常使用传值,因为复制开销小
- 容器类型(vector、unordered_map 等):通常使用传引用,避免复制开销
- 重要提醒:递归函数中的容器参数切勿使用传值,否则每次递归都会创建副本,导致性能问题
// 推荐:传引用
void processVector(vector<int>& nums) {
// 处理逻辑
}
// 避免:传值(性能差)
void processVectorSlow(vector<int> nums) {
// 处理逻辑
}