实用的C语言编程规范Word格式文档下载.docx

上传人:b****2 文档编号:338451 上传时间:2023-04-28 格式:DOCX 页数:20 大小:292.15KB
下载 相关 举报
实用的C语言编程规范Word格式文档下载.docx_第1页
第1页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第2页
第2页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第3页
第3页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第4页
第4页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第5页
第5页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第6页
第6页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第7页
第7页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第8页
第8页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第9页
第9页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第10页
第10页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第11页
第11页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第12页
第12页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第13页
第13页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第14页
第14页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第15页
第15页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第16页
第16页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第17页
第17页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第18页
第18页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第19页
第19页 / 共20页
实用的C语言编程规范Word格式文档下载.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

实用的C语言编程规范Word格式文档下载.docx

《实用的C语言编程规范Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《实用的C语言编程规范Word格式文档下载.docx(20页珍藏版)》请在冰点文库上搜索。

实用的C语言编程规范Word格式文档下载.docx

每个C程序通常分为两个文件。

一个文件用于保存程序的声明(declaration),称为头文件。

另一个文件用于保存程序的实现(implementation),称为定义(definition)文件。

C程序的头文件以“.h”为后缀,C程序的定义文件以“.c”为后缀。

2.1文件信息说明

文件信息声明位于头文件和定义文件的开头(参见示例1),主要内容有:

(1)公司名称;

(2)文件名称;

(3)版权信息;

(4)当前版本,作者/修改者,完成日期;

(5)主要函数描述;

(6)注意事项;

示例1

2.2头文件的结构

头文件由三部分内容组成:

(1)头文件开头处的文件信息说明(参见示例1);

(2)预处理块;

(3)函数和类结构声明等。

原则2.2.1为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块;

单词间以下划线“_”连接,例如有头文件名称为“”,则定义如下:

“#ifndef_”。

原则2.2.2用#include<

>

格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。

原则2.2.3用#include“”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。

原则2.2.4头文件中只存放“声明”而不存放“定义”。

原则2.2.5头文件中应包含所有定义文件所定义的函数声明,如果一个头文件对应多个定义文件,则不同定义文件内实现的函数要分开声明,并作注释以解释所声明的函数从属于那一个定义文件。

原则2.2.6.c/.h文件禁止包含用不到的头文件。

很多系统中头文件包含关系复杂,开发人员为了省事起见,可能不会去一一钻研,直接包含一切想到的头文件,甚至有些产品干脆发布了一个god.h,其中包含了所有头文件,然后发布给各个项目组使用,这种只图一时省事的做法,导致整个系统的编译时间进一步恶化,并对后来人的维护造成了巨大的麻烦。

2.3函数编写规则

函数设计的精髓:

编写整洁函数,同时把代码有效组织起来。

整洁函数要求:

代码简单直接、不隐藏设计者的意图、用干净利落的抽象和直截了当的控制语句将函数有机组织起来。

原则2.3.1一个函数仅完成一件功能。

说明:

一个函数实现多个功能给开发、使用、维护都带来很大的困难。

将没有关联或者关联很弱的语句放到同一函数中,会导致函数职责不明确,代码混乱,难以理解,难以测试和改动。

延伸阅读材料:

《敏捷软件开发:

原则、模式与实践》第八章,单一职责原则(SRP)。

原则2.3.2重复代码应该尽可能提炼成函数。

重复代码提炼成函数可以带来维护成本的降低。

项目组应当使用代码重复度检查工具,在持续集成环境中持续检查代码重复度指标变化趋势,并对新增重复代码及时重构。

当一段代码重复两次时,即应考虑消除重复,当代码重复超过三次时,应当立刻着手消除重复。

原则2.3.3避免函数过长,新增函数不超过50行(非空非注释行)。

本规则仅对新增函数做要求,对已有函数修改时,建议不增加代码行。

过长的函数往往意味着函数功能不单一,过于复杂

函数的有效代码行数,即非空非注释行应当在[1,50]区间。

原则2.3.4避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层。

本规则仅对新增函数做要求,对已有的代码建议不增加嵌套层次。

函数的代码块嵌套深度指的是函数中的代码控制块(例如:

if、for、while、switch等)之间互相包含的深度。

每级嵌套都会增加阅读代码时的脑力消耗,因为需要在脑子里维护一个“栈”(比如,进入条件语句、进入循环„„)。

应该做进一步的功能分解,从而避免使代码的阅读者一次记住太多的上下文。

原则2.3.5废弃代码(没有被调用的函数和变量)要及时清除。

程序中的废弃代码不仅占用额外的空间,而且还常常影响程序的功能与性能,很可能给程序的测试、维护等造成不必要的麻烦。

