C语言编程规范V

C语言编程规范V
C语言编程规范V

C语言编程规范-V1.0

一、文件命名

1.文件主名以字母开头,由字母、数字或下划线组成

2.采用下列文件名后缀:

.c(C程序文件)

.h(头文件)

.o(可重载目标文件)

.a(静态库)

.sl(动态库)

注:与特定编译器缺省后缀约定冲突的,遵循编译器的缺省后缀约定

3.编辑工具make的控制文件取名makefile

4.自述文件取名readme

二、源程序文件

1.源程序文件段落依照下列顺序:

序言

系统头文件引用(include)

用户头文件引用(include)

全局常量宏定义(define)

全局函数宏定义(define)

全局类型定义(typedef)

全局枚举类型定义(enums)

全局变量说明(extern)

全局变量说明(non-static)

全局变量说明(static)

函数(通常从最高层开始,按层次横向排列。如果定义较多的独立的公用函数,可以考虑按字母顺序排列)

2.序言内容应包括版权声明、文件名、内容描述、版本历史,格式如下:

/*

* Copyright 2014,XXX Co., Ltd. All right reserved.

* This program prints out messages from a queue.

* Edit History:

* 2014/11/28 - Created by GaoXuefeng.

* 2014/11/29 - Modified by ChenChen to print output in the new form.

*/

3.段落之间用空行分隔

4.文件长度尽可能在1000行之内

5.每行长度尽可能不要超过79列

三、头文件

1.用户头文件名避免使用系统头文件名

2.按照功能组织头文件,例如独立的子系统应单独一个头文件

3.与机器相关的说明组成单独头文件

4.多个源文件引用的说明放入头文件中

5.头文件不要嵌套

6.说明函数或外部变量的头文件应在定义该函数或变量的文件中引用

7.不要在头文件中定义变量

8.内部使用的宏、枚举、结构定义不应放入头文件中

9.内部使用的函数(相当于类的私有方法)声明不应放在头文件中

10.只引用需要的头文件

11.每个头文件采用下面的形式避免被重复引用:

#ifndef EXAMPLE_H

#define EXAMPLE_H

...... /* body of example.h file */

#endif /* EXAMPLE_H */

12.引用头文件不要使用绝对路径。使用引用系统头文件;使用“filename.h”

引用用户头文件,并使用C编译器的–I选项指出路径

四、其他文件

1.编写“readme”文件,列出条件编译开关、与机器相关的文件等信息

五、注释

1.用注释块描述数据结构、算法等,放在被注释的程序段前:

/*

* Here is a block comment.

* The opening slash-star and closing star-slash are alone on a line.

* ...

*/

2.单行注释放在被注释的程序段前,并与该程序段对齐:

if (argc > 1) {

/* Get input file frmm command line */

if (freopen(argv[1], "r", stdin) == NULL) {

perror(argv[1]);

}

}

3.放在代码行尾的“短注释”应从第9、13、17、21、25、……列开始,并与被注释的代

码分开至少一个空格。如果在一段代码中出现多处短注释,这些短注释应相互对齐: if (a == EXCEPTION) {

b = TRUE; /* special case */

} else {

b = isprime(a); /* works only for odd a */

}

4.除非必要,不应在一行代码或表达式的中间插入注释

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

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

7.修改代码时,应维护代码周边的所有注释,以保证注释与代码的一致性

六、说明(declaration)

1.外部数据说明明使用关键字extern

2.如果在外部数组定义时,显式地定义了其大小,则在该外部数据说明时应重复定义其大

小:

In file1:

extern int x[SIZE]; /* should not use x[] */

void foo(void) {...};

In file2:

int x[SIZE];

3.指针修饰符“*”应与变量名在一起,而不要与变量类型在一起:

char *s, *t, *u;

下列写法不正确:

char* s, t, u;

4.不相关的多个说明,即使是同一类型,也不要写在同一行

5.对每个变量和结构中的每个元素要加以短注释

6.结构中的花括号的用法采用K&R的紧凑格式

7.初值具有意义的变量在定义的同时应显式初始化,或至少应加以注释说明缺省初始化为

零:

int x = 1;

int y; /* initial value is 0 */

char *msg = “message”;

8.用长型常量初始化长型变量

9.使用大写字母“L”表示长型常量

10.如果一个程序由多个文件组成,在任何一个文件中尽可能利用static把函数和变量的作

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

11.除非不得已,应尽可能避免访问其他文件的变量。访问其他文件的变量时应加以注释,

指出变量所在文件的名称

12.用typedef定义最重要的数据类型,即便它们只是整数

13.可以在说明结构的同时定义结构类型,两者取同名:

typedef struct splodge_t {

int sp_count;

char *sp_name;

char *sp_alias;

} splodge_t;

七、函数说明

1.每个函数前加入注释块,描述函数功能、输入参数和返回值,必要时应说明其功能、用

法、重要设计决策与副作用

/*

* Function: PrintOneMsg

* To print out one message from a queue

* Parameters:

* msgno - message number

* qid - message queue identifier

* Return Value:

* 0 - success

* -1 - failure

*/

