成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

【PHP源碼學(xué)習(xí)】2019-03-26 宏定義筆記

SKYZACK / 1880人閱讀

摘要:并且在我們?nèi)粘5拇a學(xué)習(xí)中,我們會(huì)碰到過(guò)很多很多的宏定義。如果宏定義中帶有參數(shù),而代碼中出現(xiàn)同樣標(biāo)識(shí)時(shí)沒(méi)有參數(shù),不視為宏。具體的解析見(jiàn)源碼學(xué)習(xí)內(nèi)存管理筆記。

grape

全部視頻:https://segmentfault.com/a/11...

原視頻地址:http://replay.xesv5.com/ll/24...

引入

我們知道宏定義的優(yōu)點(diǎn)有方便程序的修改,提高程序運(yùn)行效率等等。并且在我們?nèi)粘5拇a學(xué)習(xí)中,我們會(huì)碰到過(guò)很多很多的宏定義。針對(duì)這些宏定義,我們通常都是秉承著“宏即是替換”的“法則”來(lái)進(jìn)行分析。然而,對(duì)于一些簡(jiǎn)單的宏定義來(lái)說(shuō),我們直接進(jìn)行替換即可完美的解決問(wèn)題,但是針對(duì)于一些復(fù)雜的宏定義來(lái)說(shuō),我們會(huì)發(fā)現(xiàn),替換也是有些門(mén)道的。那么,我們今天就來(lái)探索一下宏定義的神奇吧。

宏的基礎(chǔ)知識(shí) 一、宏替換基礎(chǔ)知識(shí):

#define 宏名 字符串
#define 宏名(形參列表) 字符串
允許宏帶有參數(shù),在宏定義中的參數(shù)稱(chēng)為形式參數(shù),在宏調(diào)用中的參數(shù)稱(chēng)為實(shí)際參數(shù)

二、C宏展開(kāi)的幾個(gè)注意事項(xiàng):

每次宏展開(kāi)的結(jié)果會(huì)被重復(fù)掃描,知道沒(méi)有任何可展開(kāi)的宏為止。

每展開(kāi)一個(gè)宏,都會(huì)記住這次展開(kāi),在這個(gè)宏展開(kāi)的結(jié)果及其后續(xù)展開(kāi)中,不再對(duì)相同的宏做展開(kāi)。

帶參數(shù)的宏,先對(duì)參數(shù)做展開(kāi),除非定義體中包含#或##

a. "#"表示將后續(xù)標(biāo)識(shí)轉(zhuǎn)化為字符串。
b. "##"標(biāo)識(shí)將兩個(gè)標(biāo)識(shí)連接成一個(gè)標(biāo)識(shí)符。
c. 注意參數(shù)展開(kāi)的結(jié)果中即使有逗號(hào),也不要視為參數(shù)的分隔符。

如果宏定義中帶有參數(shù),而代碼中出現(xiàn)同樣標(biāo)識(shí)時(shí)沒(méi)有參數(shù),不視為宏。

示例

首先我們看一個(gè)最簡(jiǎn)單的替換:

#include 

#define foo(bar) bar