原则2.3.6函数不变参数使用const。

不变的值更易于理解/跟踪和分析,把const作为默认选项,在编译时会对其进行检查,使代码更牢固/更安全。

原则2.3.7函数的参数个数不超过5个。

函数的参数过多,会使得该函数易于受外部(其他部分的代码)变化的影响,从而影响维护工作。

函数的参数过多同时也会增大测试的工作量。

函数的参数个数不要超过5个,如果超过了建议拆分为不同函数。

原则2.3.8在源文件范围内声明和定义的所有函数,除非外部可见,否则应该增加static关键字。

如果一个函数只是在同一文件中的其他地方调用,那么就用static声明。

使用static确保只是在声明它的文件中是可见的,并且避免了和其他文件或库中的相同标识符发生混淆的可能性。

3标示符的命名规则

目前比较使用的如下几种命名风格:

unixlike风格:

单词用小写字母,每个单词直接用下划线„_‟分割,例如text_mutex,kernel_text_address。

Windows风格:

大小写字母混用,单词连在一起,每个单词首字母大写。

不过Windows风格如果遇到大写专有用语时会有些别扭,例如命名一个读取RFC文本的函数,命令为ReadRFCText,看起来就没有unixlike的read_rfc_text清晰了。

匈牙利命名法:

是计算机程序设计中的一种命名规则,用这种方法命名的变量显示了其数据类型。

匈牙利命名主要包括三个部分:

基本类型、一个或更多的前缀、一个限定词。

实际上,各种风格都有其优势也有其劣势,而且往往和个人的审美观有关。

我们对标识符定义主要是为了让团队的代码看起来尽可能统一,有利于代码的后续阅读和修改。

原则3.1标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。

尽可能给出描述性名称,不要节约空间,让别人很快理解你的代码更重要。

示例:

好的命名:

即使不注释也能理解。

不好的命名:

使用模糊的缩写或随意的字符。

原则3.2除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。

较短的单词可通过去掉“元音”形成缩写,较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写,常用单词的缩写必须统一。

协议中的单词的缩写与协议保持一致。

对于某个系统使用的专用缩写应该在注视或者某处做统一说明。

一些常见可以缩写的例子:

argument可缩写为arg

buffer可缩写为buff

clock可缩写为clk

command可缩写为cmd

compare可缩写为cmp

configuration可缩写为cfg

device可缩写为dev

error可缩写为err

hexadecimal可缩写为hex

increment可缩写为inc、

initialize可缩写为init

maximum可缩写为max

message可缩写为msg

minimum可缩写为min

parameter可缩写为para

previous可缩写为prev

register可缩写为reg

semaphore可缩写为sem

statistic可缩写为stat

synchronize可缩写为sync

temp可缩写为tmp

原则3.3产品/项目组内部应保持统一的命名风格。

Unixlike和windowslike风格均有其拥趸,产品应根据自己的部署平台,选择其中一种,并在产品内部保持一致。

原则3.4尽量避免名字中出现数字编号,除非逻辑上的确需要编号。

如下命名,使人产生疑惑。

应改为有意义的单词命名

原则3.5重构/修改部分代码时,应保持和原有代码的命名风格一致。

根据源代码现有的风格继续编写代码,有利于保持总体一致。

4文件命名规则

建议3.6文件命名统一采用小写字符。

因为不同系统对文件名大小写处理会不同(如MS的DOS、Windows系统不区分大小写,但是Linux系统则区分),所以代码文件命名建议统一采用全小写字母命名。

5变量命名规则

规则5.1全局变量应增加“g_”前缀。

规则5.2静态变量应增加“s_”前缀。

增加g_前缀或者s_前缀,原因如下:

首先,全局变量十分危险,通过前缀使得全局变量更加醒目,促使开发人员对这些变量的使用更加小心。

其次,从根本上说,应当尽量不使用全局变量,增加g_和s_前缀,会使得全局变量的名字显得很丑陋,从而促使开发人员尽量少使用全局变量。

规则5.3禁止使用单字节命名变量,但允许定义i、j、k作为局部循环变量。

6函数命名规则

规则6.1函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。

找到当前进程的当前目录

7宏命名规则

规则7.1对于数值或者字符串等等常量的定义,建议采用全大写字母,单词之间加下划线„_‟的方式命名(枚举同样建议使用此方式定义)。

规则7.2除了头文件或编译开关等特殊标识定义,宏定义不能使用下划线„_‟开头和结尾。

一般来说,“_”开头、结尾的宏都是一些内部的定义,

8变量

原则8.1一个变量只有一个功能,不能把一个变量用作多种用途。

