C和C++的区别


前言

提示:这里可以添加本文要记录的大概内容:

C和C++的区别介绍


一、C 语言和 C++ 哪个更容易学?

C 语言比 C++ 更简单,更容易入门
但如果涉及 大规模项目、面向对象编程(OOP)、复杂数据结构,C++ 提供的功能更多,代码可维护性更强,但 学习曲线更陡

对于嵌入式开发(如你正在做的 ZYNQ、RTOS、驱动开发),C 语言更常用,C++ 主要用于高层应用(如 GUI、AI 计算)。


C 语言和 C++ 的主要区别

对比点C 语言C++ 语言
编程范式过程化编程(Procedural)支持面向对象(OOP)+ 过程化
内存管理需要手动 malloc/freenew/delete(支持 RAII)
数据封装主要使用 struct支持 classstruct
函数和变量只支持普通函数支持函数重载、模板、命名空间
代码复用主要靠函数和结构体支持继承、多态、模板
标准库标准库较小STL(标准模板库)强大
适用场景嵌入式、驱动、系统级开发桌面软件、游戏、GUI、AI

嵌入式/底层开发(MCU、Linux 内核、RTOS)→ C 更合适
应用层开发(GUI、AI、算法、游戏)→ C++ 更强大


二、学习方法和路径

2.1 掌握 C 语言(适合嵌入式、RTOS)

  1. 基础语法

    • 变量、数据类型 (intcharfloatdouble
    • 条件判断 (ifswitch-case
    • 循环 (forwhiledo-while
  2. 指针和内存管理

    • 指针 (*&,数组与指针的关系)
    • malloc/free 的动态内存管理
    • 结构体 (struct)、共用体 (union)
  3. 嵌入式相关

    • 了解 volatileconst
    • 位运算 (&|^~<<>>)
    • 中断、寄存器操作
    • FreeRTOS 基本 API(任务、消息队列、互斥锁)

📖 推荐书籍

  • 《C Primer Plus》
  • 《C 语言深度解剖》
  • 《深入理解计算机系统》

2.2 C++ 进阶(适合高级应用)

2.2.1 面向对象编程(OOP)

1. class和struct的区别

在 C++ 中,classstruct 功能基本一致,唯一的区别是 默认的访问权限不同

  • struct 默认是 public。
  • class 默认是*private。
2. 继承 (publicprivateprotected)

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. 容器vectorlistmap
容器说明适用场景
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. 算法sortfindcopy

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_ptrunique_ptr

在 C++ 现代开发中,智能指针用于自动管理动态分配的对象,防止 内存泄漏悬空指针 问题。C++11 提供了 std::unique_ptrstd::shared_ptrstd::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>() 函数可以处理 intdouble 等不同类型


(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 源码剖析》

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值