zoukankan      html  css  js  c++  java
  • C语言中的宏总结

    我的博客:www.shishangguan.net
    宏定义分为两种:

    1.变量式宏定义,如

    #define abc  def
    #define str "string"
    #define num 100

    2.函数式宏定义,

    #define device_init_wakeup(dev,val) 
    do { 
    device_can_wakeup(dev) = !!(val); 
    device_set_wakeup_enable(dev,val); 
    } while(0)

    注意:多行的时候,需要用do{}while(0)包装起来,这样更像一个函数调用。同时注意带有字增自减运算符的情况。

    在函数式宏定义中, # 运算符用于创建字符串, # 运算符后面应该跟一个形参(中间可以有空格
    或Tab),例如:

    #define STR(s) # s
    STR(hello world) //展开后为"hello world",自动加双引号。

    注意:实参中的多个空格会被替换成一个空格。如果游爽引号",会被自动添加转义符,

    ## 运算符把前后两个预处理Token连接成一个预处理Token,函数式宏定义和变量式宏定义都可以使用。

    #define CONCAT(a, b) a##b
    CONCAT(con, cat)    //展开后是concat
    
    #define HASH_HASH # ## #    //展开后是##

    函数式宏定义也可使用可变参数,如

    #define showlist(...) printf(#__VA_ARGS__)
    #define report(test, ...) ((test)?printf(#test):
    printf(__VA_ARGS__))
    showlist(The first, second, and third items.);
    report(x>y, "x is %d but y is %d", x, y);


    替换后变成

    printf("The first, second, and third items.");
    ((x>y)?printf("x>y"): printf("x is %d but y is %d", x, y));

    注意,__VA_ARGS__包含参数间的逗号。

    还有一种gcc的扩展,如

    #define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)

    ,##放在这儿,如果可变参数部分为空的时候,展开的时候第一个参数后不会有逗号。如

    DEBUGP("info") //printk("info")

    宏展开规则:

    1.在展开当前宏函数时,如果形参有#(字符串化操作)或##(记号连接操作)则不进行宏参数的展开,否则先展开宏参数,再展开当前宏(就像先计算函数中的参数,然后调用函数一样)。

    2.宏展开不能递归展开。

    我的博客:www.while0.com

  • 相关阅读:
    kotlin 通过 下标比对
    textarea元素调整
    jquery给两个标签绑定一个事件
    开发过程中遇到的错误
    response.setHeader各种用法详解
    如何在eclipse里删除一个类 然后SVN服务器也同时删了这个类
    @pathvariable 与@requestparam 写rest接口时遇到的
    $.getJSON
    easyUI学习
    jQuery validator addMethod 动态提示信息
  • 原文地址:https://www.cnblogs.com/yamadie/p/3557815.html
Copyright © 2011-2022 走看看