一个变量只用来表示一个特定功能,不能把一个变量作多种用途,即同一变量取值不同时,其代表的意义也不同。

原则8.2不用或者少用全局变量。

单个文件内部可以使用static的全局变量,可以将其理解为类的私有成员变量。

全局变量应该是模块的私有数据,不能作用对外的接口使用,使用static类型定义,可以有效防止外部文件的非正常访问,建议定义一个STATIC宏,在调试阶段,将STATIC定义为static,版本发布时,改为空,以便于后续的打补丁等操作。

直接使用其他模块的私有数据,将使模块间的关系逐渐走向“剪不断理还乱”的耦合状态,这种情形是不允许的。

原则8.3防止局部变量与全局变量同名。

尽管局部变量和全局变量的作用域不同而不会发生语法错误,但容易使人误解。

原则8.4通讯过程中使用的结构,必须注意字节序。

通讯报文中,字节序是一个重要的问题,我司设备使用的cpu类型复杂多样,大小端、32位/64位的处理器也都有,如果结构会在报文交互过程中使用,必须考虑字节序问题。

由于位域在不同字节序下,表现看起来差别更大,所以更需要注意。

对于这种跨平台的交互,数据成员发送前,都应该进行主机序到网络序的转换;

接收时,也必须进行网络序到主机序的转换。

原则8.5严禁使用未经初始化的变量作为右值。

坚持原则8.6(在首次使用前初始化变量,初始化的地方离使用的地方越近越好。

)可以有效避免未初始化错误。

原则8.6在首次使用前初始化变量,初始化的地方离使用的地方越近越好。

未初始化变量是C和C++程序中错误的常见来源。

在变量首次使用前确保正确初始化。

在较好的方案中,变量的定义和初始化要做到亲密无间。

原则8.7明确全局变量的初始化顺序,避免跨模块的初始化依赖。

系统启动阶段,使用全局变量前,要考虑到该全局变量在什么时候初始化,使用全局变量和初始化全局变量,两者之间的时序关系,谁先谁后,一定要分析清楚,不然后果往往是低级而又灾难性的。

原则8.8尽量减少没有必要的数据类型默认转换与强制转换。

当进行数据类型强制转换时,其数据的意义、转换后的取值等都有可能发生变化,而这些细节若考虑不周,就很有可能留下隐患。

如下赋值,多数编译器不产生告警,但值的含义还是稍有变化。

9注释

原则9.1优秀的代码可以自我解释,不通过注释即可轻易读懂。

优秀的代码不写注释也可轻易读懂,注释无法把糟糕的代码变好,需要很多注释来解释的代码往往存在坏味道,需要重构。

注释不能消除代码的坏味道:

重构代码后不需要注释

原则9.2注释的内容要清楚、明了,含义准确,防止注释二义性。

有歧义的注释反而会导致维护者更难看懂代码,正如带两块表反而不知道准确时间。

注释与代码相矛盾,注释内容也不清楚,前后矛盾。

正确做法:

修改注释描述如下:

原则9.3在代码的功能、意图层次上进行注释,即注释解释代码难以直接表达的意图,而不是重复描述代码。

注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。

对于实现代码中巧妙的、晦涩的、有趣的、重要的地方加以注释。

注释不是为了名词解释(what),而是说明用途(why)。

如下注释纯属多余。

原则则9.4修改代码时,维护代码周边的所有注释,以保证注释与代码的一致性。

不再有用的注释要删除。

不要将无用的代码留在注释中,随时可以从源代码配置库中找回代码;

即使只是想暂时排除代码,也要留个标注,不然可能会忘记处理它。

原则9.5函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;

定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等。

重要的、复杂的函数,提供外部使用的接口函数应编写详细的注释。

原则9.6全局变量要有较详细的注释,包括对其功能、取值范围以及存取时注意事项等的说明。

原则9.7注释应放在其代码上方相邻位置或右方,不可放在下面。

如放于上方则需与其上面的代码用空行隔开,且与下方代码缩进相同。

示例

原则9.8同一产品或项目组统一注释风格。

10排版与格式

规则10.1程序块采用缩进风格编写,每级缩进为4个空格。

当前各种编辑器/IDE都支持TAB键自动转空格输入,需要打开相关功能并设置相关功能。

编辑器/IDE如果有显示TAB的功能也应该打开,方便及时纠正输入错误。

IDE向导生成的代码可以不用修改。

宏定义、编译开关、条件预处理语句可以顶格。

规则10.2相对独立的程序块之间、变量说明之后必须加空行。

如下例子不符合规范。

应如下书写

规则10.3一条语句不能过长,如不能拆分需要分行写。

一行到底多少字符换行比较合适,产品可以自行确定。

