C++裏define(宏定義)的幾種用法

  1. define是發生在預編譯階段,

    預編譯,編譯,鏈接
    處理各種cpp中的指令include define 等以 # 開頭的類似指令 ,可以使用gcc -E a.cpp命令查看預編譯後的代碼

  2. define發生的替換是從左網友開始替換。在遇到 #args的替換時,轉換爲字符串後終結。
    • 從左到右式的一一替換

      源代碼

      #define AAA 1
      int main()
      {
          int a = AAA;
          return 0;
      }
      

      編譯指令

      g++ -E test.cpp

      編譯結果

      在這裏插入圖片描述
    1. 方法型測試是否發生二次替換

      源代碼

      #define AAA 1
      #define SS(a) #a
      int main()
      {
          int a = SS(AAA);
          return 0;
      }
      

      編譯結果

      在這裏插入圖片描述
  3. define的幾種用法
    1. 單一類型替換

      看上面的案例,進行一對一的替換

      #define AAA 1
      
    2. 函數型替換

      見上面的案例

      #define SS(a) #a
      
    3. 多參數宏

      #define MAX(a,b) a<b
      

      誤區

      單一替換忽略了符號優先級

      #define MAX(a,b)  a>b?a:b
      #define MUL1(a,b) a*b
      #define MUL2(a,b) (a)*(b)
      int main()
      {
          int a = MAX(1,2);
          int b = MAX(1+1,2+2);
          int c = MUL(1,2);
          int d = MUL1(1+1,2+2);
          int e = MUL2(1+1,2+2);
          return 0;
      }
      

      編譯結果

      在這裏插入圖片描述
      結果d很明顯與開發者的目的相違,所以需要使用括號提高運算等級,如e

    4. 變參數宏

      #define ss1(a,...) {a,__VA_ARGS__ }
      #define ss2(a,...) {a,##__VA_ARGS__ }
      
      ss1(1,123,456,789)
      ss1(1)
      ss2(1,123,456,789)
      ss2(1)
      

      在這裏插入圖片描述

      舉的兩個例字,需要注意特殊宏表示參數擴張。
      如果爲空,有##的會去掉前面逗號,這種是非常友好的。這裏特別注意。
      如果不爲空,就一對一替換,這樣沒有毛病,拓展一個前置##的可以對開發更友好。

    5. 宏拼接

      案例爲用來生成方法

      #define SS(a,b) \
      #define SS(a,b) \
      int a##  ##b(int c,int d)\
      {\
          return c+d;\
      }
      
      SS(get,a)
      SS(get,b)
      SS(get,c)
      SS(get,d)
      SS(get,e)
      

      在這裏插入圖片描述

      注意,儘量不要讓傳入參數名字和拼接的名字衝突了。一定要注意衝突。

    6. 將宏轉換稱爲字符串

      將輸入轉換爲字符串,原來的字符串會進行轉義

      #define SS1(a)    #a
      #define SS2(...)  #__VA_ARGS__
      SS1(123)
      SS2(123)
      SS2(123,"123")
      

      在這裏插入圖片描述

      注意前後變化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章