了解巨集參數的巨集遞歸
在 C 程式設計中,巨集為文字運算提供了強大的工具。一個有趣的方面是能夠在其他巨集的參數上使用巨集。然而,這提出了技術挑戰,因為語言通常不允許遞歸巨集。
問題:遞歸宏
考慮我們希望建立的場景名為 PRINT_ALL 的 foreach 宏,它將給定的宏 PRINT 套用於參數清單。例如:
int a = 1, b = 3, d = 0; PRINT_ALL(a,b,d);
這將對每個變數 a、b 和 d 呼叫 PRINT 巨集。簡單的方法可能會使用遞歸宏,如下所示:
#define FIRST_ARG(arg,...) arg #define AFTER_FIRST_ARG(arg,...) , ##__VA_ARGS__ #define PRINT(a) printf(#a": %d", a) #define PRINT_ALL PRINT(FIRST_ARG(__VA_ARGS__)); PRINT_ALL(AFTER_FIRST_ARG(__VA_ARGS__))
但是,這種方法會帶來兩個問題:宏不能遞歸地呼叫自身,並且它缺乏停止遞歸的停止條件。
遞歸解決方法
克服這些問題為了克服這些障礙,一個聰明的解決方法是利用一種稱為宏評估遞歸的技術。關鍵思想是發出模擬巨集呼叫的巨集文本,而不實際呼叫巨集本身。
考慮以下巨集:
#define MAP_OUT
如果我們有下列巨集:
#define A(x) x B MAP_OUT (x) #define B(x) x A MAP_OUT (x)
計算宏A(blah) 會產生輸出文字:
blah B (blah)
此文字用作巨集替換佔位符。它可以被傳回預處理器以進一步擴展,繼續巨集評估過程。
為了促進這種遞歸,定義了一系列 EVAL 巨集:
#define EVAL0(...) __VA_ARGS__ #define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__))) #define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) #define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) #define EVAL4(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) #define EVAL(...)EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
每個巨集都適用多個層級的評估,從而放大所應用的巨集的效果。
停止遞歸
為了控制遞歸,定義了一個特殊的宏MAP_END:
#define MAP_END(...)
評估此宏不執行任何操作,有效地終止遞歸。
下一個挑戰是確定何時使用 MAP_END 而不是繼續遞歸。為了實現這一點,MAP_NEXT 巨集將清單項目與特殊的清單結束標記進行比較。如果匹配,則返回 MAP_END;否則,返回下一個參數:
#define MAP_GET_END() 0, MAP_END #define MAP_NEXT0(item, next, ...) next MAP_OUT #define MAP_NEXT1(item, next) MAP_NEXT0(item, next,0) #define MAP_NEXT(item, next) MAP_NEXT1(MAP_GET_END item, next)
透過仔細建構 MAP_NEXT 宏,我們可以控制遞歸是繼續還是結束。
最終實現
結合這些構建塊,我們可以創建MAP 宏,它迭代列表並將給定的宏應用於每個item:
#define MAP(f,...)EVAL(MAP1(f,__VA_ARGS__,(),0))
該巨集的工作原理是在列表末尾放置一個列表結束標記,並附加一個額外參數以確保符合ANSI 要求。然後它透過多個 EVAL 巨集呼叫傳遞列表並傳回結果。
此技術為在巨集參數上使用巨集的問題提供了創造性的解決方案。它支援複雜的巨集操作功能,允許程式設計師以新穎的方式擴展預處理器的功能。
以上是我們如何在 C 中實作遞歸巨集?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

C 沒有死,反而在許多關鍵領域蓬勃發展:1)遊戲開發,2)系統編程,3)高性能計算,4)瀏覽器和網絡應用,C 依然是主流選擇,展現了其強大的生命力和應用場景。

C#和C 的主要區別在於語法、內存管理和性能:1)C#語法現代,支持lambda和LINQ,C 保留C特性並支持模板。 2)C#自動內存管理,C 需要手動管理。 3)C 性能優於C#,但C#性能也在優化中。

在C 中處理XML數據可以使用TinyXML、Pugixml或libxml2庫。 1)解析XML文件:使用DOM或SAX方法,DOM適合小文件,SAX適合大文件。 2)生成XML文件:將數據結構轉換為XML格式並寫入文件。通過這些步驟,可以有效地管理和操作XML數據。

在C 中處理XML數據結構可以使用TinyXML或pugixml庫。 1)使用pugixml庫解析和生成XML文件。 2)處理複雜的嵌套XML元素,如書籍信息。 3)優化XML處理代碼,建議使用高效庫和流式解析。通過這些步驟,可以高效處理XML數據。

C 在性能優化方面仍然佔據主導地位,因為其低級內存管理和高效執行能力使其在遊戲開發、金融交易系統和嵌入式系統中不可或缺。具體表現為:1)在遊戲開發中,C 的低級內存管理和高效執行能力使得它成為遊戲引擎開發的首選語言;2)在金融交易系統中,C 的性能優勢確保了極低的延遲和高吞吐量;3)在嵌入式系統中,C 的低級內存管理和高效執行能力使得它在資源有限的環境中非常受歡迎。

C XML框架的選擇應基於項目需求。 1)TinyXML適合資源受限環境,2)pugixml適用於高性能需求,3)Xerces-C 支持複雜的XMLSchema驗證,選擇時需考慮性能、易用性和許可證。

C#适合需要开发效率和类型安全的项目,而C 适合需要高性能和硬件控制的项目。1)C#提供垃圾回收和LINQ,适用于企业应用和Windows开发。2)C 以高性能和底层控制著称,广泛用于游戏和系统编程。

C 代碼優化可以通過以下策略實現:1.手動管理內存以優化使用;2.編寫符合編譯器優化規則的代碼;3.選擇合適的算法和數據結構;4.使用內聯函數減少調用開銷;5.應用模板元編程在編譯時優化;6.避免不必要的拷貝,使用移動語義和引用參數;7.正確使用const幫助編譯器優化;8.選擇合適的數據結構,如std::vector。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

記事本++7.3.1
好用且免費的程式碼編輯器

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!