对于目前大多数的PC来说,132比较合适(80/132是VTY常见的行宽值);

对于新PC宽屏显示器较多的产品来说,可以设置更大的值。

换行时有如下建议:

(1)换行时要增加一级缩进,使代码可读性更好;

(2)低优先级操作符处划分新行;

换行时操作符应该也放下来,放在新行首;

(3)换行时建议一个完整的语句放在一行,不要根据字符数断行。

规则10.4在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;

进行非对等操作时,如果是关系密切的立即操作符(如->

),后不应加空格。

采用这种松散方式编写代码的目的是使代码更加清晰。

在已经非常清晰的语句中没有必要再留空格,如括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间不必加空格,因为在C语言中括号已经是最清晰的标志了。

在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。

给操作符留空

格时不要连续留两个以上空格。

1)逗号、分号只在后面加空格

2)比较操作符,赋值操作符"

="

、"

+="

,算术操作符"

+"

、"

%"

,逻辑操作符"

&

"

,位域操作符"

<

^"

等双目操作符的前后加空格。

3)"

!

~"

++"

--"

(地址操作符)等单目操作符前后不加空格。

4)"

->

."

前后不加空格。

5)if、for、while、switch等与后面的括号间应加空格,使if等关键字更为突出、明显。

规则10.5注释符(包括„/*‟„//‟„*/‟)与注释内容之间要用一个空格进行分隔。

这样可以使注释的内容部分更清晰。

现在很多工具都可以批量生成、删除'

//'

注释,这样有空格也比较方便统一处理。

规则10.6源程序中关系较为紧密的代码应尽可能相邻。

11.对齐

原则11.1程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐;

原则11.2{}之内的代码块在‘{’右边数格处左对齐;

原则11.3代码的的对齐采用TAB键而不采用空格键对齐,一般TAB键设置为向后空4个空格。

好的代码风格

不好的代码风格

12参数设计规则

原则12.1参数的书写要完整,不要贪图省事只写参数的类型而省略参数名字,如果函数没有参数,则用void填充。

原则12.2参数命名要恰当,顺序要合理;

例如编写字符串拷贝函数StringCopy,它有两个参数,如果把参数名字起为str1和str2,例如:

voidStringCopy(char*str1,char*str2);

那么我们很难搞清楚究竟是把str1拷贝到str2中,还是刚好倒过来,可以把参数名字起得更有意义,如叫strSource和strDestination。

这样从名字上就可以看出应该把strSource拷贝到strDestination。

还有一个问题,这两个参数那一个该在前那一个该在后?

参数的顺序要遵循程序员的习惯。

一般地,应将目的参数放在前面,源参数放在后面。

如果将函数声明为:

别人在使用时可能会不假思索地写成如下形式:

原则12.3如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。

原则12.4如果输入参数以值传递的方式传递对象,则宜改用“const&

”方式来传递,这样可以省去临时对象的构造和析构过程,从而提高效率;

原则12.5避免函数有太多的参数,参数个数尽量控制在5个以内。

如果参数太多,在使用时容易将参数类型或顺序搞错。

原则12.6尽量不要使用类型和数目不确定的参数;

C标准库函数printf是采用不确定参数的典型代表,其原型为:

这种风格的函数在编译时丧失了严格的类型安全检查。

13返回值的规则

原则13.1不要省略返回值的类型。

C语言中,凡不加类型说明的函数,一律自动按整型处理,这样做不会有什么好处,却容易被误解为void类型;

C++语言有很严格的类型安全检查,不允许上述情况发生。

由于C++程序可以调用C函数,为了避免混乱,规定任何C++/C函数都必须有类型。

如果函数没有返回值,那么应声明为void类型。

原则13.2函数名字与返回值类型在语义上不可冲突;

违反这条规则的典型代表是C标准库函数getchar。

按照getchar名字的意思,将变量c声明为char类型是很自然的事情。

但不幸的是getchar的确不是char类型,而是int类型,其原型如下:

由于c是char类型,取值范围是[-128,127],如果宏EOF的值在char的取值范围之外,那么if语句将总是失败,这种“危险”人们一般哪里料得到!

导致本例错误的责任并不在用户,是函数getchar误导了使用者。

原则13.3不要将正常值和错误标志混在一起返回。

正常值用输出参数获得,而错误标志用return语句返回。

原则13.4有时候函数原本不需要返回值,但为了增加灵活性如支持链式表达,可以附加返回值;

例如字符串拷贝函数strcpy的原型:

strcpy函数将strSrc拷贝至输出参数strDest中,同时函数的返回值又是strDest。

这样做并非多此一举,可以获得如下灵活性:

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2