學習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);
}