日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

宏定义学习

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 宏定义学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【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

總結

以上是生活随笔為你收集整理的宏定义学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。