一招让你彻底掌握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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achou.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值