巨集定義黑魔法

2021-10-11 19:10:18 字數 2702 閱讀 1024

1、

#define clr_red         "\033[31m"      /* 紅色字 */

#define clr_green "\033[32m" /* 綠色字 */

#define clr_yellow "\033[33m" /* 黃色字 */

#define clr_blue "\033[34m" /* 藍色字 */

#define clr_purple "\033[35m" /* 紫色字 */

#define clr_skyblue "\033[36m" /* 天藍字 */

#define clr_white "\033[37m" /* 白色字 */

#define clr_blk_wht "\033[40;37m" /* 黑底白字 */

#define clr_red_wht "\033[41;37m" /* 紅底白字 */

#define log_level_map(***) \

***(log_level_debug, "debug", clr_white) \

***(log_level_info, "info ", clr_green) \

***(log_level_warn, "warn ", clr_yellow) \

***(log_level_error, "error", clr_red) \

***(log_level_fatal, "fatal", clr_red_wht)

typedef enum log_level_e;

這個巨集的作用是在日誌中,對不同級別的日誌,選擇不同的顏色列印。上面的是表示顏色的巨集,很簡單。 關鍵是下面的log_level_map,這個巨集可以說是乙個二級巨集,不知道有沒有這個概念,因為它後面括號裡的內容,也是乙個巨集。看下面的用法,在log_level_map巨集的下面定義了乙個列舉,這個列舉表示告警的級別。在這個列舉的中,定義了另乙個巨集。先把log_level_map(***)的第一層巨集展開,是這樣的:

typedef enum  log_level_e;
這裡為了看起來方便,把裡面的巨集定義取掉了。展開第一層後,***還是乙個巨集,在enum中定義的該巨集,所以需要繼續展開,根據第一段**中的巨集定義,展開後是這樣的:

typedef enum  log_level_e;
這樣看起來就簡單多了,但這還不是全部。。。

第二個使用該巨集的地方:

const char* pcolor = "";

const char* plevel = "";

#define ***(id, str, clr) \

case id: plevel = str; pcolor = clr; break;

switch (level)

#undef ***

第一層展開後跟上面的是一樣的,主要就是第二層,這裡直接展開第二層:

switch (level)
是不是很簡單了,就是根據日誌級別,設定相應的資訊。當然,上面所有的巨集展開實際上都在一行,只不過我為了看起來簡單,分了行。

2、使用巨集實現類似於c++中容器的功能

在array.h和queue.h中,使用巨集定義實現了類似於vector和deque的功能。因為這兩個功能的實現方式差不多,而且理解起來很簡單,就不貼介面了,只看看結構體。

#define array_decl(type, atype) \

struct atype ; \

typedef struct atype atype;\

type就是容器中元素的型別,atype就是這個容器的型別。舉個程式中使用例子

array_decl(struct epoll_event, events)
這樣就定義了乙個容器,容器型別為events,成員型別為struct epoll_event,展開就是

struct events ;
功能挺強大,但理解起來挺簡單。當然了,比起c++標準庫的容器,用起來肯定還是麻煩一些。

3、使用巨集實現類似c++繼承的功能

#define htimer_fields                   \

hevent_fields \

uint32_t repeat; \

uint64_t next_timeout; \

struct heap_node node;

struct htimer_s ;

struct htimeout_s ;

struct hperiod_s ;

htimer_s、htimeout_s和hperiod_s都包含htimer_fields,就相當於這三個結構體「繼承」了同乙個「基類」,擁有共同的一些成員。但是我個人不喜歡這種方式,我寧願將該「基類」實現為乙個結構體,然後作為其他三個結構體的內部成員。我覺得使用」基類結構體「的方式比使用巨集更具意義,也更可讀。

先寫這麼多吧。。。

Swizzling 偷梁換柱的黑魔法!

我們知道,oc是一門動態執行時語言。我們也知道,oc中的函式呼叫本質上其實是訊息的傳送 objc msgsend someobject,selector methodname parameters 所有要呼叫的函式,編譯階段是無法確定的,只有到執行的時候才能確定!正因為有此特性,所以在執行階段,我們...

黑魔法 iOS鏈式程式設計

在使用sdautolayout 時就已經發現這種鏈式程式設計。通過 將屬性鏈結在一起形成如同一條鏈的程式設計方法。self.totalmoneycount sd layout.leftequaltoview self rightequaltoview self topspacetoview self...

Python黑魔法 元類

python黑魔法 元類 術語 元程式設計 指的是程式具有編寫或操縱其自身作為它們資料的潛力。python支援稱為元類的類的元程式設計。元類是乙個深奧的物件導向程式設計 oop 概念,隱藏在幾乎所有的python 之後。無論你是否意識到它的存在,你都一直在使用它們。大多數情況下,你並不需要了解它。而...