编写程序——代码的排版

    
    代码排版是每个软件工程师都要面对的问题。好的排版不仅可以让读代码的人感到赏心悦目,更重要的是可以从代码格式中发现程序的内在逻辑结构。这就好像文章、博客的一样,它们会通过分段、空白行、标点符号等各种元素来体现文章内在结构,从而提升读者的阅读体验。试想,阅读这两句话“子曰见贤思齐靥见不贤而内自省也”与“子曰,见贤思齐靥,见不贤而内自醒也”,有多大的差异。我们的古书没有版式和标点,有一部分原因是古书记录在在竹木简上,省去标点可以减少记录的成本。有意思的是,在计算机发展的早期,那些程序员也会因为存储的限制而牺牲代码的排版,算是殊途同归。幸好,现在这两个问题都已经不复存在。

其实有很多软件工程的经典书籍都会有专门的章节来讲这个问题,像《代码大全》、《简洁代码》及各种语言的入门书籍,维基百科上关于Programming Styles的词条甚至列出了大部分主流编程语言需要注意的风格。不过在我看来,最重要的一点是程序员在写代码时候,一定要以几及彼的想想当自己来阅读这样的代码时是什么感觉。我们写的代码最终不仅要发布给计算机的编译器、发布给我们的客户,还要发布给代码的维护者。他们拿到代码,首要目的是想花更少的时间、更快的理解这份代码有什么功能。说白了,代码的维护者就你写的代码的用户,需要给他们提供好的用户体验。

给阅读代码的人提供好的“用户体验”其实是个很大的命题,比如符号(函数、变量)的命名、高质量的抽象数据结构和子程序的设计等等,这里只说说代码的排版问题,不然不仅要扯地天昏地暗,还可能会扯到蛋:)。从我的定义,代码排版主要指的是通过使用空行、空白符,对单个源文件中代码组成元素进行空间布局——横向空间布局和纵向空间布局。横向空间布局上比较简单,我会遵循传统的原则——代码行的字符数不超过80个字符,这个很容易理解,主要是为了避免在阅读长代码时需要在编辑器中横向来回拖动窗口。对于纵向空间布局,这里以C语言为例,C代码代码的组成元素包括:
  • 注释文件头,File Header
  • 依赖头文件,Dependency File
  • 外部变量和函数,Extern Definition / Declaration
  • 宏定义,Macro Definition
  • 类型定义,Type Definition
  • 全局变量和函数定义和声明,Global Definition / Declaration
  • 私有变量和函数定义和声明,Internal Definition / Declaration
  • 函数实现,Function Implementaion
通常我会在源文件中按照上诉列表的顺序依次布局各个部分的内容。具体到每个单独的部分,可遵循的有几个原则:1)按照首次使用的顺序来排放;2)并列关系按照字母序来排放;3)按照关系的亲疏排放位置。这样主要有几个好处,一是对代码的排版建立统一的约定,日后你自己或者维护你代码的同志看代码时,可以到文件对应的位置寻找相应的内容,例如你可能想看一下宏定义在哪里,就一个快速索引到它是在外部变量的声明后面,等等。其二是这样的布局也比较符合我们的思维习惯,通常我们首次打开某个源文件时,会看一下头文件的Revision History,然后跳到某个函数的入口,然后按照树的广度优先遍历依次看完代码调用树。按前述,函数的实现布局看起来像下面图示的那样:


这是我对于代码排版整体布局的一个经验,但代码排版可以讨论的内容远不止这一点。你肯定在BBS上见过很多人为了指针类型标识符’*'是靠近类型比较好呢、还是靠着变量符号比较好呢之类的问题争得面红耳赤,还比如还比如…太多了。更甚的是,在实际软件生产过程中,我们更多要面对的是你和其他人的排版美学产生冲突是,你如何在信仰与现实之间折中之类的问题
原文地址:https://www.cnblogs.com/tham/p/6827280.html