• C宏定义探析


    C语言中,预处理器功能:

    1. #include <>or" " 的头文件替换

    2.#define <identifier> <replacement token list>   对象替换(object-like

        对象替换以第一个空格为分割,之后的为replacement token list

    3.#define <identifier>(<parameter list>) <replacement token list>     函数替换(function-like)

       函数替换 <identifier>(<parameter list>)之间不能有任何空白符。但是调用的时候可以在之间有空格。

       函数替换的时候需要注意参数表的优先级和类型。如果替换块中需要用——';'是,用do{}while(0)封装,

       另外注意宏定义末尾不能有';'否则if-else语句的时候容易出错。

    4 #ifdefine等条件编译选项

     

     

     宏定义中比较容易搞错的是##与#的使用。

    ##是连接两个参数,

    #define MYCASE(item,id) \
    case id: \
    item##_##id
    = id;\
    break

    switch(x) {
    MYCASE(widget,
    23);
    }

    MYCASE(widget,
    23); 被扩展为

    case 23:

    widget_23
    = 23;

    break;
    #是把参数变为字符串
    #define QUOTEME(x) #x


    printf(
    "%s\n", QUOTEME(1+2));

    替换后
    ==>

    printf(
    "%s\n", "1+2");

    在使用##与#的时候,如果想使宏定义的参数也被宏替换(使用其值)

    而不是参数名字被使用,应该使用间接访问的方式。
    下面是两个例子:

    -----------------------------------------------------------------------------------------------------------

    enum {
    OlderSmall
    = 0,
    NewerLarge
    = 1
    };

    #define Older Newer
    #define Small Large

    #define _replace_1(Older, Small) Older##Small
    #define _replace_2(Older, Small) _replace_1(Older, Small)

    void printout( void )
    {
    // _replace_1( Older, Small ) becomes OlderSmall (not NewerLarge),
    // despite the #define calls above.
    printf("Check 1: %d\n", _replace_1( Older, Small ) );

    // The parameters to _replace_2 are substituted before the call
    // to _replace_1, so we get NewerLarge.
    printf("Check 2: %d\n", _replace_2( Older, Small ) );
    }


    results
    is:




    Check
    1: 0
    Check
    2: 1

    -----------------------------------------------------------------------------

    #define FOO bar
    #define QUOTEME_(x) #x
    #define QUOTEME(x) QUOTEME_(x)


    the code



    printf(
    "FOO=%s\n", QUOTEME(FOO));


    扩展后
    ==>

    printf(
    "FOO=%s\n", "bar");


      
  • 相关阅读:
    (转)C#中String跟string的“区别”
    C#中的this关键字
    (转)VS2015基础 指定一个或多个项目执行
    C# 中如何输出双引号(转义字符的使用)
    (转) C#中使用throw和throw ex抛出异常的区别
    springboot
    Zookeeper
    Maven
    springboot
    springboot
  • 原文地址:https://www.cnblogs.com/miniwiki/p/1743946.html
Copyright © 2020-2023  润新知