宏定義

預處理

 預處理是程序編譯前的一個預先處理的動做,編譯一共有4個步驟:C原文件 --> 預處理 --> 編譯 --> 彙編 -> 連接 --> 可執行文件。
預處理的工做主要是展開咱們C源碼中的#開頭的語句,去掉了全部的註釋,在嚴格的意義來講,這些語句它並不屬於C語言的語法範疇。
 如下是預處理的一些指令:
  1.頭文件 : #include
  2.宏定義 : #define
  3.取消宏 : #undef
  4.條件編譯 : #if \ #ifdef \ #ifndef \ #else \ #elif \ #enif
  5.顯示錯誤 : #error
  6.修改當前文件的名字行號 :#line
  7.向編譯器中發送特定的指令 : #progma
 能夠在編譯程序的時候添加一個-E的選項,讓編譯器在預處理以後停下來不要繼續往下走,macro.i是源程序將#展開的內容。數組

gcc macro.c -o macro.i -E

宏的概念

 宏(macro)實際上以一段字串,在源碼中只是用來直接替換目標位置,通常宏都使用全大寫字母(這只是一個習慣)。函數

#define    PI           3.141592 
    #define    BUF_SIZE     64 
    int main (int argc, char const *argv[]){

       printf("PI:lf\t" , PI); 
       int a = 100 + PI ; 
       printf("a:%d\n", a);
   } 

輸出:PI:3.141592    a:103

注意:
1.PI就是一個宏,在咱們的源代碼中若是出現宏的使用,則經過預處理以後會直接被替換,只是直接的字符替換而已,不會考慮語法或運算關係。code

無參宏

 無參宏意味着咱們在使用的時候不須要傳遞參數內存

#define    BUF_SIZE     64 
    
    int main (int argc, char const *argv[]){
      
      int arr[BUF_SIZE];   //定義了一個int型數組,大小爲64個
    }

注意:
1.宏他的本指就值直接的替換,沒有任何的語法檢查;
2.使用宏的狀況下若是代碼有跟新迭代時,只須要修改宏的一處,整個代碼中全部用到宏的地方都會被修改;
3.宏的名字能夠提升代碼的可讀性。編譯器

帶參宏

 帶參宏 在使用的時候須要攜帶參數來使用。源碼

#define MAX(a,b) a>b ? a : b 
    int main (int argc, char const *argv[]){
    
      printf("%d\t" , MAX(100,998) );  
      printf("%d\n" , 100>998 ? 100 : 998 ); 
    } 

輸出:998      998

注意:
1.使用帶參宏的時候也是直接替換。
2.只是存粹的文本替換,沒有任何的語法檢查/判斷,也沒有任何的運算
3.宏在預處理以後已經被替換,代碼實際運行時是不須要額外的時間開銷,只會浪費一點內存的空間。編譯

帶參宏的反作用

 因爲宏只是存粹的文本替換,中間不涉及任何的計算與語法檢查,類型匹配,因此用起來會比用函數麻煩不少。gcc

#define     MAX(a,b)    a>b ? a : b

    int main (int argc, char const *argv[]){

      int x = 100;
      int y = 200; 
      printf("MAX:%d\n" , MAX(x,y == 200 ? 888:999 ) );

從以上的代碼中, 無論表達式 y == 200 ? 888:999  的值都是大於 x ,可是卻出來最大值爲x 、
觀察一下替換後的結果:語法

printf("MAX:%d\n" , x>y == 200 ? 888:999 ? x : y == 200 ? 888:999 );   //注意從右向左運算,?的優先級大於:

因此應該修改長以下:gc

#define   MAX(a,b)  (a)>(b) ? (a) : (b) 
    printf("MAX:%d\n" , (x)>(y == 200 ? 888:999) ? (x) : (y == 200 ? 888:999) );

使用括號對宏當中的每一項括起來,提升優先級,這樣替換以後邏輯不會出現問題。

相關文章
相關標籤/搜索