zoukankan      html  css  js  c++  java
  • C语言宏定义##连接符和#符的使用(MFC就是靠##自动把消息和消息函数对应起来了,借助宏来减少switch case代码的编写量)

    C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念)。下面对常遇到的宏的使用问题做了简单总结。

    关于#和##

    在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量 通过替换后在其左右各加上一个双引号。比如下面代码中的宏:

    #define WARN_IF(EXP)    do{ if (EXP)    fprintf(stderr, "Warning: " #EXP "/n"); }   while(0)

    那么实际使用中会出现下面所示的替换过程:

    WARN_IF (divider == 0);
    被替换为
    do {
    if (divider == 0)
    fprintf(stderr, "Warning" "divider == 0" "/n");
    } while(0);

    这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。

    而##被称为连接符(concatenator),用来将两个Token连接为一个Token。注意这里连接的对象是Token就行,而不一定 是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就非常实用:

    struct command
    {
    char * name;
    void (*function) (void);
    };
    #define COMMAND(NAME) { NAME, NAME ## _command }
    // 然后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:
    struct command commands[] = {
    COMMAND(quit),
    COMMAND(help),
    ...
    }

    COMMAND宏在这里充当一个代码生成器的作用,这样可以在一定程度上减少代码密度,间接地也可以减少不留心所造成的错误。我们还可以n个##符号连接 n+1个Token,这个特性也是#符号所不具备的。比如:

    #define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d
    typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);
    // 这里这个语句将展开为:
    // typedef struct _record_type name_company_position_salary;


    http://blog.csdn.net/dotphoenix/article/details/4345174
    http://www.cnblogs.com/xuxm2007/archive/2011/06/10/2077255.html
    https://my.oschina.net/shelllife/blog/123202
  • 相关阅读:
    [转]C# 动态调用 WebService
    [转]走进 LINQ 的世界
    [转]mybatis-generator 代码自动生成工具(maven方式)
    [转]Netty入门(最简单的Netty客户端/服务器程序)
    FastJson 常见问题
    初识 ElasticSearch
    Maven Gradle 区别
    IDEA 自动生成serialVersionUID
    restful 架构详解
    初识shell expect
  • 原文地址:https://www.cnblogs.com/findumars/p/6352258.html
Copyright © 2011-2022 走看看