写别人看得懂的C/C++代码(2)
上次从物理文件布局、命名原则、保持单纯、
慎用struct-type-union-struct 等方面讨论了如何写别人看得懂的C/C++代码。(请参阅 http://blog.csdn.net/robotom/archive/2007/03/30/1547044.aspx )。
这次打算讨论条件编译原则、概念相关原则以及注释等方面的内容。
慎用条件编译
如果必须用到条件编译,请务必遵循以下原则:
条件编译集中处理原则
条件编译非常严重的影响代码阅读效率,请尽量控制条件编译语句的范围,最好将条件编译语句控制在一个文件里,而不是整个工程到处都是。如果同一个条件编译要在很多地方用到,可以将条件编译放在一个函数或宏中,然后在需要条件编译的地方使用这个宏。
比如以下条件编译:
#if defined(WIN32)
Call_Function_A(yyy);
#else
Call_Function_B(xxx);
#endif
如果这种代码分布在整个工程中,将是一件非常恐怖的事情;写成函数或宏的形式,效果会好得多。
函数:
Void Call_Function
{
#if defined(WIN32)
Call_Function_A(yyy);
#else
Call_Function_B(xxx);
#endif
}
宏:
#define \
#if defined(WIN32) \
Call_function_A(yyy); \
#else \
Call_function_B(xxx); \
#endif
这种写法带来的好处还有很多,以后有合适的主题再写出来。
少用大段的条件编译分支
想像一下#if和对应的#else之间隔着500行代码,阅读的时候是什么感觉?自己阅读尚且难受,让别人阅读只能是更恐怖了。#if .. #else..#endif之间最好控制在一眼能看穿的范围内,最低限度是不要超过一个屏幕所能显示的代码行数。
少用多层嵌套的条件编译
下面这段条件编译语句到底想表达一个什么意思呢?
#ifdef A
#ifdef B
#else
#ifdef C
#ifdef X
#define X(a) a.
#else
#define X(a) 2
#endif
#else
#ifdef X
#define X(a) a * 2
#else
#define X(a) 0
#endif
#endif
#endif
#else
#define X(a) 1
#endif
这个例子可能有点夸张,但是说明一个问题,条件编译桥套层数多了会极大的阻碍人们对代码的理解。阅读速度绝对与条件编译嵌套层数成反比。建议桥套层数最多不超过三层。
条件编译-能不用就不用
这是关于条件编译的最后一个原则,也是条件编译的最高原则。
条件编译一直就是影响代码阅读效率的天生杀手。条件编译与宏定义是一个天生的搭档,条件编译离不开宏定义。问题是,在偌大一个工程里,鬼知道哪个宏定义了,哪个宏没有定义?试问在这种情况下,又有谁知道每一个条件编译语句是走#if还是#else部分?
概念相关的函数在物理布局上相近
概念相关的代码是指这些代码为了实现同一个功能而写的一组函数。有时这些函数之间可能没有依赖关系或者相互之间没有消息传递,但是它们在一起完成了某个功能,这就是概念相关。
物理布局上相近,一个简单的方法是使用类:class。
很多人在写这样的代码时,往往设计出一组全局函数。单纯从功能上来讲,这种编码方式没有问题。但是如果把它们以静态成员函数的形式集中组织在一个类里面,是不是更容易让人理解呢? 一个类会很直观的让人们感受到这组函数之间的不同寻常的关系。
注释
一般而言,一段代码最权威的人士必定是这段代码的编写者,而注释是编写者写代码时的想法。相信任何一个读过别人的代码的人都知道注释的重要作用。这里只想简单的提几点:
ü 有注释
ü 注释必须正确
ü 注释不要太多
仔细想想,这三点其实是相辅相成的。一份比较复杂的代码,如果完全没有注释,它是一篇晦涩难懂的文言文诗歌;如果有一些正确的注释,它就是一篇白话文小说;如果夹杂些错误的注释,它就成了郭靖写给欧阳峰的假九阴真经,只会让人神经错乱直到走火入魔;如果注释跟代码一样多,那它迟早会变成一份前面的假九阴真经。
欢迎交流。
BLOG: http://blog.csdn.net/robotom/
MSN: robotom@sina.com
EMail: robotom@sina.com
发表于 @ 2007年04月07日 00:25:00|评论(loading...)|编辑