在c/c++的巨集定義中,#/##存在特殊的作用1. #運算子將乙個巨集的引數轉換為字串字面量。它僅允許出現在帶引數的巨集的替換列表中。
view plain
copy to clipboard
print?
#include
#define print_str(s) printf(#s" = %s/n", s)
int main()
輸出:s1 = aaa
注:printf(#s" = %s/n", s) -> printf(s1" = %s/n", s1) -> printf("s1 = %s/n", s1)->printf("s1 = %s/n", "aaa")#s只是做巨集引數字面替換s則仍然是乙個變數名2.##運算子可以將兩個記號(例如識別符號)「粘」在一起,成為乙個記號。(無需驚訝,##運算子被稱為「記號粘合」。)
如果其中乙個運算元是巨集引數,「粘合」會在當形式引數被相應的實際引數替換後發生。
view plain
copy to clipboard
print?
#include
#define print_str(i) printf("str = %s/n", s##i)
int main()
輸出:str = s1
str = s2
str = s3
3.c99的複雜巨集:可變引數
#include
#define print_str(format, ...) dowhile(0)
int main()
輸出:str1 is s1
str2 is s2but attention!
#include
#define print_str(format, ...) dowhile(0)
int main()
編譯:macro1.cpp: in function 『int main()』:
macro1.cpp:8: error: expected primary-expression before 『)』 token
這裡提示錯誤,原因是少了變參列表,只有format引數,這裡在format引數後就多了乙個','。so,gnu cpp想出了乙個特殊的##操作,沒錯,##操作又來了,但是不是上面的拼接行為了。如果可變引數被忽略或為空,「##」操作將使預處理器去除掉它前面的那個逗號。如果在巨集呼叫時,確實提供了一些可變引數,gnu cpp也會工作正常,它會把這些可變引數放到逗號的後面。
#include
#define print_str(format, ...) dowhile(0)
int main()
輸出:str1 is over
在c/c++中,巨集定義是由define完成的,define中有三個特殊的符號值得我們注意:
1. #:在巨集展開的時候會將#後面的引數替換成字串,如:
#define p(exp) printf(#exp);
呼叫p(asdfsadf)的時候會將#exp換成"asdfsadf"
2. ##:將前後兩個的單詞拼接在一起。例如《the c programming language》中的例子:
#define cat(x,y) x##y
呼叫cat(var, 123)展開後成為var123.
3. #@:將值序列變為乙個字元
#define ch(c) #@c
呼叫ch(a)展開後成為'a'.
自己寫了一小段測試程式:
#define a(a,b) a##b
#define b(a) #a
#define c(a) #@a
#include
using namespace std;
void main()
結果為: 1
v1 v
C C 關於 在巨集定義中的用法
在c c 的巨集定義中,存在特殊的作用1.運算子將乙個巨集的引數轉換為字串字面量。它僅允許出現在帶引數的巨集的替換列表中。cpp view plain copy include define print str s printf s s n s intmain 輸出 s1 aaa 注 printf ...
關於巨集定義中 與 的用法
巨集在條件編譯以及各種大規模的定義裡是非常有用的。前面qt原始碼學習筆記裡就有一篇用來介紹巨集的定義。這次主要介紹下巨集定義裡 的作用。關於巨集,注意可以用gcc e test.cpp來檢視預編譯之後的結果。1.先介紹 主要是字串替換的作用。將傳入的符號轉化為字串 直接上源 define marco...
關於巨集定義的用法
如何解釋下面這段 define led1 a if a gpio setbits gpioc,gpio pin 3 else gpio resetbits gpioc,gpio pin 3 首先,這個是用巨集定義的方式包裝成類似函式那樣,但不是函式呼叫 你在 中呼叫 led1 1 實際上通過巨集定義...