一、面向对象编程(OOP)
尽管 C 语言并非面向对象编程语言,但借助一些编程技巧,也能实现面向对象编程(OOP)的核心特性,如封装、继承和多态。

1.1 封装
封装是把数据和操作数据的函数捆绑在一起,对外部隐藏内部实现细节。在嵌入式 C 语言中,可通过结构体和函数指针来实现封装。
#include <stdio.h>
// 定义一个LED结构体
typedef struct {
int pin;
void (*turnOn)(struct LED*);
void (*turnOff)(struct LED*);
} LED;
// 实现LED开启函数
void ledTurnOn(LED* led){
printf("LED on pin %d is turned on.\n", led->pin);
}
// 实现LED关闭函数
void ledTurnOff(LED* led){
printf("LED on pin %d is turned off.\n", led->pin);
}
// 初始化LED
void ledInit(LED* led, int pin){
led->pin = pin;
led->turnOn = ledTurnOn;
led->turnOff = ledTurnOff;
}
int main(void){
LED myLed;
ledInit(&myLed, 13);
myLed.turnOn(&myLed);
myLed.turnOff(&myLed);
return0;
}

LED结构体封装了pin数据和turnOn、turnOff函数指针。ledInit函数用于初始化LED结构体,把具体的函数赋值给函数指针。外部代码仅能通过这些函数指针来操作LED,而无需了解内部实现细节。
1.2 继承
继承是指一个对象直接使用另一对象的属性和方法。在嵌入式 C 语言中,可通过结构体嵌套实现继承。
#include <stdio.h>
// 定义一个基类结构体
typedef struct {
int id;
void (*printInfo)(struct Base*);
} Base;
// 实现基类的打印信息函数
voidbasePrintInfo(Base* base){
printf("Base ID: %d\n", base->id);
}
// 定义一个派生类结构体
typedef struct {
Base base; // 继承Base结构体
char* name;
} Derived;
// 实现派生类的打印信息函数
void derivedPrintInfo(Derived* derived){
basePrintInfo(&derived->base);
printf("Derived Name: %s\n", derived->name);
}
// 初始化基类
void baseInit(Base* base, int id){
base->id = id;
base->printInfo = basePrintInfo;
}
// 初始化派生类
void derivedInit(Derived* derived, int id, char* name){
baseInit(&derived->base, id);
derived->name = name;
derived->base.printInfo = (void (*)(Base*))derivedPrintInfo;
}
int main(void){
Derived myDerived;
derivedInit(&myDerived, 1, "Derived Object");
myDerived.base.printInfo((Base*)&myDerived);
return0;
}

1.3 多态
多态是指不同对象对同一消息做出不同响应。在嵌入式 C 语言中,可通过函数指针实现多态。
#include <stdio.h>
// 定义一个基类结构体
typedef struct {
void (*operation)(struct Base*);
} Base;
// 定义一个派生类1结构体
typedef struct {
Base base;
} Derived1;
// 定义一个派生类2结构体
typedef struct {
Base base;
} Derived2;
// 派生类1的操作函数
void derived1Operation(Base* base){
printf("Derived1 operation.\n");
}
// 派生类2的操作函数
void derived2Operation(Base* base){
printf("Derived2 operation.\n");
}
// 初始化派生类1
void derived1Init(Derived1* derived1){
derived1->base.operation = derived1Operation;
}
// 初始化派生类2
void derived2Init(Derived2* derived2){
derived2->base.operation = derived2Operation;
}
// 执行操作
void performOperation(Base* base){
base->operation(base);
}
int main(void){
Derived1 myDerived1;
Derived2 myDerived2;
derived1Init(&myDerived1);
derived2Init(&myDerived2);
performOperation((Base*)&myDerived1);
performOperation((Base*)&myDerived2);
return0;
}

Base结构体包含一个函数指针operation。Derived1和Derived2结构体继承了Base结构体,并分别实现了自己的operation函数。performOperation函数接收一个Base指针,依据具体对象调用相应的operation函数,从而实现了多态。
二、测试驱动开发(TDD)
测试驱动开发(Test-Driven Development,TDD)是一种软件开发方法论,它强调在编写实际功能代码之前先编写测试代码。
TDD 的核心流程遵循 "红 - 绿 - 重构" 循环,下面将详细介绍其原理、流程、优势、局限性以及示例。