小記:那個(gè)宏metamacro_argcount

1. 來兩個(gè)簡(jiǎn)單的宏定義

#define metamacro_head(FIRST,..., 0) FIRST 

意義比較明顯沒難度取第一個(gè)傳入的參數(shù);如 metamacro_head("a","b","c");取值為"a"

#define metamacro_concat_(A, B) A ## B

“##” 在宏定義里面表示字符的鏈接;metamacro_concat_("test","1") 張開后為字符串"test1";所以該宏業(yè)很簡(jiǎn)單,我們知道是參數(shù)的拼接了。
用的稍微復(fù)制點(diǎn)

2. 宏的調(diào)試

我們知道從代碼到可執(zhí)行會(huì)經(jīng)歷,1.預(yù)處理替換;2.詞法分析;3.語法分析;4。IRCode生成;5.再到針對(duì)平臺(tái)的匯編; 6.生成o文件; 7.生成可執(zhí)行文件?,F(xiàn)在我們關(guān)注的是第一個(gè)步驟。這樣也能方便我們查看替換后的效果。雖然不能斷點(diǎn)調(diào)試。

- (void)viewDidLoad {
    [super viewDidLoad];
    metamacro_head("a","b","c"); 
}

2.1 預(yù)處理替換前

image.png

2.2 預(yù)處理替換后

- (void)viewDidLoad {
    [super viewDidLoad];
    "a";
}
//metamacro_head("a","b","c"); 被替換為“a”了。

3. 繼續(xù)深入

3.1 簡(jiǎn)單定義

#define metamacro_at0(...) metamacro_head(__VA_ARGS__)

metamacro_at0可以看出metamacro_head一樣。

#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)

metamacro_at1("a","b","c"); 對(duì)號(hào)入座 "a"=> _0; "b","c"=>... ; 三個(gè)點(diǎn)表示參數(shù)可以無線擴(kuò)展,"VA_ARGS"表宏定義頭的可變參數(shù)就是那三個(gè)點(diǎn);我們展開metamacro_at1("a","b","c");
宏就變成了metamacro_head("b","c");那么根據(jù)上面描述我們知道m(xù)etamacro_head是取第一個(gè)參數(shù),因此metamacro_at1("a","b","c")的值是"b"。

3.2 繼續(xù)推導(dǎo)

#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
..............
#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)

可以知道m(xù)etamacro_at + 整數(shù),整數(shù)是多少就是該宏取到第幾位參數(shù)!

3.2 抽象 “metamacro_at + 整數(shù)”

#define metamacro_at(N, ...) \
        metamacro_concat(metamacro_at, N)(__VA_ARGS__)

舉例:
metamacro_at(1,"a","b","c");我們知道m(xù)etamacro_concat為兩個(gè)產(chǎn)生拼接,那么metamacro_at(1,"a","b","c"),展開為metamacro_at1("a","b","c");那我們就知道了其結(jié)果為"b";metamacro_at2(,"a","b","c"),展開后值就是"c"了。依次類推就容易明白metamacro_at(N, ...), 是取后面可變參數(shù)"..."的第N個(gè)參數(shù)了[N從0開始計(jì)算]。
到現(xiàn)在為止我們可以獲取宏定義參數(shù)的任何為止的參數(shù)了!

4.計(jì)算宏參數(shù)個(gè)數(shù)

4.1 metamacro_argcount

也就是我們今天的主角metamacro_argcount。該宏定義為:

#define metamacro_argcount(...) \
        metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

4.2 metamacro_argcount推導(dǎo)

經(jīng)過我們上面的分析已知道曉metamacro_at的含義。

舉例:

metamacro_argcount("a","b","c")  
 =>  
metamacro_at(20, "a","b","c", 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)   
 => 
3

“3”,便是我們所傳入?yún)?shù)的個(gè)數(shù),目前該宏設(shè)計(jì)為最多能傳入20個(gè)參數(shù)。

4.3 巧妙的設(shè)計(jì):

metamacro_at19(20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:metamacro_at19表示取第19號(hào)參數(shù),第20個(gè)也就是最后一位參數(shù)1。

metamacro_at20(20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:我們有1到20總共20個(gè)參數(shù),取不到參數(shù)值,因?yàn)閙etamacro_at20取的是第20號(hào)[從0算起],第21個(gè)參數(shù)。

metamacro_at20("a",20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:metamacro_at20是取第21個(gè)參數(shù)的,現(xiàn)在我們有21個(gè)參數(shù),取到的值是多少呢?很顯然第21個(gè)參數(shù)為最后1,自己從頭開始數(shù)一數(shù);

metamacro_at20("a","b",20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:現(xiàn)在我們有22個(gè)參數(shù)而metamacro_at20是取第21個(gè)參數(shù),我們數(shù)過來就知道了結(jié)果為2;

到這里是不是恍然大悟。只要我們填的參數(shù)不超過20個(gè)就能通過metamacro_argcount宏算出所傳入的參數(shù)個(gè)數(shù)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容