99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

C語言中宏展開規(guī)則,你知多少?

1. 宏展開規(guī)則unsetunset

在C語言預(yù)處理器中,如果宏參數(shù)本身是一個(gè)宏,其展開時(shí)機(jī)遵循一定的規(guī)則。具體來說,宏參數(shù)的展開時(shí)機(jī)取決于它在宏定義中的位置和使用方式。以下是詳細(xì)的規(guī)則和解釋:

宏參數(shù)的展開時(shí)機(jī)

當(dāng)宏被調(diào)用時(shí),預(yù)處理器會(huì)按照以下步驟處理宏參數(shù):

參數(shù)替換

  • 在宏調(diào)用時(shí),預(yù)處理器會(huì)將宏參數(shù)替換為實(shí)際參數(shù)。
  • 如果宏參數(shù)本身是一個(gè)宏,預(yù)處理器會(huì)先展開這個(gè)宏參數(shù),然后再進(jìn)行替換。

替換列表中的宏展開

  • 在替換列表中,預(yù)處理器會(huì)逐個(gè)處理每個(gè)符號(hào)。如果符號(hào)是一個(gè)宏,預(yù)處理器會(huì)進(jìn)一步展開這個(gè)宏。
  • 但是,如果符號(hào)是一個(gè)宏參數(shù),并且這個(gè)宏參數(shù)在替換列表中被用作###操作符的參數(shù),則不會(huì)展開這個(gè)宏參數(shù)。

具體規(guī)則

  • 參數(shù)展開優(yōu)先于替換列表展開:宏參數(shù)在替換到替換列表之前會(huì)被展開。
  • 替換列表中的宏展開:替換列表中的符號(hào)(包括展開后的參數(shù))會(huì)被進(jìn)一步展開,除非它們被用作###操作符的參數(shù)。

示例

示例1:參數(shù)展開優(yōu)先

假設(shè)我們有以下宏定義:

#define A 123#define PRINT(x) printf("%d\n", x)

調(diào)用宏:

PRINT(A);

展開過程:

  1. 參數(shù)替換A 是一個(gè)宏,預(yù)處理器先展開 A,得到 123

  2. 替換列表展開:將 123 替換到 PRINT 的替換列表中,得到:

    printf("%d\n", 123);

最終輸出:

123

示例2:參數(shù)不展開(#操作符)

假設(shè)我們有以下宏定義:

#define A 123#define STRINGIFY(x) #x

調(diào)用宏:

printf("%s\n", STRINGIFY(A));

展開過程:

  1. 參數(shù)替換A 是一個(gè)宏,但因?yàn)?nbsp;STRINGIFY 的替換列表中使用了 # 操作符,所以不會(huì)展開 A

  2. 替換列表展開:將 A 替換到 STRINGIFY 的替換列表中,得到:

    printf("%s\n", "A");

最終輸出:

A

示例3:參數(shù)不展開(##操作符)

假設(shè)我們有以下宏定義:

#define A 123#define CONCAT(x, y) x##y

調(diào)用宏:

CONCAT(A, B);

展開過程:

  1. 參數(shù)替換A 是一個(gè)宏,但因?yàn)?nbsp;CONCAT 的替換列表中使用了 ## 操作符,所以不會(huì)展開 A

  2. 替換列表展開:將 A 和 B 替換到 CONCAT 的替換列表中,得到:

    AB

最終結(jié)果:AB 是一個(gè)符號(hào),而不是 123B

4. 規(guī)則

  • 參數(shù)展開優(yōu)先:宏參數(shù)在替換到替換列表之前會(huì)被展開。
  • 替換列表中的宏展開:替換列表中的符號(hào)會(huì)被進(jìn)一步展開,除非它們被用作###操作符的參數(shù)。
  • 特殊情況:如果宏參數(shù)在替換列表中被用作###操作符的參數(shù),則不會(huì)展開這個(gè)宏參數(shù)。

unsetunset2. 宏參數(shù)不展開的處理方法unsetunset

#define STRINGIFY(x)    STRINGIFY_HELPER(x)#define STRINGIFY_HELPER(x)     #x#define STRINGCAT(x, y)  STRINGCAT_HELPER(x, y)#define STRINGCAT_HELPER(x, y)  x##y

這些規(guī)則確保了宏的展開過程是可預(yù)測(cè)的,同時(shí)也提供了一種靈活的方式來控制宏的行為。

