宏定义学习
【1】宏定義怎么理解?
? ? ? ?關于宏定義,把握住本質:僅僅是一種字符替換,而且是在預處理之前就進行。
【2】宏定義可以包括分號嗎?
? ? ? ?可以,示例代碼如下:
1 #include<iostream> 2 using namespace std; 3 4 #define PI 3.14; //宏定義可以包括“;” 5 6 void main() 7 { 8 double r=10,s; 9 s=r*r*PI //注意此處的語法 10 cout<<s<<endl; //314 11 }【3】宏定義一種新類型如何實現?
? ? ? ?示例代碼如下:
1 #include<iostream> 2 using namespace std; 3 #define int int * 4 void main() 5 { 6 int a,b;// int *a, b; 7 } 8 //理解此處的微妙:int *a,b; 這條語句同時定義了兩個變量。一個指針:int *a; 一個變量:int b;【4】宏定義一個函數如何實現?
? ? ? ? 示例代碼如下:
1 #include<iostream> 2 using namespace std; 3 4 #define Begin() {int a;a=0;cout<<"a="<<a<<endl;} 5 6 void main() 7 { 8 Begin() 9 } 10 //如果{......}中的代碼太多,應該使用宏連接 11 //代碼如下所示: 12 #define Begin() { int i;\ 13 i=10;\ 14 cout<<"i="<<i<<endl;}【5】宏定義如何取消?
? ? ? ? 示例代碼如下:
1 #include<iostream> 2 using namespace std; 3 4 #define int int * 5 6 void main() 7 { 8 int a, p; // int *a,p; 9 a = &p; 10 #undef int //取消宏定義 11 int b = 10; 12 a = &b; 13 }?【6】對宏定義歧義現象怎么識別?
? ? ? ? ?示例代碼如下:
1 #define SUM(x,y) x*y 2 #define SUMM(x,y) ((x)*(y)) 3 void main() 4 { 5 int a = 4, b = 5; 6 cout<<SUM(a+2,b+4)<<endl; //18 7 cout<<SUMM(a+2,b+4)<<endl; //54 8 }? ? ??求一個數的平方正確的宏定義:
#define S(r) ((r)*(r))? ? ?這個宏定義注意事項:
? ? (1)宏名和參數的括號間不能有空格
? ? (2)宏替換只作替換,不做計算,不做表達式的求解
? ? (3)函數調用在編譯后程序運行時進行,并且分配內存。宏替換在編譯前執行,不分配內存
? ? (4)宏的啞實結合不存在類型,也沒有類型轉換
? ? (5)函數只有一個返回值,利用宏則可以設法得到多個值
? ? (6)宏展開使源程序變長,函數調用不會
? ? (7)宏展開不占運行時間,只占編譯時間,函數調用占運行時間(分配內存 保留現場 值傳遞 返回值)
? ? ??何謂啞實結合?
? ? ? 示例代碼及解釋如下:
1 #define S(a,b) a*b 2 void main() 3 { 4 int area = 0; 5 area = S(3,2); //第一步:被替換為area = a*b; 第二步:被替換為area = 2*3; 6 //類似于函數調用,有一個啞實結合過程 7 }?【7】下面宏定義特例如何解析?
? ? ? ? ?示例代碼如下:
1 #define NAME "zhangyuncong" 2 //#define AB "liu //error!!編譯錯誤 3 //#define 0x abcd //error!!編譯錯誤 4 void main() 5 { 6 cout<<NAME<<endl; //zhangyuncong 7 cout<<"NAME"<<endl; //NAME 8 cout<<"NAMElist"<<endl;//NAMElist 9 //cout<<NAMEList<<endl; //error!!!!編譯錯誤 10 }? ? ? ?也就是說,這種情況下記住:#define ? ?第一位置 ? ??第二位置
? ? ? (1)不替換程序中的字符串內的任何內容
? ? ? (2)第一位置只能是合法的標識符(可以是關鍵字)
? ? ? (3)第二位置如果有字符串,必須把“”配對
? ? ? (4)只替換與第一位置完全相同的標識符
? ? ? ? 總之一句話:僅僅只是簡單的替換而已,不要在中間計算結果,一定要替換出表達式之后再計算
?【8】宏定義的特例有參形式如何解析?
? ? ? ? ?示例代碼如下:
1 #define FUN(a) "a" 2 void main() 3 { 4 cout<<FUN(345)<<endl; //a 5 cout<<FUN(a)<<endl; //a 6 cout<<FUN("a")<<endl; //a 7 char *str=FUN(abc); 8 cout<<str<<endl; //a 9 }? ? ? ?通過上例可以看到,如果這樣寫,不論實參是什么,都不會擺脫被替換為“a”的命運。也許,你會問,那么我要實現FUN(345)被替換為“345”??腫么辦呢??
? ? ? ?請看下面這個用法
?【9】有參宏定義中#的有何作用?
? ? ? ? ?示例代碼如下:
1 #define STR(str) #str 2 3 void main() 4 { 5 cout<<STR(abc)<<endl; //abc 6 cout<<STR("abc")<<endl; //"abc" 7 cout<<STR(123)<<endl; //123 8 cout<<STR(my#name)<<endl; //my#name 9 // cout<<STR(()<<endl; //error!!編譯錯誤 10 cout<<STR(.)<<endl; //. 11 // cout<<STR(A,B)<<endl; //error!!編譯錯誤 12 cout<<STR(())<<endl; //() 13 const char * str=STR(liuyong); 14 cout<<str<<endl; //liuyong 15 }? ? ? ??備注:代碼編譯環境為VS2010 ?那么相信“#”的作用也一目了然。在此不作贅述。
? 【10】有參宏定義中##有何作用?
? ? ? ? ? 示例代碼如下:
1 #define SIGN( x ) INT_##x 2 #define WIDE(str) L##str 3 4 void main() 5 { 6 int SIGN(a); 7 // int INT_a; //error!! redefinition 8 char * WIDE(a); 9 // char *La; //error!! redefinition 10 }? 【11】當一個宏自己調用自己時,會發生什么呢?
? ? ? ? ?例如:#define ?TEST(x) ? ( x + TEST( x ) )
? ? ? ? ?TEST(1); 會發生什么呢?為了防止無限制遞歸展開,語法規定:當一個宏遇到自己時,就停止展開。
? ? ? ? ?也就是說,當對TEST(1)進行展開時,展開過程中又發現了一個TEST,那么就將這個TEST當作一個
? ? ? ? ?一般的符號。TEST(1)最終被展開為:1 +?TEST(1)。
? 【12】可以舉一個變參宏的例子嗎?
? ? ? ? ?示例代碼如下:
1 #define LOG( format,... ) printf( format, __VA_ARGS__ ) 2 3 void main() 4 { 5 int a = 10; 6 char *str = "abc"; 7 LOG("%d,%s",a,str); //10,abc 8 }? 【13】當宏作為參數被放進另一個宏體時,將會發生什么?
? ? ? ? ? ??當一個宏參數被放進宏體時,這個宏參數會首先被全部展開(當然,沒有絕對,也有例外)。當展開后的宏參數被放進宏體時,
? ? ? ? ?預處理器對新展開的宏體進行第二次掃描。并繼續展開。舉例說明:
? ? ? ? ?示例代碼如下:
1 #define PARAM(x) x 2 #define ADDPARAM(x) INT_##x 3 4 void main() 5 { 6 int PARAM(ADDPARAM(1)); 7 // int INT_1; //error!! 編譯錯誤 重復定義 8 }? ? ? ? ?因為ADDPARAM(1)是作為PARAM的宏參數,所以先將ADDPARAM(1)展開為INT_1,然后再將INT_1放進PARAM。
? ? ? ? ?也有例外,如果PARAM宏內對宏參數使用了#?或者 ## ,那么宏參數不再被展開。例如:
? ? ? ? ?#define PARAM( x ) #x
? ? ? ? ?#define ADDPARAM( x ) INT_##x
? ? ? ? ?PARAM( ADDPARAM( 1 ) ); 將被展開為"ADDPARAM( 1 )"。
?
Good Good Study, Day Day Up.
順序 選擇 循環 總結
轉載于:https://www.cnblogs.com/Braveliu/archive/2012/12/28/2837954.html
總結
- 上一篇: MongoDB学习笔记(一) Mongo
- 下一篇: 全国各地市统计年鉴汇总2021