C之奇淫技巧——宏的妙用

一、指定的初始化


很多人都知道像这样来静态地初始化数组:

int fibs[] = {1,2,3,4,5} ;

C99标准实际上支持一种更为直观简单的方式来初始化各种不同的集合类数据(如:结构体,联合体和数组)。

 

数组的初始化


我们可以指定数组的元素来进行初始化。这非常有用,特别是当我们需要根据一组#define来保持某种映射关系的同步更新时。来看看一组错误码的定义,如:

/* Entries may not correspond to actualnumbers. Some entries omitted. */

#define EINVAL 1

#define ENOMEM 2

#define EFAULT 3

/* ... */

#define E2BIG  7

#define EBUSY  8

/* ... */

#define ECHILD 12

/* ... */

 

现在,假设我们想为每个错误码提供一个错误描述的字符串。为了确保数组保持了最新的定义,无论头文件做了任何修改或增补,我们都可以用这个数组指定的语法

 

char *err_strings[] = {

        [0] = "Success",

   [EINVAL] = "Invalid argument",

   [ENOMEM] = "Not enough memory",

   [EFAULT] = "Bad address",

   /* ... */

   [E2BIG ] = "Argument list too long",

   [EBUSY ] = "Device or resource busy",

   /* ... */

   [ECHILD] = "No child processes"

   /* ... */

};

这样就可以静态分配足够的空间,且保证最大的索引是合法的,同时将特殊的索引初始化为指定的值,并将剩下的索引初始化为0。

 

 

结构体与联合体


用结构体与联合体的字段名称来初始化数据是非常有用的。假设我们定义:

struct point {

   int x;

   int y;

   int z;

} ;

然后我们这样初始化structpoint:

struct point p = {.x = 1,  .z = 3}; //x为1,y为0,z为3

 

当我们不想将所有字段都初始化为0时,这种作法可以很容易的在编译时就生成结构体,而不需要专门调用一个初始化函数。

 

对联合体来说,我们可以使用相同的办法,只是我们只用初始化一个字段。

 

二、宏列表


当遇到这样的问题的时候:

有一个标记变量,其中的每个位代表相应的含义。我们需要提供一组函数来访问设置这些位,但是对于每个标记位的操作函数都是相似的。若有32个位,难道要搞32套相似的操作函数么?

你也许会说,用一套操作函数,根据传入的参数来判断对哪个位操作。这样固然可行,但是

①不够直观。例如访问Movable标记位,对于用户来说,is Movable()是很自然的方式,而我们只能提供这样的接口isFlag(Movable)

②扩展性差。若以后增加删改标记位,则需要更改isFlag等函数的代码。

我们想有这样的设计:

在头文件的宏定义中增删标记位的宏,我们为每个标记位设计的操作函数名就自动更改,增加的标记位也自动增加一套操作函数,删除的标记位也自动减去一套操作函数。

这样的设计就太爽了!


但如何实现呢?

首先,每个标记位的宏名一变,我们的操作函数名也要相应改变,这时我们可以想到用带参宏,并用宏的##符,把两个字符串合在一起。(使它们能被宏替换掉)

#define FLAG_ACCESSOR(flag) \

bool is##flag() const {\

   return hasFlags(1 << flag);\

}\

void set##flag() {\

   JS_ASSERT(!hasFlags(1 << flag));\

   setFlags(1 << flag);\

}\

void setNot##flag() {\

   JS_ASSERT(hasFlags(1 << flag));\

   removeFlags(1 << flag);\

aibang.com/show/293725186-420492730/product/15408209.html
aibang.com/show/293725186-420492730/product/15408237.html
aibang.com/show/293725186-420492730/product/15408263.html
aibang.com/show/293725186-420492730/product/15408281.html
aibang.com/show/293725186-420492730/product/15408451.html
aibang.com/show/293725186-420492730/product/15408537.html
aibang.com/show/293725186-420492730/product/15408617.html
aibang.com/show/293725186-420492730/product/15408631.html
aibang.com/show/293725186-420492730/product/15408669.html
aibang.com/show/293725186-420492730/product/15408699.html
aibang.com/show/293725186-420492730/product/15408719.html
aibang.com/show/293725186-420492730/product/15408817.html
aibang.com/show/293725186-420492730/product/15408861.html
aibang.com/show/293725186-420492730/product/15408907.html
aibang.com/show/293725186-420492730/product/15408933.html
aibang.com/show/293725186-420492730/product/15408969.html
aibang.com/show/293725186-420492730/product/15408987.html
aibang.com/show/293725186-420492730/product/15409009.html
aibang.com/show/293725186-420492730/product/15409031.html
aibang.com/show/293725186-420492730/product/15409261.html
aibang.com/show/293725186-420492730/product/15409299.html
aibang.com/show/293725186-420492730/product/15409323.html
aibang.com/show/293725186-420492730/product/15409375.html
aibang.com/show/293725186-420492730/product/15409409.html
aibang.com/show/293725186-420492730/product/15409449.html
aibang.com/show/293725186-420492730/product/15409483.html
aibang.com/show/293725186-420492730/product/15409493.html
aibang.com/show/293725186-420492730/product/15409713.html
aibang.com/show/293725186-420492730/product/15409997.html
aibang.com/show/293725186-420492730/product/15410017.html
aibang.com/show/293725186-420492730/product/15410033.html
aibang.com/show/293725186-420492730/product/15410059.html
aibang.com/show/293725186-420492730/product/15410077.html
aibang.com/show/293725186-420492730/product/15410097.html
aibang.com/show/293725186-420492730/product/15410111.html
aibang.com/show/293725186-420492730/product/15410129.html
aibang.com/show/293725186-420492730/product/15410145.html
aibang.com/show/293725186-420492730/product/15410165.html
aibang.com/show/293725186-420492730/product/15410179.html
aibang.com/show/293725186-420492730/product/15410201.html
aibang.com/show/293725186-420492730/product/15410213.html
aibang.com/show/293725186-420492730/product/15410243.html
aibang.com/show/293725186-420492730/product/15410259.html
aibang.com/show/293725186-420492730/product/15410313.html
aibang.com/show/293725186-420492730/product/15410331.html
aibang.com/show/293725186-420492730/product/15410341.html
aibang.com/show/293725186-420492730/product/15410361.html
aibang.com/show/293725186-420492730/product/15410389.html
aibang.com/show/293725186-420492730/product/15410397.html
aibang.com/show/293725186-420492730/product/15410415.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值