学习心得(code)

superlong@CoreCoder

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  74 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

公告

文字可能放在http://blog.csdn.net/superlong100,此处存放代码

常用链接

留言簿(4)

我参与的团队

搜索

  •  

最新随笔

最新评论

  • 1. re: Poj 1279
  • 对于一个凹多边形用叉积计算面积 后能根据结果的正负来判断给的点集的时针方向?
  • --bsshanghai
  • 2. re: Poj 3691
  • 你写的这个get_fail() 好像并是真正的get_fail,也是说fail指向的串并不是当前结点的子串。为什么要这样弄呢?
  • --acmer1183
  • 3. re: HDU2295[未登录]
  • 这个是IDA* 也就是迭代加深@ylfdrib
  • --superlong
  • 4. re: HDU2295
  • 评论内容较长,点击标题查看
  • --ylfdrib
  • 5. re: HOJ 11482
  • 呵呵..把代码发在这里很不错..以后我也试试...百度的编辑器太烂了....
  • --csuft1

阅读排行榜

评论排行榜

Clang 宏定义初探(二)

本篇总结下这几天看的宏的一些看到的用法。

1、参数粘结

这是一个类似 shell 之类的脚本语言的特性,可以利用这个特性完成一些重复度比较高的编码的简化。
例如,对proc文件系统进行绑定的时候,需要在/proc/test/目录下,简历3个文件接口,test1、test2、test3.
可以这样写
#define BIND(x) test##x->read_proc=test##x##_read
在使用的时候,就可以
BIND(1); //展开为test1->read_proc=test1_read;
BIND(2); //展开为test2->read_proc=test2_read;

不管是从语义还是编码复杂度,都降低了。

2、参数字符化

在使用单个 # 号,作为函数式宏的参数前缀时,可以让宏的内容变成字符串,比如说:
#define print(x) do{\
printf(#x);\
printf("=%d\n",x);\
}while(0)
使用的时候,直接写:
int t = 1;
print(t);
结果会是 t=1,这个在做日志的时候还是非常好用的。

3、do{...}while(0) 和 ({...})

可以认为是前者是 void 函数,后者是有 return 值的函数。
入2中所示,do{...}while(0) 是为了产生一个程序块,当宏里有多条需要语句需要执行时,如果不适用这种do{...}while(0)的形式,可能导致一些隐形的错误,例如:
#define print(x) {printf(#x);printf("=%d\n",x);
正常的:
print(t); 是没有问题的,但是如果放在程序段里:
if( flag )
  print(t);
else
  print(a);
展开之后,会发现为
if( flag )
{printf("t");printf("=%d\n",t);};
else
这个语法就错了。因此,当代码段比较多,且不需要返回值时就用 do{...}while(0)吧。
另外一种方式属于 GNU 的扩展,后续在看。

4、多重展开

还是基于打印的例子,我需要打印一些列举的参数值:
#define P(x) arg##x
#define print(x) do{printf(#P(x));printf("=%d\n",P(x));}while(0)
这个编译通不过,换成以下方式即可:
#define P(x) arg##x
#define __print(x) do{printf(#x);printf("=%d\n",x);}while(0)
#define _print(x) __print(x)
#define print(x) _print(P(x))
修改成这样,解决了想要的解决的问题:
int arg1 = 1;
print(1);
输出结果为:arg1=1
主要涉及的问题在于宏的多次展开,宏每次展开只会对当前的输入参数进行一次展开,当你的输入值也是个宏的时候,就需要使用过度宏,让你的输入接着展开。
对于多次展开没有从最根本的原理解释,只是从实验感官上对这个特性做了分析,实际上,自己也不会写出那么复杂的宏(怕中间调用出漏洞)。

宏的基本常见用法,都差不多枚举了一番,往后在见到更高级的玩法和比较精髓的写法往后再慢慢补充上来吧,另外GNU的扩展也会在后篇继续学习了解。
posted on 2016-03-11 01:20 superlong 阅读(1861) 评论(0)  编辑 收藏 引用 所属分类: C

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理