一招讓你徹底掌握C語言中運用宏以及#與##的妙用

學習C語言,特別是閱讀linux源碼的時候,大家經常遇到很多的宏定義,有簡單的,當然也有很複雜的。
有事一個宏定義甚至有幾十行之多,遇到這種宏定義的大家基本上是一臉懵逼,不知所措,其實想複雜的宏定義沒有去深究的價值,簡短的纔有深究的價值。
但是你不理解這些長的宏定義就無法接着理解接下來的代碼,今天這裏就叫大家一個我經常使用的方法,來理解些宏定義,將你需要理解的宏定義,新建一個.c文件,比如test.c,這時僅需要使用gcc -E test.c > test,執行之後test就是test.c展開之後的文件,也就是預處理之後的文件,裏面的宏都會進行展開

我這裏舉例兩個宏定義,並趁機說明下#和##的作用

#  將對應標緻按照字面意思轉換我對應的字符
## 黏貼兩個標緻爲一個
#include <stdio.h>
#include <stdio.h>
#include <math.h> //NAN
//#的作用是將關鍵字轉換爲對應的字符
#define Peval(cmd) printf(#cmd ": %g\n", cmd);

#define Setup_list(name, ...) \
    double *name ## _list = (double []){__VA_ARGS__, NAN}; \
    int name ## _len = 0; \
    for (name ## _len =0; \
    !isnan(name ## _list[name ## _len]); \
    ) name ## _len ++;

int main()
{
    //  測試單個#
    double *plist = (double[]){1, 2, 3};
    double list[] = {1, 2, 3};
    Peval(sizeof(plist)/(sizeof(double)+0.0));
    Peval(sizeof(list)/(sizeof(double)+0.0));

    // 測試雙 ##
    Setup_list(items, 1, 2, 4, 8);
    double sum=0;
    for (double *ptr= items_list; !isnan(*ptr); ptr++)
    sum += *ptr;
    printf("total for items list: %g\n", sum);
    #define Length(in) in ## _len
    sum=0;
    Setup_list(next_set, -1, 2.2, 4.8, 0.1);
    for (int i=0; i < Length(next_set); i++)
    sum += next_set_list[i];
    printf("total for next set list: %g\n", sum);
    
}

展開後的部分代碼


int main()
{



    double *plist = (double[]){1, 2, 3};
    double list[] = {1, 2, 3};

//#的作用是將關鍵字轉換爲對應的字符
#define Peval(cmd) printf(#cmd ": %g\n", cmd);
    //Peval(sizeof(plist)/(sizeof(double)+0.0));
    //展開後,可以看到,所有Peval 裏面填寫的標誌已經經過#cmd 被轉換爲字符串 
    printf("sizeof(plist)/(sizeof(double)+0.0)" ": %g\n", sizeof(plist)/(sizeof(double)+0.0));;
    printf("sizeof(list)/(sizeof(double)+0.0)" ": %g\n", sizeof(list)/(sizeof(double)+0.0));;




#define Setup_list(name, ...) \
    double *name ## _list = (double []){__VA_ARGS__, NAN}; \
    int name ## _len = 0; \
    for (name ## _len =0; \
    !isnan(name ## _list[name ## _len]); \
    ) name ## _len ++;
    
    //雙 ## 將兩個標緻會黏貼到一塊
    
    double *items_list = (double []){1, 2, 4, 8, 
   (__builtin_nanf (""))
   }; int items_len = 0; for (items_len =0; !
   __builtin_isnan (
   items_list[items_len]

   )
   ; ) items_len ++;;
    double sum=0;
    for (double *ptr= items_list; !
                                  __builtin_isnan (

                                  *ptr

                                  )

                                             ; ptr++)
    sum += *ptr;
    printf("total for items list: %g\n", sum);

    sum=0;
    double *next_set_list = (double []){-1, 2.2, 4.8, 0.1, 
   (__builtin_nanf (""))
   }; int next_set_len = 0; for (next_set_len =0; !
   __builtin_isnan (
   next_set_list[next_set_len]
   )
   ; ) next_set_len ++;;
    for (int i=0; i < next_set_len; i++)
    sum += next_set_list[i];
    printf("total for next set list: %g\n", sum);
}

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