嵌入式系统中的C++
1. 简介
嵌入式系统是指嵌入到其他设备中的计算机系统,通常用于控制、监控或执行特定任务。C++ 是一种强大的编程语言,广泛应用于嵌入式系统开发中。本教程将带你了解如何在嵌入式系统中使用C++,从基础知识到高级应用。
2. 环境搭建
2.1 编译器选择和安装
在嵌入式系统开发中,常用的编译器有 GCC 和 ARM GCC。以下是安装步骤:
-
GCC 安装:
sudo apt-get update sudo apt-get install build-essential -
ARM GCC 安装:
sudo apt-get install gcc-arm-none-eabi
2.2 创建第一个C++程序 (Hello World)
创建一个简单的C++程序,输出 "Hello, World!":
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
编译并运行:
g++ -o hello_world hello_world.cpp
./hello_world
3. 基本语法和数据类型
3.1 基本语法
C++ 的基本语法包括变量声明、函数定义、控制流等。
3.2 数据类型
C++ 支持多种数据类型,如 int, float, double, char, bool 等。
int age = 25;
float height = 1.75;
char initial = 'J';
bool isStudent = true;
4. 变量、常量和运算符
4.1 变量
变量用于存储数据,可以随时更改。
int count = 10;
count = 20; // 变量值可以更改
4.2 常量
常量是不可更改的值。
const int MAX_VALUE = 100;
4.3 运算符
C++ 支持多种运算符,如算术运算符、关系运算符、逻辑运算符等。
int a = 10, b = 20;
int sum = a + b; // 算术运算符
bool isEqual = (a == b); // 关系运算符
bool isTrue = (a < b) && (a != 0); // 逻辑运算符
5. 函数和函数重载
5.1 函数
函数是执行特定任务的代码块。
int add(int a, int b) {
return a + b;
}
5.2 函数重载
函数重载允许定义多个同名函数,但参数类型或数量不同。
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
6. 控制流
6.1 if-else
int number = 10;
if (number > 0) {
std::cout << "Positive number" << std::endl;
} else {
std::cout << "Non-positive number" << std::endl;
}
6.2 switch
int day = 3;
switch (day) {
case 1:
std::cout << "Monday";
break;
case 2:
std::cout << "Tuesday";
break;
default:
std::cout << "Other day";
}
6.3 for 循环
for (int i = 0; i < 5; i++) {
std::cout << i << std::endl;
}
6.4 while 循环
int i = 0;
while (i < 5) {
std::cout << i << std::endl;
i++;
}
7. 数组和字符串
7.1 数组
数组是存储相同类型数据的集合。
int numbers[5] = {1, 2, 3, 4, 5};
7.2 字符串
C++ 中的字符串可以使用 std::string 类。
#include <string>
std::string name = "John";
8. 指针和引用
8.1 指针
指针存储变量的内存地址。
int value = 10;
int* ptr = &value;
8.2 引用
引用是变量的别名。
int value = 10;
int& ref = value;
9. 结构体和类
9.1 结构体
结构体是一种用户定义的数据类型。
struct Point {
int x;
int y;
};
9.2 类
类是面向对象编程的基础。
class Rectangle {
public:
int width, height;
int area() {
return width * height;
}
};
10. 类和对象
10.1 类
类是对象的蓝图。
class Circle {
public:
double radius;
double area() {
return 3.14159 * radius * radius;
}
};
10.2 对象
对象是类的实例。
Circle c;
c.radius = 5.0;
std::cout << "Area: " << c.area() << std::endl;
11. 封装、继承和多态
11.1 封装
封装隐藏了类的内部细节。
class Employee {
private:
int salary;
public:
void setSalary(int s) {
salary = s;
}
int getSalary() {
return salary;
}
};
11.2 继承
继承允许创建新类继承现有类的特性。
class Manager : public Employee {
public:
void setBonus(int b) {
setSalary(getSalary() + b);
}
};
11.3 多态
多态允许不同类的对象使用相同的接口。
class Animal {
public:
virtual void makeSound() {
std::cout << "Animal sound" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
std::cout << "Woof!" << std::endl;
}
};
12. 构造函数和析构函数
12.1 构造函数
构造函数在对象创建时自动调用。
class Point {
public:
int x, y;
Point(int x, int y) : x(x), y(y) {}
};
12.2 析构函数
析构函数在对象销毁时自动调用。
class Point {
public:
~Point() {
std::cout << "Point destroyed" << std::endl;
}
};
13. 虚函数和抽象类
13.1 虚函数
虚函数允许派生类重写基类的方法。
class Shape {
public:
virtual void draw() {
std::cout << "Drawing shape" << std::endl;
}
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing circle" << std::endl;
}
};
13.2 抽象类
抽象类不能实例化,只能作为基类。
class Shape {
public:
virtual void draw() = 0; // 纯虚函数
};
14. 运算符重载
运算符重载允许自定义运算符的行为。
class Point {
public:
int x, y;
Point operator+(const Point& p) {
return Point(x + p.x, y + p.y);
}
};
15. 模板和泛型编程
15.1 模板
模板允许编写通用代码。
template <typename T>
T add(T a, T b) {
return a + b;
}
15.2 泛型编程
泛型编程使用模板实现通用算法。
template <typename T>
void printArray(T arr[], int size) {
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
16. 异常处理
异常处理用于处理程序中的错误。
try {
int x = 10, y = 0;
if (y == 0) {
throw "Division by zero";
}
int result = x / y;
} catch (const char* msg) {
std::cerr << msg << std::endl;
}
17. 命名空间
命名空间用于避免命名冲突。
namespace MyNamespace {
int value = 10;
}
int main() {
std::cout << MyNamespace::value << std::endl;
return 0;
}
18. 智能指针
智能指针自动管理内存,防止内存泄漏。
#include <memory>
std::unique_ptr<int> ptr(new int(10));
std::shared_ptr<int> sharedPtr = std::make_shared<int>(20);
19. Lambda 表达式
Lambda 表达式是匿名函数。
auto add = [](int a, int b) { return a + b; };
std::cout << add(10, 20) << std::endl;
20. 输入输出流 (iostream)
输入输出流用于处理输入输出操作。
#include <iostream>
int main() {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
std::cout << "You entered: " << number << std::endl;
return 0;
}
21. 容器 (vector, list, map)
容器用于存储和管理数据集合。
#include <vector>
#include <list>
#include <map>
std::vector<int> vec = {1, 2, 3};
std::list<int> lst = {4, 5, 6};
std::map<std::string, int> mp = {{"one", 1}, {"two", 2}};
22. 算法库
算法库提供常用算法。
#include <algorithm>
#include <vector>
std::vector<int> vec = {3, 1, 4, 1, 5};
std::sort(vec.begin(), vec.end());
23. 字符串处理 (string)
字符串处理常用函数。
#include <string>
std::string str = "Hello";
str += " World";
std::cout << str << std::endl;
24. 多线程支持 (thread)
多线程用于并发执行任务。
#include <thread>
#include <iostream>
void printMessage() {
std::cout << "Hello from thread" << std::endl;
}
int main() {
std::thread t(printMessage);
t.join();
return 0;
}
25. 动态内存分配 (new 和 delete)
动态内存分配用于在运行时分配内存。
int* ptr = new int(10);
delete ptr;
26. 内存泄漏和调试技巧
内存泄漏是指分配的内存未释放。
int* ptr = new int[100];
// 忘记释放内存
调试技巧包括使用 valgrind 等工具。
27. 智能指针详解 (unique_ptr, shared_ptr, weak_ptr)
智能指针自动管理内存。
std::unique_ptr<int> uniquePtr(new int(10));
std::shared_ptr<int> sharedPtr = std::make_shared<int>(20);
std::weak_ptr<int> weakPtr = sharedPtr;
28. 自定义内存分配器
自定义内存分配器用于优化内存管理。
template <typename T>
class MyAllocator {
public:
T* allocate(size_t n) {
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
::operator delete(p);
}
};
29. C++11/14/17/20 新特性概览
C++ 标准不断更新,引入新特性。
// C++11 特性
auto value = 10;
// C++14 特性
auto lambda = [](auto a, auto b) { return a + b; };
// C++17 特性
std::optional<int> opt = 10;
// C++20 特性
std::ranges::sort(vec);
30. 移动语义和右值引用
移动语义用于优化资源管理。
class MyClass {
public:
MyClass() = default;
MyClass(MyClass&&) = default; // 移动构造函数
};
31. auto 和 decltype
auto 和 decltype 用于类型推导。
auto value = 10;
decltype(value) anotherValue = 20;
32. 范围for循环
范围for循环简化遍历容器。
std::vector<int> vec = {1, 2, 3};
for (int value : vec) {
std::cout << value << std::endl;
}
33. 初始化列表
初始化列表用于初始化对象。
class Point {
public:
int x, y;
Point(int x, int y) : x(x), y(y) {}
};
34. 常用设计模式在C++中的实现
设计模式是解决常见问题的最佳实践。
// 单例模式
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
private:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
35. SOLID原则
SOLID原则是面向对象设计的指导原则。
- 单一职责原则:一个类只负责一个功能。
- 开放封闭原则:类应开放扩展,封闭修改。
- 里氏替换原则:派生类应能替换基类。
- 接口隔离原则:接口应小而专。
- 依赖倒置原则:依赖抽象,不依赖具体。
36. 代码重构技巧
代码重构用于改进代码质量。
// 重构前
void processData(int data) {
if (data > 0) {
// 处理正数
} else {
// 处理负数
}
}
// 重构后
void processPositiveData(int data) {
// 处理正数
}
void processNegativeData(int data) {
// 处理负数
}
void processData(int data) {
if (data > 0) {