• 第21章 预处理


    一、参考文章

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

      2、#、 ## __VA_ARGS__ 的用法

    二、知识点

      1、#和##运算符

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

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

            注意,不能直接在其它非预编译函数直接使用#aa的形式,假如main函数里面出现printf("the square of " #x " is %d. ",(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('
    '); } 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 "
    ", ##args) // OR
        #define debug(fmt, ...) printf("debug: " fmt "
    ", ## __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("33[32;40m");  
             printf(fmt, ##args);    
             printf("33[0m");      
          } while(0);
    #else
       #define debug(fmt,args...)
    #endif
     

     

  • 相关阅读:
    TensorFlow学习笔记--CIFAR-10 图像识别
    第二章--第二节:注释
    webbrowser
    RichViewEdit
    RichEdit
    TreeView
    RichView
    ListView
    DesktopLoader服务程序
    Delphi实现程序只运行一次并激活已打开的程序
  • 原文地址:https://www.cnblogs.com/shanyu20/p/11155964.html
Copyright © 2020-2023  润新知