泰晓科技 -- 聚焦嵌入式 Linux - 追本溯源,见微知著!
网站地址:http://tinylab.org
微信公众号关注我们新浪微博


扫一扫

关注 @泰晓科技
『光顾开源小店,支持泰晓原创!』
请稍侯

也谈 C 语言编程风格:完成从程序员到工程师的蜕变

Wu Zhangjin 创作于 2014/08/17

by falcon wuzhangjin@gmail.com of TinyLab.org 2014/08/17

前言

几个礼拜前,机械工业出版社有一朋友的学姐,在新西兰读书,发过来一段代码,希望就代码风格提供些修改建议。

学姐

我把那个C函数的代码发你邮箱了,麻烦帮我提点修改建议,非常感谢!

看了下代码,本身是实现了一个算法,代码很漂亮,注释也到位,命名也符合“见文知意”。不知道有啥需要检查的。所以跟学姐确认了一下:

Falcon

不好意思,大概看了下好像是个算法实现,有啥需要帮忙check的么?

学姐

帮我看看代码是否规范,变量的声明啥是否符合嵌入式的风格,谢谢 ;-P

Falcon

风格方面没有特定的统一规范哦,不同的项目或者公司要求有差异,比如Linux的驱动和代码由Documentation/CodingStyle规范,而所有GNU项目有他们自己的规范,其他项目类似。而公司方面,比如华为公司有自己的风格。

如果是自己开发新项目,遵循其中某个约定就好,比如Linux的,如果是老项目,则可以考虑坚持老项目原有的规范,目标是让整个代码风格统一,方便阅读和维护。

上面基本是跟学姐交流的原文,下面我们就该问题展开深入讨论,希望为有类似困惑的同学提供一些参考。

编程风格的意义

深入讨论之前,首先要明确编程风格的意义所在,基本的有:

  • 美观
  • 方便阅读
  • 易于理解
  • 方便修改和维护
  • 方便审查
  • 方便测试
  • 程序效率
  • 代码质量
  • 方便编写

总之,就是要平衡各个方面的需求,最终让产品团队高效、快乐地生产出高质量、高效的软件,并且要确保软件在整个生命周期内利于各个阶段的活动,包括前期编写、中期评审、后期测试和长期维护。

所以编码本身其实也是一种艺术。

编程风格有哪些成文规范

就如同艺术流派的多样性一样,编码风格没有特定的统一规范,不同的软件项目或者企业有不同的艺术风格,这些风格成文后就变成了规范,例如:

而公司方面,比如华为有自己的编程规范:《华为编程规范》,当然,不同的编程语言会有不同版本的规范。

具体(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的艺术,为人类创造更好体验的产品,这种产品在达成某种实用功能的基础上,能够为用户的各种感官甚至精神上提供美的感受和体验,最终,这种产品不再是简单的堆砌,而是成为各方面协调一致的艺术品。

Read More: