学习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);
}