zoukankan      html  css  js  c++  java
  • X宏

       毕业去的第一家公司,跟着组长学到了好多的新知识以及代码编程规范,有些小技巧希望记录一下,分享给大家,在博客中参考学习了别人的博客,不废话了。

       X宏是汇编语言的一个宏,但很容易转换为C语言宏。

      换了一家公司后,我还从没在别人的代码中看到过。现在该我把这个小技巧传递下去了。

    举例说明,假设我们有一个头文件叫color.h,里面有一个颜色的宏:

    enum Color { Cred, Cblue, Cgreen };

    在相应的源文件color.c中,为了正确的打印颜色,有一个字符串数组:

    static char *ColorStrings[] = {"red", "blue", "green"};

    我们可以这样使用:

    enum Color c;
    ...
    printf("the color is %s
    ",
    ColorStrings[c]);

    到目前为止一切都很好。随着时间推移,假如新加入一个颜色:

    enum Color{ Cred, Cyellow, Cblue, Cgreen };


    是的,假如我们忘记更新数组ColorStrings[]了,打印Cyellow却输出了“blue”,更糟糕的是,如果打印Cgreen会造成数组越界。

    (作为一个聪明的程序员,你是不可能犯这样的错误的,对么?)

    主要问题是在enum和数组之间没有语义连接。 通常的解决办法是添加一个单元测试包。

    但如果我们能找到一个连接enum和数组的方法,从而在编译时检测到此类错误,岂不美哉?

    ---  X 宏 ---

    这是它的功能么?

    它能做到这一点么?

    X宏如下:

    #define COLORS 
      X(Cred, "red") 
      X(Cblue, "blue") 
      X(Cgreen, "green")

    把这个放在color.h中。接下来的是颜色枚举的定义:

    #define X(a, b) a,
      enum Color { COLORS };
    #undef X

    在源代码文件color.c中这样定义数组:

    #define X(a, b) b,
      static char *ColorStrings[] = { COLORS };
    #undef X

    可以看出,我们重新定义了X宏,以便提取出必要的信息而忽略其它。

    正确的宏管理在这里得以体现,因为如果X已经定义过#define X将会抱怨,而#undef保证了这一点不会发生。

    现在如果再添加一个颜色将变得非常简单:

    #define COLORS 
      X(Cred, "red") 
      X(Cyellow, "yellow") 
      X(Cblue, "blue") 
      X(Cgreen, "green")

    enum和数组都自动得到了更新,看起来很美妙是不是。有经验的程序员会立刻明白可以有更复杂的设计:

    复制代码
    #define COLORS 
      X(red) 
      X(blue) 
      X(green)
    
    #define X(a) C##a,
      enum Color { COLORS };
    #undef X
    
    #define X(a) #a,
      static char *ColorStrings[] = { COLORS };
    #undef X
    复制代码

    一个真实的例子是在C++编译器 Digital Mars 前端:

    #define ENUMSCMAC 
      X(unde, SCEXP|SCKEP|SCSCT ) 
      X(auto, SCEXP|SCSS|SCRD ) 
      X(static, SCEXP|SCKEP|SCSCT) 
      X(thread, SCEXP|SCKEP ) 
      ...

    3个独立但并行构造的构建 - 枚举,用于打印的字符串表,以及数组。

    我使用过的最复杂的X宏有6个参数,它可以构造枚举,结构初始化,运行时初始化等。

    当然,你可能已经在使用一个叫X的宏或者变量,且在宏内部X是硬编码的。

    Andrei Alexandrescu(Author of Modern C++ Design)建议以下改进,即将X宏作为参数:

    #define FOR_ALL_COLORS(apply) 
      apply(red) 
      apply(blue) 
      apply(green)

    紧接着:

    #define SELECT_STRING(a) #a,
    static char *ColorStrings[] =
    { 
      FOR_ALL_COLORS(SELECT_STRING)
    };
    #undef SELECT_STRING 


    任何语言只要支持文本宏预处理程序,X宏技术就能大展身手。

    C语言肯定能胜任工作。使用并且传播它,就像我贴心的朋友把他告诉我一样。:)

    转载:http://www.cnblogs.com/envoy/p/4749355.html

    爬坑的路上要越怕越勇.....
  • 相关阅读:
    关于vue无法侦听数组及对象属性的变化的解决方案
    web js导出csv 文件(使用a标签)
    微信小程序-获取用户信息和openid,session_key,
    H5适配 iponex
    项目使用iconfont图标
    锚点链接,组件库中锚点实现
    前端的调试工具和node调试工具
    前端模块化 CommonJS AMD CMD ES6
    支付宝小程序
    个人创用 UA 列表
  • 原文地址:https://www.cnblogs.com/shike8080/p/6321958.html
Copyright © 2011-2022 走看看