🎓 C++ 综合复习 - L30 数据结构

知识点回顾、综合应用、常见问题解答、学习路径建议

📚 核心知识点回顾

1. 结构体(struct)

struct Student { string name; int age; double score; }; // 创建和初始化 Student stu = {"张三", 18, 92.5}; cout << stu.name << endl; // 访问成员
特性说明
默认访问控制public(所有成员公开)
主要用途数据聚合,简单数据集合
初始化方式逐个赋值、初始化列表、C++11统一初始化
嵌套支持可以包含其他结构体

2. 指针(Pointer)

int num = 42; int* ptr = # // 获取地址 cout << *ptr << endl; // 解引用:42 *ptr = 100; // 通过指针修改原变量 // 动态内存分配 int* arr = new int[5]; delete[] arr; // 释放内存
运算符作用
&取地址运算符
*解引用运算符
new/delete动态内存分配/释放
nullptr空指针(C++11)

3. 引用(Reference)

int x = 10; int& ref = x; // ref是x的别名 ref = 20; // x也变成20 // 函数参数传递 void swap(int& a, int& b) { int temp = a; a = b; b = temp; }
特性说明
必须初始化声明时必须绑定到变量
不能重新绑定一旦绑定不能改变
无额外开销底层实现为指针,但更安全
const引用只读引用,防止修改

4. 类(Class)

class Student { private: string name; double score; public: // 构造函数 Student(string n, double s) : name(n), score(s) {} // Getter/Setter string getName() { return name; } void setScore(double s) { score = s; } void show() { cout << name << ": " << score << endl; } };
特性说明
默认访问控制private(成员私有)
封装数据隐藏,接口暴露
构造函数对象创建时自动调用
析构函数对象销毁时自动调用
this指针指向当前对象

💻 综合应用示例

学生管理系统(完整版)

结合结构体、指针、类、文件操作等知识,实现一个完整的学生管理系统。

#include <iostream> #include <vector> #include <string> #include <fstream> #include <algorithm> using namespace std; // 使用类封装学生信息 class Student { private: string name; int id; double score; public: Student(string n = "", int i = 0, double s = 0) : name(n), id(i), score(s) {} // Getter方法 string getName() const { return name; } int getId() const { return id; } double getScore() const { return score; } // Setter方法 void setScore(double s) { if (s >= 0 && s <= 100) score = s; } // 显示信息 void display() const { cout << "ID: " << id << " | 姓名: " << name << " | 成绩: " << score << endl; } }; // 学生管理类 class StudentManager { private: vector<Student> students; public: // 添加学生 void addStudent(const Student& stu) { students.push_back(stu); } // 查找学生 const Student* findStudent(int id) const { for (const auto& stu : students) { if (stu.getId() == id) { return &stu; // 返回指针 } } return nullptr; } // 按成绩排序 void sortByScore() { sort(students.begin(), students.end(), [](const Student& a, const Student& b) { return a.getScore() > b.getScore(); }); } // 计算平均分 double averageScore() const { if (students.empty()) return 0; double total = 0; for (const auto& stu : students) { total += stu.getScore(); } return total / students.size(); } // 显示所有学生 void displayAll() const { for (const auto& stu : students) { stu.display(); } } size_t getSize() const { return students.size(); } }; int main() { StudentManager manager; // 添加学生 manager.addStudent(Student("张三", 1001, 92.5)); manager.addStudent(Student("李四", 1002, 88.0)); manager.addStudent(Student("王五", 1003, 95.0)); // 显示所有学生 cout << "=== 学生列表 ===" << endl; manager.displayAll(); // 查找学生 const Student* found = manager.findStudent(1002); if (found) { cout << "\n找到学生:" << endl; found->display(); } // 排序并显示 manager.sortByScore(); cout << "\n=== 按成绩排序 ===" << endl; manager.displayAll(); // 统计信息 cout << "\n学生总数:" << manager.getSize() << endl; cout << "平均成绩:" << manager.averageScore() << endl; return 0; }

关键技术点总结

