第21章 预处理

一、参考文章

  1、宏的高级使用--##,__VA_ARGS__, __FILE__, __FUNCTION__等

  2、#、 ## __VA_ARGS__ 的用法

二、知识点

  1、#和##运算符

    1.1   #用在预编译语句里面可以把预编译函数的变量直接格式成字符串;如:#define Func1(x) printf("the square of "  #x " is %d.\n",(x)*(x))  

        调用Func1(30);则输出:the square of 30 is 900.

        注意,不能直接在其它非预编译函数直接使用#aa的形式,假如main函数里面出现printf("the square of " #x " is %d.\n",(x)*(x))是不能通过编译的.

    

    1.2  ##宏连接符

      举个例子:宏定义为#define XNAME(n) x##n,代码为:XNAME(4),则在预编译时,宏发现XNAME(4)与XNAME(n)匹配,则令 n 为 4,然后将右边的n的内容也变为4,

            然后将整个XNAME(4)替换为 x##n,亦即 x4,故 最终结果为 XNAME(4) 变为 x4.

 1 #include <stdio.h>
 2 #define XNAME(n) x ## n
 3 #define PRINT_XN(n) printf("x" #n " = %d/n", x ## n);
 4 int main(void)
 5 {
 6     int XNAME(1) = 14; // becomes int x1 = 14;
 7     int XNAME(2) = 20; // becomes int x2 = 20;
 8     PRINT_XN(1); // becomes printf("x""1"" = %d/n", x1);即    
 9                          //printf("x1 = %d/n", x1)
10     PRINT_XN(2); // becomes printf("x""2"" = %d/n", x2);即
11                          //printf("x2 = %d/n", x2)
12     return 0;
13 }
14                     

 

  2、可变参数

    1)参考文章:C 语言的奇技淫巧

      在 GUNC 中的扩展,其形式如下。

      #define log_debug(fmt, args...)  do { printf("gnu debug: " fmt, ## args); putchar('\n'); } while(0);
   
    2)参考文章:Linux c编程一站式学习的第21章 预处理
      
gcc有一种扩展语法,如果##运算符用在__VA_ARGS__前面,除了起连接作用之外还有特殊的含义,例如内核代码net/netfilter/nf_conntrack_proto_sctp.c中的:
        #define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)

          printk这个内核函数相当于printf,也带有格式化字符串和可变参数,由于内核不能调用libc的函数,所以另外实现了一个打印函数。

      这个函数式宏定义可以这样调用:DEBUGP("info no. %d", 1)。也可以这样调用:DEBUGP("info")。后者相当于可变参数部分传了一个空参数,

      但展开后并不是printk("info",),而是printk("info"),当__VA_ARGS是空参数时,##运算符把它前面的,号“吃”掉了。

     3)调试常用格式   

// 常用格式
#ifdef DEBUG
    #define debug(fmt, args...) printf("debug: " fmt "\n", ##args) // OR
    #define debug(fmt, ...) printf("debug: " fmt "\n", ## __VA_ARGS__);
#else
    #define debug(fmt,args...)
#endif

// 输出文件名、函数名、行数
#ifdef DEBUG
    #define debug(fmt, args...) printf("%s, %s, %d: " fmt , __FILE__, __FUNCTION__, __LINE__, ##args)
#else
    #define debug(fmt, args...)
#endif

// 输出信息含有彩色
#ifdef DEBUG
   #define debug(fmt,args...)    \
      do{                        \
         printf("\033[32;40m");  \
         printf(fmt, ##args);    \
         printf("\033[0m");      \
      } while(0);
#else
   #define debug(fmt,args...)
#endif

 

 

 

posted @ 2019-07-09 10:52  shanyu20  阅读(127)  评论(0编辑  收藏  举报