1. C++基础概念概述
C++作为一门经典的编程语言,从1983年诞生至今已经走过了40年的发展历程。它最初被称为"C with Classes",是Bjarne Stroustrup在贝尔实验室工作时对C语言的扩展。与C语言相比,C++最大的特点就是支持面向对象编程(OOP),同时保留了C语言的高效性和底层控制能力。
在实际开发中,C++被广泛应用于系统软件、游戏开发、高频交易、嵌入式系统等对性能要求极高的领域。比如我们熟知的Windows操作系统核心组件、Adobe系列软件、Unreal游戏引擎等都是用C++开发的。学习C++不仅能让你理解计算机底层工作原理,还能培养严谨的编程思维。
提示:虽然C++学习曲线较陡峭,但掌握其核心概念后,你会发现它比其他语言提供了更精细的内存控制和更高的执行效率。
2. C++核心语法解析
2.1 变量与数据类型
C++作为静态类型语言,要求在编译时就确定变量的数据类型。基础数据类型包括:
- 整型:int(4字节)、short(2字节)、long(4或8字节)、long long(8字节)
- 浮点型:float(4字节)、double(8字节)
- 字符型:char(1字节)
- 布尔型:bool(1字节)
变量声明示例:
cpp复制int age = 25; // 整型变量
double price = 99.99; // 双精度浮点
char grade = 'A'; // 字符
bool is_valid = true; // 布尔
类型修饰符:
- signed/unsigned:控制是否有符号
- const:定义常量
- volatile:防止编译器优化
注意:C++11引入了auto关键字用于自动类型推导,但基础学习中建议显式声明类型以加深理解。
2.2 运算符与表达式
C++运算符主要分为:
- 算术运算符:+ - * / % ++ --
- 关系运算符:== != > < >= <=
- 逻辑运算符:&& || !
- 位运算符:& | ^ ~ << >>
- 赋值运算符:= += -= *= /= %=等
运算符优先级问题在实际编码中经常导致bug。例如:
cpp复制int result = 5 + 3 * 2; // 结果是11而不是16
建议:
- 复杂表达式使用括号明确优先级
- 避免在单个表达式中使用过多运算符
- 注意++/--的前置和后置区别
2.3 控制结构
2.3.1 条件语句
if-else是最基础的条件控制:
cpp复制if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else {
grade = 'C';
}
switch-case适用于多分支选择:
cpp复制switch(day) {
case 1: cout << "Monday"; break;
case 2: cout << "Tuesday"; break;
// ...
default: cout << "Invalid day";
}
提示:switch中的break语句不能省略,否则会继续执行后续case(称为"fall through")
2.3.2 循环结构
C++提供三种循环:
- while循环:
cpp复制while (condition) {
// 循环体
}
- do-while循环:
cpp复制do {
// 至少执行一次
} while (condition);
- for循环(最常用):
cpp复制for (int i = 0; i < 10; i++) {
cout << i << endl;
}
循环控制语句:
- break:立即退出循环
- continue:跳过本次迭代
3. 函数与程序结构
3.1 函数基础
函数定义语法:
cpp复制返回类型 函数名(参数列表) {
// 函数体
return 返回值;
}
示例:
cpp复制int add(int a, int b) {
return a + b;
}
函数调用:
cpp复制int sum = add(3, 5); // sum = 8
3.2 函数参数传递
C++支持三种参数传递方式:
- 传值(默认):
cpp复制void func(int x) {...} // 修改x不影响实参
- 传引用:
cpp复制void func(int &x) {...} // 修改x会影响实参
- 传指针:
cpp复制void func(int *x) {...} // 通过指针修改实参
经验:大型对象建议使用const引用传递,避免拷贝开销同时防止修改
3.3 函数重载
C++允许同名函数根据参数列表区分:
cpp复制int add(int a, int b) { return a+b; }
double add(double a, double b) { return a+b; }
编译器会根据实参类型选择合适版本。
3.4 默认参数
可以为参数指定默认值:
cpp复制void print(string msg, int times = 1) {
for (int i=0; i<times; i++)
cout << msg;
}
调用时:
cpp复制print("Hello"); // 打印1次
print("Hi", 3); // 打印3次
注意:默认参数必须从右向左连续定义
4. 面向对象编程基础
4.1 类与对象
类定义示例:
cpp复制class Student {
private:
string name;
int age;
public:
void setName(string n) { name = n; }
string getName() { return name; }
void setAge(int a) {
if (a > 0) age = a;
}
int getAge() { return age; }
};
创建对象:
cpp复制Student stu;
stu.setName("Alice");
stu.setAge(20);
4.2 构造函数与析构函数
构造函数在对象创建时自动调用:
cpp复制class Student {
public:
Student(string n, int a) {
name = n;
age = a;
}
// ...
};
析构函数在对象销毁时调用:
cpp复制~Student() {
cout << "Student对象被销毁" << endl;
}
4.3 继承与多态
继承示例:
cpp复制class Person {
protected:
string name;
public:
void walk() { cout << "Walking..." << endl; }
};
class Student : public Person {
public:
void study() { cout << "Studying..." << endl; }
};
多态通过虚函数实现:
cpp复制class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override { cout << "Drawing circle" << endl; }
};
5. 内存管理与指针
5.1 指针基础
指针变量存储内存地址:
cpp复制int num = 10;
int *ptr = # // ptr指向num的地址
cout << *ptr; // 解引用,输出10
5.2 动态内存分配
使用new/delete操作符:
cpp复制int *arr = new int[10]; // 分配数组
delete[] arr; // 释放数组
Student *stu = new Student(); // 分配对象
delete stu; // 释放对象
警告:忘记delete会导致内存泄漏,重复delete会导致未定义行为
5.3 智能指针(C++11)
现代C++推荐使用智能指针:
cpp复制#include <memory>
unique_ptr<int> p1(new int(42)); // 独占所有权
shared_ptr<int> p2 = make_shared<int>(42); // 共享所有权
weak_ptr<int> p3 = p2; // 弱引用
6. 标准库常用组件
6.1 字符串处理
string类比C风格字符串更安全:
cpp复制#include <string>
using namespace std;
string s1 = "Hello";
string s2 = "World";
string s3 = s1 + " " + s2; // 字符串连接
cout << s3.length(); // 获取长度
cout << s3.substr(1, 3); // 子串
6.2 容器类
常用STL容器:
cpp复制#include <vector>
#include <map>
#include <unordered_map>
vector<int> vec = {1, 2, 3};
vec.push_back(4); // 添加元素
map<string, int> m;
m["apple"] = 5; // 插入键值对
unordered_map<string, int> um; // 哈希表实现
6.3 算法
STL算法示例:
cpp复制#include <algorithm>
vector<int> nums = {3, 1, 4, 2};
sort(nums.begin(), nums.end()); // 排序
auto it = find(nums.begin(), nums.end(), 4); // 查找
if (it != nums.end()) {
cout << "Found at position " << it - nums.begin();
}
7. 常见问题与调试技巧
7.1 编译错误排查
常见编译错误:
- 语法错误:缺少分号、括号不匹配等
- 类型不匹配:如将int赋值给string
- 未声明标识符:忘记包含头文件或拼写错误
建议:
- 从第一个错误开始修正
- 仔细阅读错误信息(包括行号)
- 使用IDE的语法高亮和实时检查
7.2 运行时错误处理
常见运行时错误:
- 段错误(Segmentation fault):非法内存访问
- 除零错误
- 空指针解引用
调试技巧:
- 使用gdb调试器
- 添加打印语句
- 使用try-catch处理异常
7.3 性能优化建议
- 避免不必要的拷贝:使用引用或移动语义
- 预分配容器大小:如vector的reserve()
- 选择合适的数据结构:如频繁查找用unordered_map
- 减少动态内存分配:重用对象或使用内存池
8. 现代C++特性简介(C++11/14/17)
8.1 自动类型推导
auto关键字:
cpp复制auto x = 5; // int
auto y = 3.14; // double
auto z = "hello"; // const char*
8.2 范围for循环
简化容器遍历:
cpp复制vector<int> vec = {1, 2, 3};
for (auto num : vec) {
cout << num << endl;
}
8.3 Lambda表达式
匿名函数:
cpp复制auto sum = [](int a, int b) { return a + b; };
cout << sum(3, 4); // 输出7
8.4 移动语义
避免不必要的拷贝:
cpp复制string s1 = "Hello";
string s2 = move(s1); // s1现在为空
在实际项目中,我建议初学者先从基础语法和面向对象概念开始,逐步过渡到STL使用,最后再学习现代C++特性。每个概念都要通过实际编码来巩固,比如实现一个小型学生管理系统来练习类和对象的使用。
