c/c++宏函数和多参宏函数
生活随笔
收集整理的這篇文章主要介紹了
c/c++宏函数和多参宏函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
記住宏函數并非真函數,就是一個字符串的替代動作,預編譯階段處理成真代碼
1:基礎宏函數
#include <stdio.h> #include <stdlib.h> #include <unistd.h>//宏的定義 // 形式: // #define 宏名稱 替換主體//宏函數的特點: // 1: 效率高,非真函數,只是字符串替換, 所以結尾";"可有可無 // 2: 可重復調用。 // 3: 核心是字符串替換操作,只是預編譯階段進行的簡單的替換,宏也不是類型定義。 // 4:由于是字符串替換,必須要注意結合順序,給足括號,防止意外。 // 5: 宏 起到指揮編譯具體目標的作用,如#ifdef,可見 宏 的主場是預編譯階段。 // 6:輔助實現了可變數量參數功能//部分預定義宏,在預編譯階段轉為實際的代碼 // 本機日期 __DATE__ // 文件名 __FILE__ // 行號 __LINE__ // 本機時間 __TIME__#define sqr(x) (x)*(x) //一定要注意括號給足#define my_pt(x) printf("%s %s\r\n",x,__DATE__)int main(int argc,char** argv) {printf("ret = %d\r\n",sqr(5+1)); printf("%s\r\n",__DATE__);printf("%s\r\n",__TIME__);printf("%s\r\n",__FILE__);printf("%d\r\n",__LINE__);my_pt("this define means string exchange=> ");return 0; }2:hentai喜歡寫的多參宏函數
#include <stdlib.h> #include <stdio.h> #include <unistd.h>//__VA_ARGS__需和define一起使用:將左側宏名稱中的...原樣抄到右邊的__VA_ARGS__地方 #define PT(...) printf(__VA_ARGS__) //原樣全抄,其實并沒啥意義,只是換了個調用名字,在宏內不能增加操作了,還算啥“宏函數” #define PT_A(...) printf(__VA_ARGS__"\r\n") //簡單追加,記住宏的內核是簡單替換 #define PT_B(...) printf("fun in %s,"__VA_ARGS__"\r\n",__FILE__) //將傳入的替換,并且再做兩側追加系統預定義宏#define LT(fm,...) printf(fm,__VA_ARGS__) // #define LT(fm , ...) printf(fm,__VA_ARGS__,__FILE__)//無法做追加操作,無法編譯,其實是替換后的編碼格式不對了 // #define LT(fm , ...) printf(fm,__FILE__,__VA_ARGS__)//無法做追加操作// #define RT(fm,...) printf(fm,##__VA_ARGS__) //單獨的##__VA_ARGS__沒啥意義 //因為是核心是預編譯的字符串替換操作,所以“,”會導致決定是否能編譯,即決定編碼內容格式。 #define RT_A(fm,...) printf(fm"fun in %s,line %d:\r\n",##__VA_ARGS__,__FILE__,__LINE__) #define RT_B(fm,...) printf("fun in %s,line %d:\r\n"fm,__FILE__,__LINE__,##__VA_ARGS__) //調整替換追加順序也可以 //關鍵處:fm"fun in %s,line %d:\r\n",##__VA_ARGS__ //關鍵處的關鍵##__VA_ARGS__ //1:如果可變參數被忽略或為空,## 操作將使預處理器(preprocessor)去除掉它前面的那個逗號 //ep: RT_A("this is const"); =>printf("this is const""fun in %s,line %d:\r\n",__FILE__,__LINE__) //2:如果你在宏調用時,確實提供了一些可變參數,GNU CPP 也會工作正常,它會把這些可變參數放到逗號的后面,匹配前面的fm規定格式 //ep: RT_A("a=%d,b=%d,sum=%d\r\n",a,b,a+b); => printf("a=%d,b=%d,sum=%d\r\n""fun in %s,line %d:\r\n",,a,b,a+b,__FILE__,__LINE__)//ep:前側可再多定義一個"參數",format位置也可以調換,但都是和" %s-%d:"連體的。 //#define LOG(Priority,format,...) syslog(LOG_DEBUG," %s-%d:" format,__FILE__,__LINE__,##__VA_ARGS__) //猜測這個順序也行#define LOG(Priority,format,...) syslog(LOG_DEBUG,format" %s-%d:",##__VA_ARGS__,__FILE__,__LINE__) int main(int argc, char ** argv){int a = 10; int b = 20;PT("this is a simple copy from ... to __VA_ARGS__"); //只能直接copyPT_A("this is a simple copy from ... to __VA_ARGS__");//注意這里存在一個前提,宏函數必定會對傳入數據進行操作,不存在直接完全拷貝的情況,這是無意義的PT("this is a simple copy from ... to __VA_ARGS__ %d %d",a,b);//能過編譯,但這種完全直接拷貝做法毫無意義// PT_A("this is a simple copy from ... to __VA_ARGS__ %d %d",a,b); //編譯不通過,在宏函數中對傳入變量進行了操作,就報字符串連接錯誤了 // PT_B("this is a simple copy from ... to __VA_ARGS__%d %d",a,b); //編譯不通過,在宏函數中需要操作變量時,出現同上問題printf("\r\n");LT("a=%d,b=%d,sum=%d\r\n",a,b,a+b);//替換了兩段東西,前半段fm,后半段...,所以后半段的,分隔是可變的,反正都去替換為__VA_ARGS__了,所以后半段參數量可變。//但是不能在宏函數中追加別的動作了printf("\r\n");RT_A("this is const");RT_A("a=%d,b=%d,sum=%d\r\n",a,b,a+b);RT_B("a=%d,b=%d,sum=%d\r\n",a,b,a+b); }結合下面兩個地址看:
https://www.codersrc.com/archives/9450.html
https://www.codersrc.com/archives/9480.html
常見還有常見宏使用的#,##用法:
#:
把后面的參數換成參數字符串
//和define定義的宏函數一起使用,獲得 傳入宏函數的參數的變量名。 #define new_print(A) printf(%s %d \r\n“,#A,A); int main(){int age = 10;new_print(age); } =》 age 10##:(宏函數內的粘接劑)
#define new_fun(parm) print##parm("this is a printf\r\n"); int main() { //new_fun(oh); //無法編譯通過 new_fun(f);return 0; } =》this is a printf即等于最終執行了printf("this is a printf\r\n");
linux內核中的#define有大量出現##這個粘接劑ep:
#define MAX8925_LDO(_id, min, max, step) \ { \.desc = { \.name = "LDO" #_id, \.ops = &max8925_regulator_ldo_ops, \.type = REGULATOR_VOLTAGE, \.id = MAX8925_ID_LDO##_id, \.owner = THIS_MODULE, \}, \.step_uV = step * 1000, \.vol_reg = MAX8925_LDOVOUT##_id, \.vol_shift = 0, \.vol_nbits = 6, \.enable_reg = MAX8925_LDOCTL##_id, \.enable_bit = 0, \ }??
總結
以上是生活随笔為你收集整理的c/c++宏函数和多参宏函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 核心网学习1
- 下一篇: MiniVCap 用普通usb摄像头做视