int PrintOneMsg((int msgno, int qid)

{

function body;

}

2.不要省略函数返回类型;如果函数无返回值,使用void作为函数返回类型

3.函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用

4.函数的参数个数尽可能不要超过5个

5.函数体的开、闭花括号写在第一列,分别占一行。函数体的局部变量说明和代码缩进4

6.如果一组函数含有一个相同的参数或局部变量,则每个函数以相同的变量名引用这个变

量,并出现在参数表相同的位置

7.不同含义的变量即使在不同的相关函数中,也不要使用相同的变量名

8.局部变量说明与函数的语句以一行空行分开

八、空格和空行

1.空格和空行应反映代码的块结构。例如:每个函数之间空1行,函数内每个程序段空1

行,每个层次缩进4格

2.缩格一律使用空格键,而不要用制表键

3.关键字与带括号的表达式间插入一个空格(sizeof例外)

4.在变量表中,逗号后插入一个空格

5.宏函数名与左括号之间不要有空格

6.换行时应一个完整的语句放在一行,不要根据字符数断行

九、简单句

1.每行仅书写一条语句。在for或while循环中,如果循环体为空,空循环体应占一行并

加注释:

while (*dest++ = src++)

; /* void */

2.除下条规定的情况以外,其他情况不要在条件表达式中使用隐式的非零检测,例如

if (f() != FAIL)

不应写成

if (f())

3.对满足以下全部条件的函数可以使用隐式的非零检测:

函数值取零时表示假

函数名明显地表示真值:isdigit()、isvalid()、alid()

4.必要时可以在公共头文件中定义:

#define FALSE 0

#define TRUE 1

5.不要检测布尔值等于1(TRUE),例如

if (f() != FAIL)

不应写成

if (f() == TRUE)

6.慎用嵌入式赋值语句,例如下列写法是一种不好的风格:

d = (a = b + c) + r;

但下列写法是允许的:

while ((c = getchar()) != EOF) {

process the character

}

7.慎用goto语句。通常仅用于中断多层嵌套的switch、for、while语句,并加以注释:

/* broken out into errro handling when disaster */

for (...) {

while (...) {

...

if (disaster)

goto error;

}

}

error:

clean up the mess;

十、复合语句

1.复合句花括号的书写格式采用K&R紧凑风格:

开括号与相应的关键字同行

if-else语句的else部分与闭括号同行

do-while语句的while部分与闭括号同行

https://www.360docs.net/doc/915888816.html,bel语句单独一行(除非在一个程序块中有许多label)

3.在switch语句中出现的fall-through应加以注释:

switch (expr) {

case ABC:

case DEF:

statement;

break;

case UVW:

statement;

/* fall-through */

case XYZ:

statement;

break;

}

4.在switch语句中的最后一个case结束处也需使用braek语句

5.如果switch语句含default case,它应出现在最后,但不需要break语句。在switch语句

的default case使用注释列出可能的取值。在if-else语句中,如果if或else部分是复合句,则if和else部分无论是复合句还是简单句均加上花括号:

if (expr) {

statement;

} else {

statement;

statement;

}

6.带else if的 if-else语句中的else条件应左对齐:

if (...) {

statement;

...

} else if (...) {

statement;

...

} else if (...) {

statement;

...

} else {

statement for default;

...

}

7.do-while语句的循环体总是加上花括号

8.如果if产生无条件转出(break、continue、goto、return),则else应该是隐含的,且不

需要缩进:

if (level > limit)

return (OVERFLOW);

normal();

return (level);

十一、运算符及表达式

1.单目操作符不要与它的操作数分开。双目操作符除“.”和“->”外一般应与它的操作

数用空格分开。但对于较复杂的表达式,如果里层的操作符不用空格与它的操作数分开,可能更清晰

2.对于复杂的表达式,可以分成若干行,并尽可能在最低运算顺序的操作符前断行,且后

续行缩进4个空格。涉及多种操作符的表达式,尽可能利用圆括号强调运算顺序

3.对于取离散数值的变量,不要用float类型

4.float变量的比较使用“<=”或“>=”,而不要用“==”或“!=”

5.用括号明确表达式的操作顺序,避免过分依赖默认优先级

十二、基本命名约定

1.以下划线开头或结尾的名字是系统保留的,应用程序应避免用来命名自己的名字

2.#define常量名应全部大写

3.Enum常量名应全部大写

4.函数名、typedef名和变量名(包括struct、union、enum),除了常见的通用缩写以外,

不使用单词缩写,不得使用汉语拼音,命名法可采用以下三种常用命名法之一:

Unix like命名法,单词用小写字母,每个单词直接用下划线分割,例如text_mutex,kernel_text_address

骆驼式命名法,第一个单词小写,其余单词首字母大写,单词都连结在一起

帕斯卡命名法,第一个单词首字母采用大写字母,后续单词的首字母亦采用大写字母,单词都连结在一起

注:同一应用程序只能使用一种命名法

5.宏函数名应全部大写

6.避免仅用大小写或下划线区分相似的标识符,如foo和FOO、foobar和foo_bar

7.typedef名通常以“_t”结尾

8.避免看上去不易区分的标识符,如:1(一),l(小写L),I(大写i)

9.避免标识符完全相同的局部变量和全局变量。特别地,避免以标准库中的名字来命名应

用系统中的名字

10.变量名应使用“名词”或“形容词+名词”

11.函数名应使用“动词”或“动词+名词”(动宾词组)

12.避免标识符出现数字编号,除非逻辑上确实需要编号

十三、常量

1.不要在程序中直接写数值,而通过#define给其一个有意义的标识符,然后在程序中引

用。但在某些场合,0和1可以直接使用,如作为循环的初值

2.取离散数值的变量最好定义为enum数据类型

3.常量的定义应与它们的用途一致。例如,对于浮点数,常量540应定义为540.0

4.对于空指针值,应使用NULL,而不要使用0

5.如果某一常量与其他常量密切相关,应在定义中包含这种关系,例如:

#define RADIUS = 100;

#define DIAMETER = RADIUS * 2;

十四、条件编译

1.用#ifdef定义条件编译依赖的机器时,如果未指定机器,应产生错误(使用#error),而

不是缺省机器

2.用#ifdef定义优化时,缺省应为非优化

金卡工程城市卡运营联盟TSM平台运营公司(筹)

2014年12月08日

相关主题
相关文档
最新文档