前言
提示:这里可以添加本文要记录的大概内容:
C和C++的区别介绍
一、C 语言和 C++ 哪个更容易学?
C 语言比 C++ 更简单,更容易入门。
但如果涉及 大规模项目、面向对象编程(OOP)、复杂数据结构,C++ 提供的功能更多,代码可维护性更强,但 学习曲线更陡。
对于嵌入式开发(如你正在做的 ZYNQ、RTOS、驱动开发),C 语言更常用,C++ 主要用于高层应用(如 GUI、AI 计算)。
C 语言和 C++ 的主要区别
| 对比点 | C 语言 | C++ 语言 |
|---|---|---|
| 编程范式 | 过程化编程(Procedural) | 支持面向对象(OOP)+ 过程化 |
| 内存管理 | 需要手动 malloc/free | new/delete(支持 RAII) |
| 数据封装 | 主要使用 struct | 支持 class 和 struct |
| 函数和变量 | 只支持普通函数 | 支持函数重载、模板、命名空间 |
| 代码复用 | 主要靠函数和结构体 | 支持继承、多态、模板 |
| 标准库 | 标准库较小 | STL(标准模板库)强大 |
| 适用场景 | 嵌入式、驱动、系统级开发 | 桌面软件、游戏、GUI、AI |
嵌入式/底层开发(MCU、Linux 内核、RTOS)→ C 更合适
应用层开发(GUI、AI、算法、游戏)→ C++ 更强大
二、学习方法和路径
2.1 掌握 C 语言(适合嵌入式、RTOS)
-
基础语法
- 变量、数据类型 (
int、char、float、double) - 条件判断 (
if、switch-case) - 循环 (
for、while、do-while)
- 变量、数据类型 (
-
指针和内存管理
- 指针 (
*和&,数组与指针的关系) malloc/free的动态内存管理- 结构体 (
struct)、共用体 (union)
- 指针 (
-
嵌入式相关
- 了解
volatile、const - 位运算 (
&、|、^、~、<<、>>) - 中断、寄存器操作
- FreeRTOS 基本 API(任务、消息队列、互斥锁)
- 了解
📖 推荐书籍:
- 《C Primer Plus》
- 《C 语言深度解剖》
- 《深入理解计算机系统》
2.2 C++ 进阶(适合高级应用)
2.2.1 面向对象编程(OOP)
1. class和struct的区别
在 C++ 中,class 和 struct 功能基本一致,唯一的区别是 默认的访问权限不同:
struct默认是 public。class默认是*private。
2. 继承 (public、private、protected)
C++ 支持 继承,即子类可以复用父类的代码。
继承方式:
class Parent {
public:
int a;
protected:
int b;
private:
int c;
};
// public 继承:保留原来的访问权限
class Child1 : public Parent {
// a 仍然是 public
// b 仍然是 protected
// c 无法访问
};
// protected 继承:public 变成 protected
class Child2 : protected Parent {
// a 变成 protected
// b 仍然是 protected
// c 无法访问
};
// private 继承:public/protected 变成 private
class Child3 : private Parent {
// a 变成 private
// b 变成 private
// c 无法访问
};
实际开发中,99% 的情况用 public 继承,让子类继续使用父类的成员。
3. 多态(虚函数 virtual)
多态允许我们用 同一接口调用不同的函数,实现 动态绑定(运行时决定调用哪个函数)。
示例:
#include <iostream>
using namespace std;
class Animal {
public:
virtual void makeSound() { // `virtual` 关键字实现多态
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override { // override 关键字可选,防止拼写错误
cout << "Bark" << endl;
}
};
int main() {
Animal* a = new Dog(); // 父类指针指向子类对象
a->makeSound(); // 输出 "Bark"
delete a;
}
使用 virtual 关键字可以让 makeSound() 在运行时决定调用子类的方法,而不是父类的方法。
2.2.2标准库(STL)
1. 容器vector、list、map
| 容器 | 说明 | 适用场景 |
|---|---|---|
vector | 动态数组 | 适合随机访问,增删慢 |
list | 双向链表 | 适合频繁插入删除 |
map | 键值对 | 适合快速查找 |
(1)vector(动态数组)
#include <vector>
using namespace std;
int main() {
vector<int> v = {1, 2, 3};
v.push_back(4); // 添加元素
v.pop_back(); // 删除最后一个元素
cout << "第一个元素: " << v[0] << endl;
for (int num : v) {
cout << num << " ";
}
return 0;
}
vector 适合随机访问,但插入删除效率较低。
(2) list(双向链表)
示例:
#include <list>
#include <iostream>
using namespace std;
int main() {
list<int> l = {1, 2, 3};
l.push_back(4); // 末尾添加
l.push_front(0); // 头部添加
l.pop_front(); // 删除头部元素
for (int num : l) {
cout << num << " ";
}
return 0;
}
list 适合插入删除,但随机访问效率低。
(3) map(键值对)
示例:
#include <map>
#include <iostream>
using namespace std;
int main() {
map<string, int> scores;
scores["Alice"] = 90;
scores["Bob"] = 85;
cout << "Alice's score: " << scores["Alice"] << endl;
for (auto& pair : scores) {
cout << pair.first << " " << pair.second << endl;
}
return 0;
}
map 适合快速查找,内部用红黑树实现。
2. 算法sort、find、copy
sort 用于排序,find 用于查找。
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {3, 1, 4, 2};
sort(v.begin(), v.end()); // 排序
cout << "排序后: ";
for (int num : v) cout << num << " ";
auto it = find(v.begin(), v.end(), 2); // 查找 2
if (it != v.end()) cout << "\n找到 2";
return 0;
}
3. 智能指针shared_ptr、unique_ptr)
在 C++ 现代开发中,智能指针用于自动管理动态分配的对象,防止 内存泄漏 和 悬空指针 问题。C++11 提供了 std::unique_ptr、std::shared_ptr 和 std::weak_ptr,它们都在 <memory> 头文件中定义。
|----------|----------|----------|
| unique_ptr | 独占所有权,不能复制 | 独占资源,如文件、线程 |
| shared_ptr | 共享所有权,引用计数 | 多对象共享资源,如缓存、线程池 |
| weak_ptr | 弱引用,不增加计数 | 防止 shared_ptr 循环引用 |
(1) std::unique_ptr(独占所有权)
unique_ptr 是 独占所有权 智能指针,意味着 一个对象只能被一个指针管理,不能共享所有权。
基本用法
#include <iostream>
#include <memory> // 智能指针库
using namespace std;
class Test {
public:
Test() { cout << "Test 构造" << endl; }
~Test() { cout << "Test 析构" << endl; }
void show() { cout << "Test::show()" << endl; }
};
int main() {
unique_ptr<Test> p1 = make_unique<Test>(); // 使用 make_unique 创建对象
p1->show();
// unique_ptr 不能被复制
// unique_ptr<Test> p2 = p1; // ❌ 错误
unique_ptr<Test> p2 = move(p1); // ✅ 需要使用 `move()` 转移所有权
if (!p1) cout << "p1 已被转移,变为空" << endl;
return 0;
}
特点:
- 不能被 复制(
unique_ptr<Test> p2 = p1;)。 - 只能 转移所有权(
move(p1))。 - 适用于 独占管理资源 的情况,如文件、网络连接等。
(2) std::shared_ptr(共享所有权)
shared_ptr 允许多个指针共享同一块资源,会 自动计数,当引用计数归零时,资源被释放。
基本用法
#include <iostream>
#include <memory>
using namespace std;
class Test {
public:
Test() { cout << "Test 构造" << endl; }
~Test() { cout << "Test 析构" << endl; }
};
int main() {
shared_ptr<Test> p1 = make_shared<Test>(); // 推荐使用 make_shared
{
shared_ptr<Test> p2 = p1; // 共享所有权
cout << "引用计数: " << p1.use_count() << endl; // 输出 2
} // p2 作用域结束,引用计数减 1
cout << "引用计数: " << p1.use_count() << endl; // 输出 1
return 0;
} // p1 作用域结束,计数归零,自动释放
特点:
- 引用计数,多个
shared_ptr共享所有权,计数为 0 时释放资源。 - 适用于 多个对象需要共享资源,如 缓存管理、线程池。
(3) std::weak_ptr(弱引用,防止循环引用)
weak_ptr 是 弱引用,它不会增加引用计数,主要用于 防止 shared_ptr 循环引用(即 A 指向 B,B 指向 A,导致资源无法释放)。
循环引用问题
#include <iostream>
#include <memory>
using namespace std;
class B;
class A {
public:
shared_ptr<B> ptrB;
~A() { cout << "A 析构" << endl; }
};
class B {
public:
shared_ptr<A> ptrA;
~B() { cout << "B 析构" << endl; }
};
int main() {
shared_ptr<A> a = make_shared<A>();
shared_ptr<B> b = make_shared<B>();
a->ptrB = b; // A 持有 B
b->ptrA = a; // B 持有 A(循环引用)
return 0; // A 和 B 都不会被释放,造成 **内存泄漏**
}
解决方案:使用 weak_ptr 代替 shared_ptr
class B;
class A {
public:
weak_ptr<B> ptrB; // 改为 weak_ptr
~A() { cout << "A 析构" << endl; }
};
class B {
public:
shared_ptr<A> ptrA;
~B() { cout << "B 析构" << endl; }
};
特点:
- 不会增加引用计数,用于解决
shared_ptr循环引用 问题。 - 需要 先转换为
shared_ptr才能访问资源:
if (auto sp = weak_ptr_instance.lock()) {
// 使用 sp 访问对象
}
(4) make_unique vs make_shared
C++ 推荐使用 make_unique<T>() 和 make_shared<T>() 来创建智能指针对象。
| 智能指针 | 主要特性 | 适用场景 |
|---|---|---|
unique_ptr | 独占所有权,不能复制 | 独占资源,如文件、线程 |
shared_ptr | 共享所有权,引用计数 | 多对象共享资源,如缓存、线程池 |
weak_ptr | 弱引用,不增加计数 | 防止 shared_ptr 循环引用 |
示例
auto p1 = make_unique<int>(10); // 推荐
auto p2 = make_shared<int>(20); // 推荐
相比 shared_ptr<int> p2(new int(20)),make_shared 只分配一次内存,效率更高。
2.2.3 模板与泛型
(1)函数模板
示例:
#include <iostream>
using namespace std;
template <typename T> // 定义模板
T add(T a, T b) {
return a + b;
}
int main() {
cout << add(2, 3) << endl; // 处理 int
cout << add(2.5, 3.5) << endl; // 处理 double
return 0;
}
add<T>() 函数可以处理 int、double 等不同类型。
(2)类模板
示例:
#include <iostream>
using namespace std;
template <typename T>
class Box {
public:
T value;
Box(T val) : value(val) {}
void show() { cout << "Value: " << value << endl; }
};
int main() {
Box<int> intBox(10);
intBox.show();
Box<double> doubleBox(5.5);
doubleBox.show();
return 0;
}
类模板让 Box<T> 适用于不同的数据类型。
📖 推荐书籍:
- 《C++ Primer》
- 《Effective C++》
- 《STL 源码剖析》

被折叠的 条评论
为什么被折叠?



