1. C++基础语法精要
C++作为一门兼具高性能与灵活性的编程语言,其基础语法体系是每个开发者必须扎实掌握的根基。不同于其他现代语言,C++保留了C语言的核心特性同时引入了面向对象范式,这种双重特性使其在系统编程领域始终占据不可替代的地位。
1.1 变量与数据类型
C++作为静态类型语言,要求在编译时明确每个变量的数据类型。基础数据类型包括:
- 整型:
short(2字节)、int(4字节)、long(8字节) - 浮点型:
float(4字节)、double(8字节) - 字符型:
char(1字节)、wchar_t(宽字符) - 布尔型:
bool(true/false)
变量声明语法示例:
cpp复制int count = 10; // 带初始化的声明
double price = 9.99; // 双精度浮点数
char grade = 'A'; // 单字符
bool is_valid = true; // 布尔值
关键细节:C++11引入了
auto关键字实现类型推导,但基础阶段建议显式声明类型以加深理解。
1.2 运算符与表达式
C++支持丰富的运算符类型:
- 算术运算符:
+ - * / % - 关系运算符:
== != > < >= <= - 逻辑运算符:
&& || ! - 位运算符:
& | ^ ~ << >>
典型表达式示例:
cpp复制int result = (a + b) * c % d; // 复合算术运算
bool condition = (x > 0) && (y < 100); // 逻辑组合
特殊运算符注意事项:
- 自增/自减运算符的前置(
++i)与后置(i++)差异 - 三目运算符
?:的合理使用场景 - 位运算在嵌入式开发中的高效应用
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 流程控制结构
2.1 条件分支
if-else语句是基础中的基础,但实际工程中容易忽略一些细节:
cpp复制if (temperature > 30) {
cout << "Hot day";
} else if (temperature > 20) {
cout << "Warm day";
} else {
cout << "Cool day";
}
switch语句适用于多路分支:
cpp复制switch(menu_choice) {
case 1:
startGame();
break;
case 2:
loadGame();
break;
default:
cout << "Invalid choice";
}
常见陷阱:忘记写
break导致的case穿透问题,这在大型项目中可能引发难以察觉的bug。
2.2 循环结构
while循环适合不确定次数的迭代:
cpp复制while (server.isRunning()) {
processRequest();
}
for循环的传统与C++11风格:
cpp复制// 传统方式
for (int i = 0; i < 10; ++i) {
cout << i << endl;
}
// C++11范围for
vector<int> nums = {1,2,3};
for (int num : nums) {
cout << num << endl;
}
循环控制关键字:
break:立即退出循环continue:跳过本次迭代- 避免滥用这些控制语句,保持代码可读性
3. 函数与作用域
3.1 函数定义与调用
基本函数结构示例:
cpp复制// 函数声明
double calculateBMI(double weight, double height);
// 函数定义
double calculateBMI(double weight, double height) {
return weight / (height * height);
}
参数传递方式对比:
- 值传递:创建副本,原变量不受影响
- 引用传递:操作原始变量,使用
&符号 - 指针传递:通过地址间接操作
3.2 函数重载与默认参数
C++允许同名函数通过参数列表区分:
cpp复制void print(int i) { cout << "Integer: " << i; }
void print(double f) { cout << "Float: " << f; }
void print(string s) { cout << "String: " << s; }
默认参数设置技巧:
cpp复制void setup(int width = 800, int height = 600) {
// 使用默认值或传入参数
}
工程经验:重载函数应保持语义一致性,避免给调用者造成困惑。
4. 数组与字符串处理
4.1 数组基础
一维数组声明与初始化:
cpp复制int numbers[5] = {1,2,3,4,5}; // 静态数组
int matrix[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}}; // 二维数组
数组使用的注意事项:
- 越界访问是常见错误源
- C++11支持更安全的
std::array容器 - 数组名在多数情况下退化为指针
4.2 字符串处理
C风格字符串与C++ string类对比:
cpp复制char cstr[] = "Hello"; // C风格
string cppstr = "World"; // C++ string类
常用字符串操作:
cpp复制string s1 = "Hello";
string s2 = "World";
string s3 = s1 + " " + s2; // 字符串连接
int len = s3.length(); // 获取长度
size_t pos = s3.find("Wo"); // 查找子串
性能提示:频繁字符串操作应优先使用string类,避免C风格字符串的内存管理负担。
5. 指针与引用深入
5.1 指针基础概念
指针声明与使用示例:
cpp复制int var = 20;
int *ptr = &var; // ptr指向var的地址
cout << *ptr; // 解引用输出20
*ptr = 30; // 通过指针修改变量值
指针运算的特殊性:
cpp复制int arr[] = {10,20,30};
int *p = arr;
cout << *(p + 1); // 输出20,指针算术
5.2 引用特性
引用与指针的关键区别:
cpp复制int x = 10;
int &ref = x; // 引用必须初始化
ref = 20; // 直接修改x的值
// 引用与指针的对比:
// 1. 引用不能为空,指针可以为nullptr
// 2. 引用不能重新绑定,指针可以改变指向
// 3. 引用使用更直观,无需解引用操作符
设计原则:函数参数优先使用const引用,既避免拷贝又防止意外修改。
6. 结构体与自定义类型
6.1 结构体定义
基本结构体示例:
cpp复制struct Student {
string name;
int age;
double gpa;
};
Student s1;
s1.name = "Alice";
s1.age = 20;
结构体与类的区别:
- 默认访问权限不同(struct是public)
- 习惯上struct用于纯数据聚合
- C++中struct也可以包含成员函数
6.2 类型别名
使用typedef和using创建类型别名:
cpp复制typedef unsigned long ulong; // 传统方式
using Matrix = vector<vector<double>>; // C++11方式
枚举类型定义:
cpp复制enum Color {RED, GREEN, BLUE};
Color c = GREEN;
7. 文件基础IO操作
7.1 文件读写流程
文件操作基本模式:
cpp复制#include <fstream>
// 写入文件
ofstream outfile("data.txt");
outfile << "Hello File IO" << endl;
outfile.close();
// 读取文件
ifstream infile("data.txt");
string line;
while (getline(infile, line)) {
cout << line << endl;
}
infile.close();
文件打开模式详解:
ios::in:读取模式ios::out:写入模式ios::app:追加模式ios::binary:二进制模式
7.2 错误处理机制
检查文件操作状态:
cpp复制if (!infile) {
cerr << "File open failed" << endl;
return 1;
}
使用异常处理:
cpp复制try {
ofstream file("data.txt");
if (!file) throw runtime_error("File error");
// 文件操作...
} catch (const exception& e) {
cerr << "Error: " << e.what() << endl;
}
8. 标准模板库(STL)入门
8.1 容器概览
三大类STL容器:
- 序列容器:
vector,list,deque - 关联容器:
set,map,multiset - 无序关联容器:
unordered_set,unordered_map
vector基本用法:
cpp复制vector<int> nums = {1,2,3};
nums.push_back(4); // 添加元素
cout << nums[0]; // 访问元素
nums.pop_back(); // 移除末尾元素
8.2 算法与迭代器
常用算法示例:
cpp复制#include <algorithm>
vector<int> v = {3,1,4,2};
sort(v.begin(), v.end()); // 排序
auto it = find(v.begin(), v.end(), 4); // 查找
reverse(v.begin(), v.end()); // 反转
迭代器类型与用法:
cpp复制for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
性能建议:了解各容器的时间复杂度特性,如vector随机访问O(1)但中间插入O(n)。
9. 面向对象基础
9.1 类与对象
类定义基本结构:
cpp复制class Rectangle {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() { return width * height; }
};
Rectangle rect(3.0, 4.0);
cout << rect.area(); // 输出12
访问控制详解:
private:仅类内可访问protected:类及子类可访问public:完全开放访问
9.2 构造函数与析构函数
特殊成员函数示例:
cpp复制class Student {
string name;
public:
Student() : name("Unknown") {} // 默认构造
Student(string n) : name(n) {} // 参数化构造
~Student() { cout << "Destroying " << name; } // 析构
};
构造函数初始化列表的优势:
- 直接初始化成员变量
- 对const成员和引用成员必须使用
- 性能优于先默认构造再赋值
10. 异常处理机制
10.1 try-catch块
基本异常处理结构:
cpp复制try {
int age = -5;
if (age < 0) throw invalid_argument("Age cannot be negative");
} catch (const invalid_argument& e) {
cerr << "Error: " << e.what() << endl;
} catch (...) {
cerr << "Unknown error occurred" << endl;
}
标准异常类型:
logic_error:程序逻辑错误runtime_error:运行时错误bad_alloc:内存分配失败
10.2 自定义异常
创建异常类:
cpp复制class MyException : public exception {
string msg;
public:
MyException(const string& m) : msg(m) {}
const char* what() const noexcept override {
return msg.c_str();
}
};
异常安全原则:
- 不抛出析构函数中的异常
- 保证资源释放(使用RAII)
- 异常应传递足够诊断信息
11. 现代C++特性简介
11.1 auto与decltype
类型推导应用:
cpp复制auto x = 5; // x被推导为int
auto y = 3.14; // double
vector<int> v = {1,2,3};
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it;
}
decltype类型查询:
cpp复制int a = 10;
decltype(a) b = 20; // b的类型与a相同(int)
11.2 基于范围的for循环
简化容器遍历:
cpp复制vector<string> names = {"Alice", "Bob"};
for (const auto& name : names) {
cout << name << endl;
}
实现原理:
- 依赖容器的
begin()和end()方法 - 相当于传统迭代器语法的语法糖
- 对数组也有效
12. 实战项目:学生成绩系统
12.1 系统设计
基本功能需求:
- 添加学生记录
- 查询学生成绩
- 统计班级平均分
- 保存/加载数据
类结构设计:
cpp复制class Student {
string name;
vector<double> scores;
public:
// 成员函数声明...
};
class GradeSystem {
vector<Student> students;
public:
void addStudent(const Student& s);
void saveToFile(const string& filename);
// 其他功能...
};
12.2 核心实现
文件持久化示例:
cpp复制void GradeSystem::saveToFile(const string& filename) {
ofstream out(filename);
for (const auto& s : students) {
out << s.getName() << ",";
for (double score : s.getScores()) {
out << score << " ";
}
out << endl;
}
}
数据统计功能:
cpp复制double GradeSystem::classAverage() const {
if (students.empty()) return 0.0;
double total = 0.0;
int count = 0;
for (const auto& s : students) {
for (double score : s.getScores()) {
total += score;
count++;
}
}
return total / count;
}
13. 调试技巧与工具
13.1 常见错误类型
编译时错误:
- 语法错误:缺少分号、括号不匹配等
- 类型不匹配:隐式转换问题
- 未声明标识符:拼写错误或缺少头文件
运行时错误:
- 段错误:非法内存访问
- 除零错误:数学运算异常
- 逻辑错误:程序行为不符合预期
13.2 GDB基础用法
基本调试命令:
code复制g++ -g program.cpp -o program # 编译时加入调试信息
gdb ./program # 启动调试
(gdb) break main # 设置断点
(gdb) run # 启动程序
(gdb) next # 单步执行
(gdb) print variable # 查看变量值
(gdb) backtrace # 查看调用栈
14. 性能优化基础
14.1 常见优化策略
代码层面优化:
- 减少不必要的拷贝(使用引用)
- 预分配容器空间(vector::reserve)
- 选择合适的数据结构
编译器优化选项:
-O1:基础优化-O2:推荐优化级别-O3:激进优化(可能增加代码体积)
14.2 性能分析工具
使用gprof进行性能剖析:
code复制g++ -pg program.cpp -o program # 编译时加入剖析信息
./program # 运行生成gmon.out
gprof program gmon.out > analysis.txt # 生成分析报告
报告关键指标:
- 各函数调用次数
- 函数执行时间占比
- 调用关系图
15. 编码规范与最佳实践
15.1 命名约定
常见命名风格:
- 驼峰式:
myVariableName - 蛇形:
my_variable_name - 匈牙利:
iCount(不推荐现代C++)
类型命名建议:
- 类名:大写开头,
MyClass - 变量名:小写开头,
studentCount - 常量:全大写,
MAX_SIZE
15.2 代码组织
头文件规范示例:
cpp复制// myclass.h
#ifndef MYCLASS_H // 防止重复包含
#define MYCLASS_H
class MyClass {
public:
void publicMethod();
private:
int privateData;
};
#endif
源文件对应实现:
cpp复制// myclass.cpp
#include "myclass.h"
void MyClass::publicMethod() {
// 实现代码
}
16. 跨平台开发注意事项
16.1 平台差异处理
行尾符差异:
- Windows:
\r\n - Unix/Linux:
\n - Mac OS传统:
\r
路径分隔符处理:
cpp复制#ifdef _WIN32
const char SEP = '\\';
#else
const char SEP = '/';
#endif
16.2 条件编译
平台特定代码示例:
cpp复制#if defined(__linux__)
// Linux专用代码
#elif defined(_WIN32)
// Windows专用代码
#else
#error "Unsupported platform"
#endif
特性检测宏:
cpp复制#if __cplusplus >= 201103L
// C++11及以上特性
#endif
17. 第三方库集成
17.1 库的获取与安装
常见安装方式:
- 系统包管理器(apt/yum等)
- 源码编译安装(./configure && make)
- 包管理工具(vcpkg/conan)
编译链接选项:
code复制g++ program.cpp -I/path/to/include -L/path/to/lib -llibraryname
17.2 常用库推荐
基础工具库:
- Boost:扩展功能库
- fmt:格式化库
- spdlog:日志库
领域专用库:
- OpenCV:计算机视觉
- Eigen:线性代数
- Qt:GUI开发
18. 多文件项目管理
18.1 Makefile基础
简单Makefile示例:
makefile复制CXX = g++
CXXFLAGS = -std=c++11 -Wall
target: main.o utils.o
$(CXX) $(CXXFLAGS) -o target main.o utils.o
main.o: main.cpp utils.h
$(CXX) $(CXXFLAGS) -c main.cpp
utils.o: utils.cpp utils.h
$(CXX) $(CXXFLAGS) -c utils.cpp
clean:
rm -f *.o target
18.2 CMake入门
基本CMakeLists.txt:
cmake复制cmake_minimum_required(VERSION 3.10)
project(MyProject)
set(CMAKE_CXX_STANDARD 11)
add_executable(target main.cpp utils.cpp)
构建流程:
code复制mkdir build && cd build
cmake ..
make
19. 内存管理进阶
19.1 智能指针
unique_ptr示例:
cpp复制#include <memory>
auto ptr = std::make_unique<int>(42);
// 自动释放内存,不能复制
shared_ptr使用场景:
cpp复制auto shared = std::make_shared<int>(100);
// 引用计数,可共享所有权
19.2 内存泄漏检测
Valgrind基本用法:
code复制valgrind --leak-check=full ./program
常见内存问题:
- 忘记释放内存
- 重复释放
- 访问已释放内存
20. 模板编程入门
20.1 函数模板
通用函数示例:
cpp复制template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
cout << max(3, 5); // 5
cout << max(3.14, 2.0); // 3.14
20.2 类模板
通用容器示例:
cpp复制template <class T>
class Box {
T content;
public:
void set(T t) { content = t; }
T get() { return content; }
};
Box<int> intBox;
Box<string> strBox;
模板特化:
cpp复制template <>
class Box<char> {
// 针对char类型的特殊实现
};
