📚 一、C++ 基础语法
1.1 程序结构
cpp
#include <iostream> // 包含标准输入输出库
using namespace std; // 使用标准命名空间(可选,但常见)
int main() {
cout << "Hello, World!" << endl; // 输出字符串
return 0; // 返回程序状态(0表示成功)
}
#include:预处理器指令,包含头文件。main():程序入口函数,必须存在。cout:输出流对象,<<是流插入运算符。endl:换行并刷新缓冲区。
✅ 注意事项:
using namespace std;在大型项目中可能导致命名冲突,建议在函数内使用或显式写std::cout。return 0;在main函数中可省略(C++ 标准规定默认返回 0)。
🧩 二、数据类型与变量
2.1 基本数据类型
| 类型 | 大小(字节) | 范围 |
|---|---|---|
bool |
1 | true / false |
char |
1 | -128 到 127 或 0 到 255 |
int |
4 | -2^31 到 2^31-1 |
float |
4 | 单精度浮点数 |
double |
8 | 双精度浮点数 |
void |
无 | 无值 |
cpp
#include <iostream>
#include <climits> // 提供整型极限值
#include <cfloat> // 提供浮点型极限值
int main() {
int a = 10;
double b = 3.14159;
char c = 'A';
bool flag = true;
cout << "int size: " << sizeof(int) << " bytes" << endl;
cout << "Max int: " << INT_MAX << endl;
cout << "Min double: " << DBL_MIN << endl;
return 0;
}
⚠️ 注意事项:
char可能是signed或unsigned,取决于编译器,建议明确使用signed char或unsigned char。- 浮点数比较应避免直接使用
==,建议使用误差范围。
🔢 三、运算符
3.1 常用运算符
cpp
int a = 10, b = 3;
// 算术
int add = a + b; // 13
int mod = a % b; // 1
// 关系
bool eq = (a == b); // false
// 逻辑
bool and_op = (a > 5 && b < 5); // true
// 位运算
int and_bit = a & b; // 2 (0b1010 & 0b0011)
int left_shift = a << 1; // 20 (左移1位)
// 自增/自减
int x = 5;
int y = ++x; // x=6, y=6 (前缀)
int z = x++; // z=6, x=7 (后缀)
✅ 高级用法:位运算常用于状态标志、性能优化。
🧱 四、控制结构
4.1 条件语句
cpp
int score = 85;
if (score >= 90) {
cout << "A";
} else if (score >= 80) {
cout << "B"; // 输出
} else {
cout << "C";
}
4.2 循环
cpp
// for 循环
for (int i = 0; i < 5; ++i) {
cout << i << " ";
}
// while
int i = 0;
while (i < 5) {
cout << i++ << " ";
}
// do-while(至少执行一次)
do {
cout << i-- << " ";
} while (i > 0);
⚠️ 注意事项:
- 优先使用
++i而非i++在循环中(性能更优,尤其对复杂对象)。- 避免无限循环,确保循环条件可终止。
📦 五、函数
5.1 函数定义与调用
cpp
#include <iostream>
using namespace std;
// 函数声明(可选)
int add(int a, int b);
// 函数定义
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(3, 4); // 调用
cout << result << endl; // 7
return 0;
}
5.2 函数重载
cpp
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
string add(string a, string b) { return a + b; }
✅ 规则:参数类型、数量或顺序不同即可重载。
5.3 内联函数(inline)
cpp
inline int max(int a, int b) {
return (a > b) ? a : b;
}
✅ 用途:减少函数调用开销,适合短小函数。
🔗 六、指针与引用
6.1 指针
cpp
int value = 10;
int* ptr = &value; // 指针指向 value 的地址
cout << *ptr << endl; // 解引用:输出 10
*ptr = 20; // 修改 value 的值
cout << value << endl; // 20
6.2 引用
cpp
int a = 10;
int& ref = a; // ref 是 a 的别名
ref = 20;
cout << a << endl; // 20
✅ 区别:
- 指针可变,引用一旦绑定不能改。
- 引用必须初始化,指针可以为
nullptr。- 引用更安全,推荐用于函数参数传递。
6.3 动态内存
cpp
int* p = new int(42); // 动态分配
cout << *p << endl;
delete p; // 释放内存
// 数组
int* arr = new int[10];
delete[] arr; // 注意:用 delete[] 释放数组
⚠️ 注意事项:
- 必须配对
new/delete,new[]/delete[]。- 避免内存泄漏,建议使用智能指针。
🧱 七、数组与字符串
7.1 数组
cpp
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; ++i) {
cout << arr[i] << " ";
}
// C++11 范围 for
for (int& elem : arr) {
cout << elem << " ";
}
7.2 字符串
cpp
#include <string>
string str = "Hello";
str += " World";
cout << str << endl; // Hello World
cout << str.length() << endl; // 11
✅ 建议 :优先使用
std::string而非 C 风格字符串(char*)。
🏗️ 八、类与对象(面向对象)
8.1 类定义
cpp
class Person {
private:
string name;
int age;
public:
// 构造函数
Person(const string& n, int a) : name(n), age(a) {}
// 成员函数
void introduce() const {
cout << "I'm " << name << ", " << age << " years old." << endl;
}
// Getter/Setter
int getAge() const { return age; }
void setAge(int a) { if (a > 0) age = a; }
};
8.2 使用
cpp
int main() {
Person p("Alice", 25);
p.introduce(); // I'm Alice, 25 years old.
return 0;
}
8.3 构造函数与析构函数
cpp
class MyClass {
public:
MyClass() { cout << "Constructor called" << endl; }
~MyClass() { cout << "Destructor called" << endl; }
};
✅ 注意:析构函数用于释放资源(如动态内存)。
8.4 拷贝构造函数与赋值运算符
cpp
class MyClass {
int* data;
public:
// 构造
MyClass(int val) {
data = new int(val);
}
// 拷贝构造(深拷贝)
MyClass(const MyClass& other) {
data = new int(*other.data);
}
// 赋值运算符
MyClass& operator=(const MyClass& other) {
if (this != &other) {
delete data;
data = new int(*other.data);
}
return *this;
}
// 析构
~MyClass() {
delete data;
}
};
⚠️ Rule of Three:如果需要自定义析构函数,通常也需要拷贝构造和赋值运算符。
🧬 九、继承与多态
9.1 继承
cpp
class Animal {
public:
virtual void speak() const {
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
void speak() const override {
cout << "Woof!" << endl;
}
};
9.2 多态
cpp
Animal* a = new Dog();
a->speak(); // 输出 "Woof!"(动态绑定)
delete a;
✅ 关键点:
- 使用
virtual实现运行时多态。- 基类析构函数应为
virtual,否则派生类资源可能无法正确释放。
🧩 十、模板(泛型编程)
10.1 函数模板
cpp
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 使用
int m1 = max(3, 5); // T = int
double m2 = max(3.1, 2.9); // T = double
10.2 类模板
cpp
template <typename T>
class Box {
T content;
public:
Box(T c) : content(c) {}
T get() const { return content; }
};
// 使用
Box<int> intBox(42);
Box<string> strBox("Hello");
✅ 优势:代码复用,类型安全。
🧠 十一、STL(标准模板库)
11.1 容器
cpp
#include <vector>
#include <map>
#include <set>
#include <algorithm>
vector<int> vec = {1, 2, 3};
vec.push_back(4);
map<string, int> ages;
ages["Alice"] = 25;
ages["Bob"] = 30;
set<int> nums = {1, 2, 2, 3}; // 自动去重
11.2 算法
cpp
sort(vec.begin(), vec.end());
auto it = find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
cout << "Found at index " << it - vec.begin() << endl;
}
✅ 建议:优先使用 STL 容器和算法,高效且安全。
🧰 十二、智能指针(C++11 起)
替代原始指针,自动管理内存。
cpp
#include <memory>
// 唯一所有权
unique_ptr<int> uptr = make_unique<int>(42);
// 自动释放,无需 delete
// 共享所有权
shared_ptr<int> sptr1 = make_shared<int>(100);
shared_ptr<int> sptr2 = sptr1; // 引用计数+1
// 当最后一个 shared_ptr 销毁时,自动释放
// 弱引用(避免循环引用)
weak_ptr<int> wptr = sptr1;
✅ 最佳实践 :优先使用
make_unique和make_shared。
🧪 十三、异常处理
cpp
#include <stdexcept>
void divide(int a, int b) {
if (b == 0) {
throw invalid_argument("Division by zero!");
}
cout << a / b << endl;
}
int main() {
try {
divide(10, 0);
} catch (const invalid_argument& e) {
cout << "Error: " << e.what() << endl;
}
return 0;
}
⚠️ 建议:
- 不要滥用异常。
- 抛出对象,捕获引用(避免拷贝)。
🧱 十四、高级特性(C++11/14/17/20)
14.1 auto 与 decltype
cpp
auto x = 42; // x 是 int
auto it = vec.begin(); // 自动推导迭代器类型
decltype(x) y = 10; // y 也是 int
14.2 Lambda 表达式
cpp
auto func = [](int a, int b) -> int {
return a + b;
};
cout << func(3, 4) << endl; // 7
// 捕获外部变量
int multiplier = 2;
auto lambda = [multiplier](int n) {
return n * multiplier;
};
14.3 移动语义(Move Semantics)
cpp
class MyString {
char* data;
public:
// 移动构造函数
MyString(MyString&& other) noexcept {
data = other.data;
other.data = nullptr;
}
// 移动赋值
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
other.data = nullptr;
}
return *this;
}
};
✅ 用途:提高性能,避免不必要的拷贝。
🛠️ 十五、注意事项与最佳实践
| 项目 | 建议 |
|---|---|
| 命名 | 使用驼峰或下划线,保持一致 |
| 内存管理 | 优先使用智能指针、容器,避免 new/delete |
| const 正确性 | 多用 const 修饰变量、函数、参数 |
| 头文件保护 | 使用 #pragma once 或 #ifndef |
| 编译警告 | 开启 -Wall -Wextra,修复所有警告 |
| RAII | 资源获取即初始化,确保异常安全 |
| C++ 标准 | 尽量使用 C++11 及以上特性 |