by falcon wuzhangjin@gmail.com of TinyLab.org
2014/08/17
最初发表:泰晓科技 – 聚焦嵌入式 Linux,追本溯源,见微知著!
原文链接:也谈C语言编程风格:从程序员到工程师的蜕变
评论说明:为更好地聚合大家的讨论,请到上面原文的评论区回复。
前言
几个礼拜前,机械工业出版社有一朋友的学姐,在新西兰读书,发过来一段代码,希望就代码风格提供些修改建议。
学姐
我把那个C函数的代码发你邮箱了,麻烦帮我提点修改建议,非常感谢!
看了下代码,本身是实现了一个算法,代码很漂亮,注释也到位,命名也符合“见文知意”。不知道有啥需要检查的。所以跟学姐确认了一下:
Falcon
不好意思,大概看了下好像是个算法实现,有啥需要帮忙check的么?
学姐
帮我看看代码是否规范,变量的声明啥是否符合嵌入式的风格,谢谢 ;-P
Falcon
风格方面没有特定的统一规范哦,不同的项目或者公司要求有差异,比如Linux的驱动和代码由Documentation/CodingStyle规范,而所有GNU项目有他们自己的规范,其他项目类似。而公司方面,比如华为公司有自己的风格。
如果是自己开发新项目,遵循其中某个约定就好,比如Linux的,如果是老项目,则可以考虑坚持老项目原有的规范,目标是让整个代码风格统一,方便阅读和维护。
上面基本是跟学姐交流的原文,下面我们就该问题展开深入讨论,希望为有类似困惑的同学提供一些参考。
编程风格的意义
深入讨论之前,首先要明确编程风格的意义所在,基本的有:
- 美观
- 方便阅读
- 易于理解
- 方便修改和维护
- 方便审查
- 方便测试
- 程序效率
- 代码质量
- 方便编写
总之,就是要平衡各个方面的需求,最终让产品团队高效、快乐地生产出高质量、高效的软件,并且要确保软件在整个生命周期内利于各个阶段的活动,包括前期编写、中期评审、后期测试和长期维护。
所以编码本身其实也是一种艺术。
编程风格有哪些成文规范
就如同艺术流派的多样性一样,编码风格没有特定的统一规范,不同的软件项目或者企业有不同的艺术风格,这些风格成文后就变成了规范,例如:
- Linux Documentation/CodingStyle
- GNU Coding Standard
- Uboot Coding Style
- Busybox Style Guide
而公司方面,比如华为有自己的编程规范:《华为编程规范》,当然,不同的编程语言会有不同版本的规范。
具体(C语言开发)时应遵循哪个规范
那开发项目时,到底应该如何遵循规范呢?
根据自己在外企、民企和社区多年的项目开发经验,做个基本小结:
-
如果是全新的项目,推荐直接采用Linux规范
这里的全新,意味着是一个从头开发的项目。
Linux规范是笔者体验过的最“美”的风格,没有之一。当然,诸如《C Traps & Pitfalls》等提供了很好的补充,但是其他规范如果与Linux规范有冲突,请使用Linux规范。
要研究他,请重复阅读并持续实践:Documentation/CodingStyle,最好是创造些机会给社区贡献些代码。
记得善用(不是滥用)这些辅助工具:
- scripts/Lindent
- scripts/checkpatch.pl (更具实践性的不成文约定)
- scripts/cleanpatch
- scripts/cleanfile
如果公司没有制定规范,请不要重新发明轮子,即使有需要,也最多在这个之上加些补充。不要以公司创始人或者某些技术专家的喜好作为规范。
如果项目中用到第三方的库,建议这些部分保留它们自己的规范。
-
如果是社区项目
请遵循社区项目本身的规范,比如上面提到的Linux,GNU toolchain,Uboot, Busybox等,请用他们自己的规范。
即使GNU编码规范再“丑陋”,如果想往这个社区提交代码,为了保持整个项目的一致性,必须符合他们的规范,因为那是他们的地盘。
-
如果是老项目
这个“老”可能是公司历史遗留项目或者是供应商提供的源码,在维护已有的代码时,为了方便评审,请在修改代码时,千万不要尝试去修改已有代码的风格,并且在源代码基础上新增的代码也需要遵循老代码的风格,有两个方面的关注:
- 保持最小粒度的文件内代码风格的一致性
- 让变更最小化,不要给评审带来额外的干扰,而且让Reviewer看到相对舒适的代码
当然,不排除老代码就是一坨翔,那么请按照这个步骤走,同样以Linux为例:
- 先备份老的代码,或者先直接提交老代码入库
- 用工具自动格式化,请用scripts/Lindent
- 然后解决自动格式化工具没有处理好的问题
- 之后用scripts/checkpatch.pl做一些检查
- 生成补丁,提交变更,发送评审
上面只是把老的代码入库了,并且确保了老代码是遵循规范的,之后再单独提交新的变更,并做相应评审。这个时候就不会把老代码风格的变更与新代码的变更搅合在一起,因此会更方便评审,提高代码入库的效率。
后记
如果只是简单重复的Copy & Paste,那永远可能只是个程序员/Coder,在Coding的时候必须综合思考效率、质量、协作、体验、工程等因素,并能够很好地权衡,让各个因素达成一个美的平衡,这样的Coder才会逐步成为真正意义上的工程师。
真正的工程师,可以在音乐、电影、写作、雕塑等之外,演绎另外一门IT的艺术,为人类创造更好体验的产品,这种产品在达成某种实用功能的基础上,能够为用户的各种感官甚至精神上提供美的感受和体验,最终,这种产品不再是简单的堆砌,而是成为各方面协调一致的艺术品。