int main()
{
   printf("%s
",foo("grape")); 
    return 0;
}

結(jié)果相信大家一眼就可以看出來(lái),是的輸出“grape”,如圖所示:

對(duì)應(yīng)于注意事項(xiàng)中的的一項(xiàng),展開(kāi)所有的宏,我們來(lái)看這樣一個(gè)代碼:

#include 

#define foo(bar) bar1
#define bar1 "hello"
int main()
{
   printf("%s
",foo("grape")); 
    return 0;
}

結(jié)果是什么呢?
好的,結(jié)果和大家想的一樣,就是hello,如圖所示:

繼續(xù),對(duì)于第二個(gè)注意事項(xiàng),首先我們分析一下這個(gè)事項(xiàng)是為什么。相信大家都知道遞歸,倘若一個(gè)遞歸沒(méi)有結(jié)束條件會(huì)怎么樣,結(jié)果肯定是無(wú)限的執(zhí)行下去,如果,我們的宏定義也會(huì)出現(xiàn)這個(gè)情況,那。。。讀者自行腦補(bǔ)吧。基于這個(gè)場(chǎng)景我們來(lái)看看這第二條規(guī)則,我們看一下這種情況,當(dāng)然為了簡(jiǎn)單,這段代碼是不可執(zhí)行的:

#define foo foo bar

我們來(lái)看這個(gè)foo的定義,如果我們不知道這項(xiàng)規(guī)則,這段代碼被我們來(lái)解析,按照替換來(lái)講,我們是不是會(huì)認(rèn)為是"... bar bar foo ..."這樣子?然而真實(shí)的情況是這樣子的:

foo
//|->foo bar
//|  |~    |->bar bar foo
//|  |-> foo bar bar foo (至此展開(kāi)完畢)

所以,同一個(gè)宏定義是不可循環(huán)展開(kāi)的。

對(duì)于#和##的注意,在我們的日常代碼學(xué)習(xí)中,我們很少遇見(jiàn)#和##,所以相信大家對(duì)此都十分陌生,現(xiàn)在讓我們來(lái)看看它究竟有什么作用。見(jiàn)代碼:

#include 
  
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)

int main()
{
    printf("%s
",h(f(1,2))); //result1
    printf("%s
",g(f(1,2))); //result2
    return 0;
}

大家可以先看一下代碼,考慮一下result1和result2會(huì)輸出什么?
結(jié)果如圖所示:

然后我們可以想一下,如果沒(méi)有#和##會(huì)輸出?

#include 
  
#define f(a,b) b
#define g(a) a
#define h(a) g(a)

int main()
{
    printf("%d
",f(1,2));
    printf("%d
",h(f(1,2)));
    printf("%d
",g(f(1,2)));
    return 0;
}

結(jié)果如圖所示:

對(duì)比兩者我們會(huì)發(fā)現(xiàn)#和##的作用。即帶參數(shù)的宏執(zhí)行時(shí),我們通常先對(duì)參數(shù)的宏進(jìn)行展開(kāi),但是,在參數(shù)的宏中擁有#或者##的時(shí)候,會(huì)最后才進(jìn)行展開(kāi)。

第四點(diǎn)注意事項(xiàng),就會(huì)很容易理解,舉個(gè)例子,聲明一個(gè)有入?yún)⒌暮瘮?shù),如果你只去調(diào)用函數(shù)名會(huì)出現(xiàn)什么問(wèn)題?當(dāng)然,還有另外一種情況,例如:

#define _BIN_DATA_SIZE(num, size, elements, pages, x, y) size,
static const uint32_t bin_data_size[] = {
  ZEND_MM_BINS_INFO(_BIN_DATA_SIZE, x, y)
};
#define ZEND_MM_BINS_INFO(_, x, y) 
    _( 0,    8,  512, 1, x, y) 
    _( 1,   16,  256, 1, x, y) 
    _( 2,   24,  170, 1, x, y) 
    _( 3,   32,  128, 1, x, y) 
    _( 4,   40,  102, 1, x, y) 
    _( 5,   48,   85, 1, x, y) 
    _( 6,   56,   73, 1, x, y) 
    _( 7,   64,   64, 1, x, y) 
    _( 8,   80,   51, 1, x, y) 
    _( 9,   96,   42, 1, x, y) 
    _(10,  112,   36, 1, x, y) 
    _(11,  128,   32, 1, x, y) 
    _(12,  160,   25, 1, x, y) 
    _(13,  192,   21, 1, x, y) 
    _(14,  224,   18, 1, x, y) 
    _(15,  256,   16, 1, x, y) 
    _(16,  320,   64, 5, x, y) 
    _(17,  384,   32, 3, x, y) 
    _(18,  448,    9, 1, x, y) 
    _(19,  512,    8, 1, x, y) 
    _(20,  640,   32, 5, x, y) 
    _(21,  768,   16, 3, x, y) 
    _(22,  896,    9, 2, x, y) 
    _(23, 1024,    8, 2, x, y) 
    _(24, 1280,   16, 5, x, y) 
    _(25, 1536,    8, 3, x, y) 
    _(26, 1792,   16, 7, x, y) 
    _(27, 2048,    8, 4, x, y) 
    _(28, 2560,    8, 5, x, y) 
    _(29, 3072,    4, 3, x, y)

我們?cè)诘谝淮慰吹絖BIN_DATA_SIZE只認(rèn)為是一個(gè)形量傳入到函數(shù)中,沒(méi)有做宏替換,在_替換之后會(huì)被掃描到重新做替換。具體的解析見(jiàn)【PHP源碼學(xué)習(xí)】2019-03-11 PHP內(nèi)存管理3筆記。

結(jié)尾

在我們的工作或者學(xué)習(xí)中,會(huì)出現(xiàn)很多復(fù)雜的宏替換,只要我們認(rèn)定“宏即是替換”以及記住以上注意事項(xiàng),那么一切復(fù)雜宏替換都是紙老虎。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/31519.html

相關(guān)文章

  • 【LNMPR源碼學(xué)習(xí)筆記匯總

    摘要:此文用于匯總跟隨陳雷老師及團(tuán)隊(duì)的視頻,學(xué)習(xí)源碼過(guò)程中的思考整理與心得體會(huì),此文會(huì)不斷更新視頻傳送門(mén)每日學(xué)習(xí)記錄使用錄像設(shè)備記錄每天的學(xué)習(xí)源碼學(xué)習(xí)源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)基本變量筆記 此文用于匯總跟隨陳雷老師及團(tuán)隊(duì)的視頻,學(xué)習(xí)源碼過(guò)程中的思考、整理與心得體會(huì),此文會(huì)不斷更新 視頻傳送門(mén):【每日學(xué)習(xí)記錄】使用錄像設(shè)備記錄每天的學(xué)習(xí) PHP7...

    Barrior 評(píng)論0 收藏0
  • PHP源碼學(xué)習(xí)2019-03-11 PHP內(nèi)存管理3筆記

    摘要:那么問(wèn)題來(lái)了,為什么要把如此簡(jiǎn)單的一個(gè)數(shù)組初始化問(wèn)題復(fù)雜化這樣寫(xiě)代碼真的真的不會(huì)被別人錘嗎其實(shí)源碼中還有其他相關(guān)部分我們可以看到,源碼中提供了三個(gè)類(lèi)似的宏替換結(jié)構(gòu)。 baiyan 全部視頻:https://segmentfault.com/a/11... 源視頻地址:http://replay.xesv5.com/ll/24... 復(fù)習(xí) PHP內(nèi)存分配流程 showImg(https:...

    wangjuntytl 評(píng)論0 收藏0
  • PHP源碼學(xué)習(xí)2019-03-18 復(fù)習(xí)前面的內(nèi)容

    摘要:調(diào)用函數(shù)時(shí),它將用戶(hù)釋放的內(nèi)存塊連接到空閑鏈上。這個(gè)聯(lián)合體共占用字節(jié)。是數(shù)字,且順序遞增位置固定,如訪問(wèn)是的元素,即,就直接訪問(wèn)數(shù)組的第個(gè)位置即可即,這樣就不需要前面的索引數(shù)組。 baiyan 全部視頻:https://segmentfault.com/a/11... 原視頻地址:http://replay.xesv5.com/ll/24... 本筆記中部分圖片截自視頻中的片段,圖片版...

    lindroid 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<