C 中的巨集(續)

2021-05-22 16:34:14 字數 1631 閱讀 8820

1.1.1. #運算子

#字元在#define巨集定義中是乙個將引數名轉換為字串的運算子,#放在巨集引數的前面。例如:

#include

#include

#define declare_non_copiable_begin(cname) /

class cname /

public: /

virtual std::string tostring( void )const /

private: /

cname(const cname&); /

cname& operator=(const cname&);

#define declare_non_copiable_end(cname) };

declare_non_copiable_begin(socket)

public:

socket( void )

declare_non_copiable_end(socket)

int main( void )

socket sock;

std::cout<

<

return 0;

先定義了一對巨集,declare_non_copiable_begin和declare_non_copiable_end,在前乙個巨集中將拷貝建構函式和複製運算子定義為private,避免物件進行複製(例如檔案、socket等資源),並定義了乙個預設的tostring函式返回類的名稱,類名稱字串就是通過#運算子生成的。接下來使用定義的巨集定義了乙個socket類,來展示這對巨集的用法。當然這種實現方式不一定是最好的,還可以通過定義乙個基類來實現這種方式,在講到拷貝建構函式時會展示另一種方案。

1.1.2. ##運算子

在#define定義的巨集中,##運算子用於將引數與識別符號連線,構成新的識別符號,但##運算子放在乙個識別符號的最前面,也不能放到識別符號的最後。例如:

#include

#define declare_bit(n) const unsigned int bit ## n = 1<

declare_bit(0); // 等價於:const unsigned int bit0 = 1<<0;

declare_bit(1);

declare_bit(2);

declare_bit(3);

declare_bit(4);

declare_bit(5);

declare_bit(6);

declare_bit(7);

int main( void )

std::cout<<"bit0:"<

<<", bit1:"<

<<", bit2:"<

<<"... bit7:"<

<

return 0;

上面的**先定義了乙個巨集declare_bit,該巨集用於定義整數中各位的權值,然後使用該巨集定義了一系列位的權值。這樣的**更利益於維護,比如我們隨時可以修改實現的機制,此處是通過定義常量實現的,我們隨時可以修改常量的型別,而且只需修改一行**。

注意:需要注意的是c++標準並沒有定義##運算子與#運算子的處理順序,所以不要定義依賴於這兩個運算子解析順序的巨集,避免在不同編譯器下產生不同的結果,這樣的bug往往非常難以定位。

c語言 巨集中 的用法(續)

如下 不明覺厲。define ext2 debug f,a.特別是其中printf f,a 這樣的用法。google之後在stackoverflow找到了這個問題以及解答。詳細的解答跳轉到了gnu的gcc文件 譯文如下 3.6 variadic macros 可變引數的巨集 乙個巨集可以像乙個函式一...

巨集定義中的續行符

巨集定義中的續行符 巨集定義規定,巨集定義必須在一行裡完成。所以用 define定義巨集定義時,有時為了閱讀方便,就加續行符 來換行。在普通 行後面加不加都一樣 vc是自動判斷續行的 例如 define somefun x,a,b if x x a b else x a b 這一行定義是沒有問題的,...

c 中的續行符 和巨集定義的結合使用

c 中經常遇到巨集定義 巨集定義要求的是一行完成 但是一般宣告帶有引數列表的巨集定義的時候,由於函式體字串太長,導致很長不能直觀的看出來,如果自動換行又影響了一行完成的規定 所以誕生了續行符。define somefun x,a,b if x x a b else x a b 這一行定義是沒有問題的...