写函数宏应该注意什么?

qqq123 2009-03-17 04:47:53
例如一个double list的insert宏:
#define list_insert(p1, p2) {\
(p2)->next = (p1)->next; \
(p2)->prev = p1; \
(p1)->next = p2; \
(p2)->next->prev = p2; }
这样写好吗?或者应当写成:
#define list_insert(p1, p2) (\
(p2)->next = (p1)->next, \
(p2)->prev = p1, \
(p1)->next = p2, \
(p2)->next->prev = p2)

我函数宏不是很熟,请问如何写比较专业?

...全文
147 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
qqq123 2009-03-20
  • 打赏
  • 举报
回复
谢谢大家给个宝贵意见!

如果不是必须要用C语言我会考虑C++的模板的,现在我采用do{}while(0)形式,有时间我会读读《程序设计实践》。

最后特别谢谢lwouyang,祝大家coding happy!!!
lwouyang 2009-03-18
  • 打赏
  • 举报
回复
强烈不推荐用第一种写法,想想如果在代码当中调用时这样
list_insert(p1, p2); //出错了!不可以有分号
加分号就错了,而不加分号的话别人还以为你忘了加了。
也不推荐用第二种写法,虽然写法上没有什么问题,但是说白了只是一个表达式而已,不可以使用语句循环之类功能很单薄。

有一种写法比较好,

#define MACRO(param) do { \
do_something_about(param); \
} while(0) //注意!这里不加分号

这样宏体内可以放一些很复杂的语句没有问题。

宏名称一定要用大写字母,没什么好说的,约定俗成;宏体一定要缩进并最好对齐。
用作表达式使用(包括LZ的例子)的宏定义注意:无论任何时候,参数全部加括号,整个宏体加括号;
用作替代函数使用的宏定义也仍然参数全部加括号,整个宏体用do { } while(0)包起来。

[Quote=引用 6 楼 czbever 的回复:]
都不好 一般不要把函数写在宏里 那样调试也麻烦
[/Quote]
赞同,而且除了条件编译这种非用宏不可的和一些简单常量声明,其他都不建议用宏。
宏是一种及其简单粗糙的方法,它只在编译的预处理阶段起作用,几乎不具备一般函数所应有的特征。
使用宏必须非常小心,不然很容易掉进所不知的陷阱里面,大部分情况是费了很大很大的精力去调试最终竟然是由于宏替代出现文法错误或者表达式运算顺序问题,欲哭无泪啊!
想想,费那么多精力,写了一个自认为很漂亮的宏,结果反倒带来很多麻烦,浪费很多精力和时间,何必呢!

事实上,大多数情况我们并不是说非用宏不可。
alexhilton 2009-03-18
  • 打赏
  • 举报
回复
建议楼主读读《程序设计实践》
yellowhwb 2009-03-18
  • 打赏
  • 举报
回复
宏很好用的,一般用do{......}while(0)包起来比较好,否则容易有括号不匹配等错误
shuizhiyun 2009-03-18
  • 打赏
  • 举报
回复
用宏写这个东东的是脑子进水了
czbever 2009-03-17
  • 打赏
  • 举报
回复
都不好 一般不要把函数写在宏里 那样调试也麻烦
fx397993401 2009-03-17
  • 打赏
  • 举报
回复
学习 恩 呵呵
aime99 2009-03-17
  • 打赏
  • 举报
回复
都挺不好看的,不过我看很多人都是第一种写法略好一些,同楼上
softwaregf 2009-03-17
  • 打赏
  • 举报
回复
有很多应当注意的的地方有很多 , 第一种方法更好我觉得是因为以下原因:
一个指令应当以分号结束,更为正规,而且一个函数块应当用{} ,括起来,
写宏不太好,例如i++ ,等问题非常容易出错
qqq123 2009-03-17
  • 打赏
  • 举报
回复
>当然第一种写法好
why???
  • 打赏
  • 举报
回复
当然第一种写法好

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