  • 类的封装:private数据 + public接口
  • 构造函数:初始化列表高效初始化
  • const正确性:不修改对象的方法标记为const
  • 指针返回:findStudent返回指针,未找到返回nullptr
  • vector容器:动态数组管理学生列表
  • Lambda表达式:sort的自定义比较函数
  • range-based for:简洁的遍历方式

❓ 常见问题解答

Q1: struct和class有什么区别?

A: 主要区别在于默认访问控制:

// struct默认public struct MyStruct { int x; // public,外部可直接访问 }; // class默认private class MyClass { int x; // private,外部不能直接访问 }; // 在C++中,struct也可以有方法和继承 // 但通常用于简单数据集合 // class用于面向对象编程
💡 选择建议:
• 简单数据集合 → 使用struct
• 需要封装、继承、多态 → 使用class
• 实际开发中,大多数情况使用class更规范

Q2: 什么时候用指针,什么时候用引用?

A: 根据使用场景选择:

// 使用引用的场景: // 1. 函数参数传递(避免拷贝) void modify(int& x) { x = 100; } // 2. 返回值(返回已存在的对象) int& getElement(vector<int>& vec, int index) { return vec[index]; } // 使用指针的场景: // 1. 动态内存分配 int* arr = new int[10]; // 2. 可能为空的情况 Node* findNode(int id) { // 找不到返回nullptr } // 3. 需要重新指向不同对象 int* ptr = &a; ptr = &b; // 可以改变指向
💡 一般原则:
• 优先使用引用(更安全、更清晰)
• 需要nullptr或重新指向时用指针
• 现代C++推荐使用智能指针管理动态内存

Q3: 如何避免内存泄漏?

A: 遵循以下最佳实践:

// ❌ 错误:忘记释放内存 int* ptr = new int(42); // 忘记 delete ptr // ✅ 正确:及时释放 int* ptr = new int(42); delete ptr; ptr = nullptr; // 避免野指针 // ✅ 推荐:使用智能指针(C++11) #include <memory> auto ptr = make_unique<int>(42); // 自动释放,无需手动delete
💡 内存管理规则:
• new ↔ delete(单个对象)
• new[] ↔ delete[](数组)
• 释放后立即设置为nullptr
• 优先使用智能指针(unique_ptr、shared_ptr)

Q4: const有哪些用法?

// 1. const变量(常量) const int MAX_SIZE = 100; // 2. const指针 const int* ptr1; // 指针指向的内容不可变 int* const ptr2; // 指针本身不可变 const int* const ptr3; // 都不可变 // 3. const引用 void print(const string& str) { // 保证不修改str } // 4. const成员函数 class Student { public: int getAge() const { // 不修改对象状态 return age; } };

🗺️ 学习路径建议

已完成的学习内容

  • 基础篇(L1-L5):变量、数据类型、运算符、输入输出、控制结构
  • 高级篇(L14-L20):数组、字符串、函数、递归、算法基础
  • 核心语言特性(L21-L28):数制转换、函数深入、字符串类、文件操作、指针引用、日期时间、类和对象
  • 数据结构(L29-L30):结构体、综合复习 ← 刚完成
🎯 当前进度:19/40课程完成(47.5%)
你已经掌握了C++的核心基础知识!接下来可以进入算法基础模块。

下一步学习计划

模块内容难度预计时间
算法基础(L31-L40) 暴力枚举、排序算法、二分查找、递归算法、动态规划等 ⭐⭐⭐ 2-3周
进阶篇(L6-L13) 循环深入、函数进阶、数组应用、字符串处理等 ⭐⭐ 1-2周
项目实战 学生管理系统、简易计算器、文本编辑器等 ⭐⭐⭐⭐ 2-4周

学习建议

  1. 理论与实践结合:每学一个概念都要动手写代码
  2. 多做练习:完成每个课程的实战练习部分
  3. 阅读优秀代码:学习他人的编程风格和技巧
  4. 参与项目:将所学知识应用到实际项目中
  5. 持续学习:关注C++新特性(C++11/14/17/20)
  6. 加入社区:参与编程论坛,与他人交流学习
💡 推荐资源:
• 书籍:《C++ Primer》、《Effective C++》
• 网站:cppreference.com、LeetCode
• 工具:Visual Studio、CLion、VS Code
• 社区:Stack Overflow、GitHub、Reddit r/cpp

📝 实战练习

📝 理解测试

以下代码有什么问题?

#include <iostream> using namespace std; int* createArray(int size) { int arr[100]; // 局部数组 for (int i = 0; i < size; i++) { arr[i] = i; } return arr; // 返回局部数组的地址 } int main() { int* ptr = createArray(10); cout << ptr[0] << endl; // 未定义行为! return 0; }
选择答案查看解析...
💻 综合挑战

题目:设计一个完整的通讯录管理系统:
1. 定义Contact结构体:姓名、电话、邮箱、地址
2. 使用vector存储联系人
3. 实现功能:添加、删除、查找、显示所有联系人
4. 按姓名排序
5. 保存到文件和从文件加载

点击"生成代码框架"查看提示...