好久沒開文章了,有點手生,小伙伴們周末好,今天給大家分享一下宏定義,原本以為是很簡單的小知識點,最近在別人的構架里發現看不懂了,發現了新大陸,必須拿來分享一下,首先來一下我們經常用到的宏定義,經常把常數定義成一個宏,如下:
#define MY_FIRST_MACRO 1 //(非常簡單吧)
接下來看看最近我在分析QF框架時的境遇吧,對于QF來講,因為他要做時間管理,所以需要一個QF_tick()處理,隨便打開了一個bsp.c如下:
第一眼看上去他應該是函數吧,我們跟進去看一下定義是啥:
我的天,他居然是一個宏,他居然不大寫。。。看一下后面大寫的那個家伙:
他居然是個函數,注意他居然是個全大寫的函數,驚不驚喜意不意外,接下來我們作者為啥要這么干。
假如你一直都是些單片機軟件,你可能會非常的迷糊,為啥要搞得這么復雜的宏,這里直接告訴你答案,因為要移植,移植,移植,到不同的硬件平臺上去,作者寫的構架是一個通用的產物,那么不光單片機能用,PC(Linux、windows)都要能用,才是他的目的。
假如換了多年前的我,我會想那么一個平臺一個bsp包多么簡單,不用那么復雜的宏進行替換,一眼到底多清爽,十幾個平臺就會有十幾個包,修改一點配置也要多一個包,他最終會膨脹到你無法想象的數量,所以兼容這個事情雖然難,也必須要做。
接下來我們總結一下宏,定義一個宏的目的,并不是讓你知道他是一個常量或者是一個函數、一段代碼,只是通過一個別名告訴你這段代碼是干什么用的,他的初衷并不是希望你單步跟進去看看是怎么實現的,而是讓你對這段代碼整體的功能有個大體的理解。
宏不一定非要大寫,函數也不一定非要小寫,有些特殊的場景,我們需要忘掉那些腦袋中那些常規的套路。
也就是說一個宏,可以是一個常量,一段代碼或者一個函數等等。第二點,宏定義用的是#define進行定義,也就是說宏定義是一個預處理命令,他最終會在真正的編譯之前幫你配置出真正需要編譯的代碼,那個唯一配置的包。
最終作者希望達到的效果是,不管你有多少款板子,多少種配置,基于一個通用的SDK源碼包,通過簡單的宏定義命令就可以組織出一個你想要的工程。