一、面向對象編程(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 的核心流程遵循 “紅 - 綠 - 重構” 循環,下面將詳細介紹其原理、流程、優勢、局限性以及示例。
點擊嵌入式C語言高級編程:OOP封裝、TDD測試與防御性編程實踐 查看全文