C語——宏小結

c語言關於宏的使用十分頻繁。可是宏的使用有利也有弊,與此同時,它仍是一個特別容易搞錯的地方。正是基於此,它經常成爲一些面試會側重考察的地方。ios

所謂宏就是 #define 機制包括的一個規定,即容許把參數替換到文本中。它的聲明方式:#define name(參數列表) stuff  面試

其中參數列表是一個由逗號分隔的符號列表,對應參數做用於stuff中,至關於宏替換函數;若是沒有參數列表,那就是咱們日常用得比較多的宏替換變量了。安全

使用特別要注意問題

 


1. 分號問題函數

2. 符號優先級問題spa

3. 做用域問題調試

4.使用帶反作用的宏參數code

 

宏定義處用了分號blog

#include <iostream>
using namespace std; #define MAX( l, r) l > r? l: r; 
int main() { int a =1 , b=2; if( a) int max = MAX( a,b);// <=> max = a > b? a:b;; 出錯!!
    else { } return 0; }

 

 

符號優先級問題作用域

 #include <iostream>
 using namespace std; #define MAX( l, r) l > r? l: r 
 int main() { int a =1 , b=2; int max = MAX( a && 3, b);//a && 3 > b? a && 3: b 達不到預想結果
     cout<<max; return 0; }

改造:io

 #define MAX( l, r) ( (l)> (r)? (l) :(r) )   
 int main() { int a =1 , b=2; int max = MAX( a && 3, b);//(a && 3) > b? (a && 3) : b
     cout<<max; return 0; }

 

 

做用域問題

 

 #include <iostream> using namespace std; //=優先級很低,不用優先級問題
 #define SWAP(l, r) {\ int tmp = l;\ l = r; \ r = tmp;} int main() { int a =1 , b=2; if(a) SWAP(a, b); //<=> {.... } ;   此處只容許出現一條語句,但這裏產生2條
 else { } cout<<a <<" "<<b<<endl; return 0; }

 

解決:用do{... }while(0)  解決

 //=優先級很低,不用優先級問題
 #define SWAP(l, r) do{\ int tmp = l;\ l = r; \ r = tmp;}while(0) int main() { int a =1 , b=2; if(a) SWAP(a, b); //<=> do{.... }while( 0) ;  else { } cout<<a <<" "<<b<<endl; return 0; }

 

 

帶反作用的宏參數

當宏參數在宏定義中出現次數超過一次時,若是這個參數具備反作用,那麼當使用這個宏時就出現危險,致使不可預料的結果。反作用就是在表達式求值時出現永久性的效果。好比x++,它能夠增長x的值。當下一次執行該表達式時,他將產生一個全新的結果。仍是之前面的的MAX函數爲例

 #include <iostream>
 using namespace std; #define MAX(l, r) ( (l)>(r)? (l): (r)) int main() { int a =1 , b=2; int max = MAX(a++, b++); //<=> (a++)>( b++)? ( a++):( b++); //結果: 3 2 4
 cout<<max<<" "<<a<<" "<<b<<endl; return 0; }

 

結果讓較小的值a增長了一次,但確讓較大的值b增長了2次。這種帶反作用宏參數會修改變量的值,使用需格外注意。

 

 

宏的優缺點


 優勢

1. 快! 因爲是預處理時期直接宏替換,不用像函數那樣來回調用返回,增長額外開銷。

2. 因爲能夠替換變量,修改變量僅需在宏定義處修改,增長了程序的可維護性。

 

缺點:

1. 沒有類型安全的檢查。宏和類型是無關的,只要對參數操做合法,它可使用任何參數類型。

2. 極易出錯。  宏參數求值是要依賴於周圍表達式的上下文環境。沒有合理地加括號,得不到指望的結果; 同時參數每次用於宏定義時,它們都會從新求值,因爲這樣屢次求值,因此讓具備反作用的參數可能產生不可預料的結果。

3. 不可調試。因爲預處理階段,直接進行了宏替換,對替換掉的代碼沒法進行調試檢查。

4. 替換插入代碼,致使程序代碼長度大大加長。

相關文章
相關標籤/搜索