C语言编程规范10.docx
- 文档编号:28919262
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:34
- 大小:198.60KB
C语言编程规范10.docx
《C语言编程规范10.docx》由会员分享,可在线阅读,更多相关《C语言编程规范10.docx(34页珍藏版)》请在冰豆网上搜索。
C语言编程规范10
C编码规范
109条规则+49条建议
目录
1.文件结构(4条规则+6条建议)1
1.1版权和版本的声明1
1.2头文件的结构2
1.3定义文件的结构3
1.4头文件和定义文件使用(4条规则+6条建议)3
2.程序版式(34条规则+2条建议)4
2.1空行(4条规则)4
2.2代码行(5条规则+1条建议)4
2.3代码行内的空格(6条规则+1条建议)5
2.4对齐(4条规则)6
2.5长行拆分(2条规则)7
2.6修饰符的位置(1条规则)8
2.7注释(12条规则)8
3.标识符命名(15条规则+1条建议)8
4.常量(7条规则)10
4.1const与#define的比较(2条规则)10
4.2常量定义(5条规则)10
5.变量(11条规则)11
6.表达式和基本语句(17条规则+3条建议)11
6.1运算符的优先级(1条规则)11
6.2复合表达式(4条规则)12
6.3if语句布尔表达式(7条规则)12
6.4循环语句(1条规则+3条建议)15
6.5switch语句(2条规则)16
6.6goto语句(1条规则)16
7.函数设计(16条规则+10条建议)16
7.1注释规则(1条规则)16
7.2函数的使用(1条规则)16
7.3参数的规则(4条规则+2条建议)17
7.4返回值的规则(6条规则)17
7.5函数内部实现的规则(2条规则)17
7.6其它建议(6条建议)18
7.7使用断言(2条规则+2条建议)18
8.内存管理(5条规则)18
8.1内存使用注意的问题(5条规则)18
9.其他规范及建议(27条建议)19
9.1提高程序的效率(6条建议)19
9.2编译问题(2条建议)19
9.3兼容性问题(8条建议)19
9.4性能问题(4条建议)19
9.5其他一些有益的建议(7条建议)20
1.文件结构(4条规则+6条建议)
C程序文件通常分为两类文件:
一类文件用于保存程序的声明(declaration),称为头文件。
头文件以“.h”为后缀。
另一类文件用于保存程序的实现(implementation),称为定义(definition)文件。
定义文件以“.c”为后缀。
对于简单的C语言程序,一般在把头文件和程序定义文件放在一起,只有一个.c定义文件即可。
而对于复杂的程序,则多采用头文件包含的形式并通过多个定义文件实现。
1.1版权和版本的声明
版权和版本的声明一般应该位于头文件和定义文件的开头(参见示例1-1),主要内容包括:
(1)版权信息;
(2)文件名称、文件标识、摘要;
(3)当前版本号、作者/修改者、修改日期、修改描述等;
(4)版本历史信息、原作者、完成日期等。
示例1-1版权和版本的声明
版本标识:
采用<主版本号>.<次版本号>.<修订号>来命名自己产品的编号。
一般这样约定,如果次版本号是偶数(如0、2、4等),代表正式版本,如果次版本号是奇数(如1、3、5等),代表开发过程中的测试版本。
修订号则相当于Build号,用来标识一些小的改动。
1.2头文件的结构
头文件由三部分内容组成:
(1)文件开头处的版权和版本声明(参见示例1-1);
(2)预处理块;
(3)声明函数原型和声明数据结构或变量等。
假设头文件名称为filename.h,头文件的结构参见示例1-2。
示例1-2C头文件结构
1.3定义文件的结构
定义文件有三部分内容:
(1)定义文件开头处的版权和版本声明(参见示例1-1);
(2)对一些头文件的引用;
(3)程序的实现体(包括数据和代码)。
假设定义文件的名称为filename.c,定义文件的结构参见示例1-3
示例1-3C定义文件的结构
1.4头文件和定义文件使用(4条规则+6条建议)
【规则1-2-1】在复杂的工程文件中,为了防止头文件被重复引用,应使用ifndef/define/endif结构产生预处理块。
【规则1-2-2】用#include
【规则1-2-3】用#include“filename.h”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。
【规则1-2-4】只引用必需的头文件,不要为了防止忘记包含头文件而在每个文件开始添加很多的头文件。
【建议1-2-1】不要在头文件中定义常量或变量,注意头文件只是用来声明。
【建议1-2-2】不提倡使用全局变量,尽量不要在头文件中出现像“externintwidth;”这类声明。
【建议1-2-3】将非系统的函数库放在一个单独的目录下引用。
【建议1-2-4】头文件应按功能组织在一起,即对单独子系统的声明应放在单独的头文件中。
此外,当代码从一个平台移植到另一个平台时有可能发生更改的声明应位于单独的头文件中,并进行相应的注释。
【建议1-2-5】避免使用与函数库中专用头文件名相同的头文件名。
语句#include"math.h"如果在当前目录中找不到所期望文件的话,会包括标准库math头文件。
【建议1-2-6】包含头文件时一般不使用绝对路径名。
2.程序版式(35条规则+2条建议)
2.1空行(4条规则)
空行起着分隔程序段落的作用,空行得体将使程序的布局更加清晰。
空行不会浪费内存,所以不要舍不得用空行。
【规则2-1-1】在函数内部局部变量定义结束之后处理语句之前要加空行。
【规则2-1-2】在每个函数定义结束之后都要加空行。
参见示例2-1(a)。
【规则2-1-3】函数返回语句和其他语句之间使用空行分开。
【规则2-1-4】在一个函数体内,逻辑上密切相关的语句之间不加空行,其它地方应加空行分隔。
参见示例2-1(b)。
示例2-1(a)函数之间的空行示例2-1(b)函数内部的空行
2.2代码行(5条规则+1条建议)
【规则2-2-1】一行代码只做一件事情,如只定义一个变量,或只写一条语句。
这样的代码容易阅读,并且方便写注释。
【规则2-2-2】if、for、while、do等语句自占一行,执行语句不得紧跟其后。
不论执行语句有多少都要加{}表明是一个语句块。
【规则2-2-3】一对花括号要单独各占一行。
但是在do-while、struct和union及其后有‘;’的除外,要同在一行。
例如:
【规则2-2-4】switch语句中的每个case语句各占一行,当某个case语句不需要break语句最好加注释声明。
【规则2-2-5】并列的语句行应该按照字母顺序排序,如变量定义和switch中的case语句等。
【建议2-2-1】尽可能在定义变量的同时初始化该变量(就近原则),如果变量的引用处和其定义处相隔较远,变量的初始化很容易被忘记。
如果引用了未被初始化的变量,可能会导致程序错误。
本建议可以减少隐患。
例如:
intwidth=20;/*定义并初绐化width*/
intheight=20;/*定义并初绐化height*/
intdepth=20;/*定义并初绐化depth*/
风格良好的代码行
风格不良的代码行
intwidth;/*宽度*/
intheight;/*高度*/
intdepth;/*深度*/
intwidth,height,depth;/*宽度高度深度*/
x=a+b;
y=c+d;
z=e+f;
x=a+b;y=c+d;z=e+f;
if(width { dosomething(); } if(width for(initialization;condition;update) { dosomething(); } //空行 other(); for(initialization;condition;update) dosomething(); other(); 2.3代码行内的空格(6条规则+1条建议) 【规则2-3-1】关键字之后要留空格。 象const、case等关键字之后至少要留一个空格,否则无法辨析关键字。 象if、for、while等关键字和紧跟的左括号‘(’之后应留一个空格,右括号前也对应要留一个空格,以突出关键字。 例如: if(a==b) 【规则2-3-2】函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别。 例如: voidcalc(void); 【规则2-3-3】“,”之后要留空格,如Function(x,y,z)。 如果‘;’不是一行的结束符号,其后要留空格,如for(initialization;condition;update)。 【规则2-3-4】不要在单目运算符(如“! ”、“~”、“++”、“--”、“&”)和其操作对象间加空格。 例如: ! foo,++i,(long)getValue 【规则2-3-5】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”、“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应当加空格。 【规则2-3-6】象“[]”、“.”、“->”这类操作符前后不加空格。 例如: big.bar,pFile->bar,big[bar] 【建议2-3-1】对于表达式较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格. 例如: for(i=0;i<10;i++)和if((a<=b)&&(c<=d)) 风格良好的空格 风格不良空格 voidFunc1(intx,inty,intz); voidFunc1(intx,inty,intz); if(year>=2000) if((a>=b)&&(c<=d)) if(year>=2000) if(a>=b&&c<=d) for(i=0;i<10;i++) for(i=0;i<10;i++) for(i=0;i<10;i++) x=a a: b; x=a a: b; int*x=&y; int*x=&y; array[5]=0; a.Function(); b->Function(); array[5]=0; a.Function(); b->Function(); 2.4对齐(4条规则) 【规则2-4-1】程序的分界符‘{’和‘}’应独占一行并且位于同一列,同时与引用它们的语句左对齐。 【规则2-4-2】水平缩进每次使用四个空格即可(定义一个tab键为四个空格。 有的要求缩进两个空格)。 【规则2-4-3】同属于一个语句块的代码对齐。 【规则2-4-4】{}之内的代码块在‘{’右边一个tab键处左对齐。 风格良好的对齐 风格不良的对齐 voidFunction(intx) { programcode } voidFunction(intx){ programcode } if(condition) { programcode } else { programcode } if(condition){ programcode } else{ programcode } for(initialization;condition;update) { programcode } for(initialization;condition;update){ …programcode } while(condition) { programcode } while(condition){ …programcode } 如果出现嵌套的{},则使用缩进对齐,如: { { } } 2.5长行拆分(2条规则) 【规则2-5-1】代码行最大长度宜控制在70至80个字符以内。 代码行不宜过长,否则不便于阅读,也不便于打印。 【规则2-5-2】长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。 拆分出的新行要进行适当的缩进,使排版整齐,语句可读。 if((very_longer_variable1>=very_longer_variable12) &&(very_longer_variable3<=very_longer_variable14) &&(very_longer_variable5<=very_longer_variable16)) { dosomething(); } virtualCMatrixCMultiplyMatrix(CMatrixleftMatrix, CMatrixrightMatrix); for(very_long_initialization; very_long_condition; very_long_update) { dosomething(); } 示例2-5长行的拆分 2.6修饰符的位置(1条规则) 【规则2-6-1】将修饰符*和&紧靠变量名,以免引起误解。 例如: char*name; int*x,y;/*此处y不会被误解为指针*/ 2.7注释(12条规则) C语言的注释符为“/*…*/”和“//”。 注释通常用于: (1)版本、版权声明; (2)函数接口说明,包括参数类型和意义、函数类型和意义等; (3)重要的数据类型声明、变量、算法、处理、段落等提示。 “//”为行注释。 【规则2-7-1】注释是对代码作用的“提示”,而不是文档。 注释的频度要合适,一般要求占程序总行数的1/5~1/4。 【规则2-7-2】边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。 不再有用的注释要删除。 【规则2-7-3】注释应准确、易懂,防止注释有二义性。 错误的注释不但无益反而有害。 【规则2-7-4】尽量避免在注释中使用缩写,特别是不常用的缩写。 根据维护程序的对象确定使用中文还是使用英文。 【规则2-7-5】注释的位置应与被描述代码相邻,可以放在代码的上方或右方,一般不宜放在下方。 【规则2-7-6】当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读。 【规则2-7-7】尽量不要在语句指令中添加注释。 【规则2-7-8】注释不具备约束使用者行为的能力。 【规则2-7-9】给一行代码添加注释最好使用“//”,比较清楚。 【规则2-7-10】不要使用/**/注释掉大量代码,而要使用#if0条件编译语句 例如: 【规则2-7-11】行末注释最好对齐。 【规则2-7-12】应对包含的头文件进行行末注释。 3.标识符命名(15条规则+1条建议) 共性规则是被大多数程序员采纳的,我们应当在遵循这些共性规则。 命名两个基本原则: 1.含义清晰,不易混淆; 2.不与其它模块、函数的命名空间相冲突。 【规则3-1-1】标识符要清楚、准确、简单而且尽量可发音的英文名字。 例如: intreturnStatus; 不要把currentValue写成nowValue。 【规则3-1-2】标识符的长度应当符合“min-length&&max-information”(最短并包含信息最多)原则。 单字符的名字也是有用的,常见的如i、j、k、m、n、x、y、z等,它们通常可用作函数内的局部变量。 【规则3-1-3】命名规则尽量与所采用的操作系统或开发工具的风格保持一致。 例如Windows应用程序的标识符通常采用“大小写”混排的方式,如printStudent;而Unix应用程序的标识符通常采用“小写加下划线”的方式,如print_student。 别把这两类风格混在一起用。 【规则3-1-4】尽量选择通用词汇并保持整个软件风格一致。 例如: 使用get、read、fetch、retrieve都能表达“取出”的意思,一旦软件采用哪一个则应贯穿始终。 【规则3-1-5】程序中不要出现仅靠大小写区分的相似的标识符。 例如: intx,X;/*变量x与X容易混淆*/ voidfoo(inty);/*函数foo与FOO容易混淆*/ voidFOO(floaty); 【规则3-1-6】程序中不要出现标识符完全相同的局部变量和全局变量,尽管可能两者的作用域不同而不会发生语法错误,但会使人误解。 【规则3-1-7】变量的名字应当使用“名词”或者“形容词+名词”。 例如: floatvalue; floatnewValue; 【规则3-1-8】用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。 例如: intMinValue; intMaxValue; intMinValue(void); intMaxValue(void); 【规则3-1-9】变量和参数首字母小写,其后每个英文单词的第一个字母大写,其它小写。 例如: intrecWidth; 【规则3-1-10】标识布尔型的变量或函数名称一般使用is作为前缀。 例如: voidisFull(); 【规则3-1-11】常量全用大写字母,用下划线分割单词。 constintMAX_LENGTH=100; 【规则3-1-12】静态变量加前缀s_(表示static)。 staticints_initValue;/*静态变量*/ 【规则3-1-13】如果需要定义全局变量,则变量加前缀g_(表示global)。 例如: intg_howStudent;/*全局变量*/ 【规则3-1-14】函数名用大写字母开头的单词组合而成。 由多个单词组成的标识符每个单词首字母大写。 其它小写。 例如: InputStudInfo();//全局函数 【规则3-1-15】一般错误包裹函数名全部大写。 例如: 可以定义成下面的包裹函数 以后调用的话,则可以使用下面的简洁方式: FILE*pFile=FOPEN("readme.txt","rw++"); 【建议3-1-1】尽量避免名字中出现数字编号,如value1、value2等,除非逻辑上的确需要编号。 4.常量(7条规则) 常量是一种标识符,它的值在运行期间恒定不变。 C语言用#define来定义常量。 除了#define之外还可以用const来定义常量。 4.1const与#define的比较(2条规则) C语言可以用const来定义常量,也可以用#define来定义常量。 但是前者比后者有更多的优点: (1)const常量有数据类型,而宏常量没有数据类型。 编译器可以对前者进行类型安全检查。 而对后者只进行字符替换,没有类型安全检查,并且在字符替换过程中可能会产生意料不到的错误。 (2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。 【规则4-1-1】尽量使用含义直观的常量来表示那些将在程序中多次出现的数字或字符串。 例如: #defineMAX100//C语言的宏常量 constfloatPI=3.14159;//C语言的const常量 【规则4-1-2】尽量使用const定义常量替代宏定义常量。 4.2常量定义(5条规则) 【规则4-2-1】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的头部。 为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。 【规则4-2-2】如果某一常量与其它常量密切相关,则应在定义中包含这种关系,而不应给出一些孤立的值。 例如: constfloatRADIUS=100; constfloatDIAMETER=RADIUS*2; 【规则4-2-3】enum中的枚举常量应以大写字母开头或全部大写。 【规则4-2-4】如果宏值多于一项,一定使用括号。 例如: #defineERROR_DATA_LENGTH10+1 应该这样定义: #defineERROR_DATA_LENGTH(10+1) 这样使用malloc(5*ERROR_DATA_LENGTH)时,得到是5*(10+1)=55;而上面的定义则得到5*10+1=51。 【规则4-2-5】函数宏的每个参数都要括起来。 例如: #defineWEEKS_TO_DAYS(w)(w*7) 应该写成: #defineWEEKS_TO_DAYS(w)((w)*7) 这样在翻译totalDays=WEEKS_TO_DAYS(1+2)时,才能够正确地翻译成: (1+2)*7;否则将错误地翻译成1+2*7。 5.变量(11条规则) 【规则5-1-1】局部变量在引用之前要进行出初始化或要有明确的值。 【规则5-1-2】如果指针变量知道被初始化为什么地址,则初始化为该地址,否则初始化为NULL。 【规则5-1-3】所有的外部变量声明前都应加上extern关键字。 【规则5-1-4】尽量不要使用一个bit位控制程序流程或标识特定状态。 最好使用多位或枚举类型标识状态。 【规则5-1-5】如果定义数组时全部初始化,则不用给出数组长度。 例如: intarray[]={1,2,3,4,5}; 在需要使用数组长度时,用sizeof(array)/sizeof(array[0])计算得出。 【规则5-1-6】不同文件的全局变量没有固定的初始化顺序,注意使用#include包括的文件都算作同一文件。 【规则5-1-7】尽量避免强制类型转换;如果不得不使用,则尽量使用显式方式。 【规则5-1-8】不要强制指针指向尺寸不同的目标。 例如: intFunction(constchar*pChar) { int*pInt=(constint*)pChar;/*危险操作*/ return(*pInt); } 【规则5-1-9】尽量少使用无符号类型,其在混合表达式中可能隐式转换造成错误。 【规则5-1-10】尽量少的使用浮点类型,因为浮点数据标识不精确,而且运算速度慢。 【规则5-1-11】尽量少用union类型,因为成员共用内存空间,处理不当容易出错。 6.表达式和基本语句(17条规则+3条建议) 6.1运算符的优先级(1条规则) 【规则6-1-1】避免使用默认的优先级。 如果代码行中的运算符比较多,为了防止产生歧义并提高可读性,应当用括号明确表达式的计算顺序。 例如: value=(high<<8)|low if((a|b)&&(a&c)) 6.2复合表达式(4条规则) 如a=b=c=0这样的表达式称为复
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 编程 规范 10