這段代碼中定義了兩個(gè)宏 STRINGIFY 和 STRINGIFY_HELPER,以及 STRINGCAT 和 STRINGCAT_HELPER。之所以需要兩個(gè)宏來實(shí)現(xiàn)功能,而不是用一個(gè)宏直接完成,是因?yàn)?C 預(yù)處理器的工作機(jī)制。

原因解釋

  1. 預(yù)處理器的展開規(guī)則在 C 預(yù)處理器中,宏參數(shù)在第一次展開時(shí)不會(huì)立即被替換為實(shí)際值,而是保留其原始形式。只有通過間接展開(即通過另一個(gè)宏調(diào)用)才能正確解析參數(shù)的實(shí)際值。

  2. 具體場(chǎng)景分析

    • 對(duì)于 STRINGIFY(x),如果直接定義為 #x,則無法正確處理帶參數(shù)的宏或復(fù)雜表達(dá)式。通過 STRINGIFY_HELPER(x) 的間接調(diào)用,可以確保參數(shù)被正確展開后再進(jìn)行字符串化。
    • 同理,對(duì)于 STRINGCAT(x, y),如果直接定義為 x##y,則無法正確連接帶參數(shù)的宏或復(fù)雜表達(dá)式。通過 STRINGCAT_HELPER(x, y) 的間接調(diào)用,可以確保參數(shù)被正確展開后再進(jìn)行拼接。
  3. 示例對(duì)比假設(shè)有以下代碼:

    #define FOO 123#define STRINGIFY(x)    #x#define STRINGCAT(x, y) x##yconst char* str = STRINGIFY(FOO); // 結(jié)果是 "FOO" 而不是 "123"int value = STRINGCAT(FOO, 456);  // 結(jié)果是 FOO456 而不是 123456

    如果使用間接宏:

    #define STRINGIFY(x)    STRINGIFY_HELPER(x)#define STRINGIFY_HELPER(x)     #x#define STRINGCAT(x, y)  STRINGCAT_HELPER(x, y)#define STRINGCAT_HELPER(x, y)  x##yconst char* str = STRINGIFY(FOO); // 結(jié)果是 "123"int value = STRINGCAT(FOO, 456);  // 結(jié)果是 123456

通過間接宏調(diào)用,參數(shù)會(huì)被正確展開,從而實(shí)現(xiàn)預(yù)期的功能。

unsetunset總結(jié)unsetunset

定義兩個(gè)宏的原因是為了利用 C 預(yù)處理器的兩步展開機(jī)制,確保宏參數(shù)能夠被正確解析和處理。如果只用一個(gè)宏實(shí)現(xiàn),則無法正確處理復(fù)雜的宏參數(shù)或表達(dá)式。

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 3
收藏 4
關(guān)注 37
成為作者 賺取收益
全部留言
0/200
成為第一個(gè)和作者交流的人吧
主站蜘蛛池模板: 一本久久精品一区二区 | 欧美国产成人精品二区芒果视频 | 人人爱人人乐免费 | 天堂成人一区二区三区 | 欧美黑人又粗又大久久久 | 9999热视频在线观看 | 惊爆摩天楼在线观看 | 中国白嫩精品bbwbbw | 欧美最猛性 | 欧美一区二区三区国产精品 | 欧美操日本 | 日本伦理片在线播放 | 日韩精美视频 | 亚洲综合无码日韩 | 在线看片免费人成视频影院看 | 美女上床啪啪 | 国产又粗又大又黄AA片爱豆 | 亚洲网站h | 欧美成人免费在线视频 | 亚洲AV成人WWW永久无码精品 | 男人放进女人阳道动态图 | 国产高清一级毛片在线不卡 | 韩国毛片在线 | 极品粉嫩嫩模大尺度无码视频 | 久久国产视频网 | 久久久久久中文 | 麻豆传媒最新网址 | 国产娱乐凹凸视觉盛宴在线视频 | 女人看片www.8888成人 | 国产午夜日韩不卡一区 | 天天夜操 | 日本免费三级网站 | 中文字幕欧美日韩一区 | 被公侵犯的漂亮人妻 | 亚洲综合色视频 | 久久玖玖 | 性高爱久久久久久久久久久dj | 欧洲亚洲一区二区三区 | 免费视频网站一区二区三区 | 国产农村熟妇出轨VIDEOS | 成人免费毛片片v |