嵌入式系统中的C语言编码规范_第1页
嵌入式系统中的C语言编码规范_第2页
嵌入式系统中的C语言编码规范_第3页
嵌入式系统中的C语言编码规范_第4页
嵌入式系统中的C语言编码规范_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式系统中的C语言编码规范2004-11 范围本文件规定了书写程序代码时的一般规则和要求。本文件适用于研发中心监控硬件室的嵌入式程序开发过程。2 原则2.1 目的为了统一在项目开发中的程序编码风格,提高代码的编写质量和可重用性,使代码具有如下的特点:可移植性,一致性,易维护性,易理解性,整洁、简朴和清晰。2.2 基本原则1) 书写的所有C语言代码应遵守ANSI C规范。2) 保持代码简洁。3) 语言描述直接、清晰。4) 风格要保持一致。5) 要避免语句复杂。6) 慎重使用GOTO语句。7) 及时更新旧代码。8) 注释要通俗易懂,不产生歧义。3 源文件3.1 注意代码行的宽度代码行的宽度不可太

2、长,以避免代码在显示器上显示时和被打印出来后的清单不便阅读。较长的语句要分成多行书写,划分出的新行要进行适当的缩进,使排版整齐,语句易读。如果能够做到:“长表达式在低优先级操作符处划分新行,操作符放在新行之首”,就最好。3.2 关于制表符(TAB)因为TAB符(ASCII码为0x09)在不同的计算机和打印机上所表现的可能不同,使得维护不便。要使用合适数量的空格符(ASCII码为0x20)代替TAB来对齐文字。3.3 使用4个空格的缩进方式程序块要采用缩进风格编写,缩进的空格数为4,缩进只使用空格键,不用TAB键。3.4 程序块的分界符程序块的分界符(大括号“”和“”)应各独占一行并且位于同一列

3、,同时与引用它们的语句左对齐。在函数体的开始、结构体的定义、联合体的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。3.5 关于文件头和函数头部的注释源文件(包括说明性如:头文件.h文件、.inc文件、.def文件、编译说明文件.cfg等)头部应放置注释文字,注释必须列出:版权说明、版本号、完成日期、作者、内容、模块目的/功能、主要函数及其功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。函数头部也应进行注释,注释时要列出:函数名、函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等(必要时要

4、举例说明函数的使用方法)。3.6 文件书写的层次实现文件(.C文件)的层次:File headingRevision history#include#define constantsMacrosLocal data typesLocal variablesLocal tablesLocal function prototypesGlobal functionsLocal functions声明文件(.H文件)的层次:File headingRevision history#define constantsGlobal macrosGlobal data typesGlobal variable

5、sExternalsGlobal function prototypes3.7 用注释将各个主要段分隔使用如下的方式分隔:/* Data Types*/typedef unsigned char BOOLEAN;/* Prototypes*/BOOLEAN TaskRdy(void);空行起着分隔程序段落的作用,空行得体(不过多也不过少)将使程序的布局更加清晰。3.8 必须要采取一定的措施防止头文件被重复引用比如在使用HIWARE的HI-CROSS+编译器时可以使用如下的方法:#ifndef _MAIN_H#define _MAIN_H Body of the header file.#end

6、if3.9 使用#include用#include filename.h格式来引用标准库的头文件(编译器将从标准库目录开始搜索),用#include “filename.h”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。4 注释4.1 原则上使用中文注释。4.2 使每行注释都有其价值一般情况下,源程序有效注释量必须在20以上。写注释时要明智些!如果一段代码的逻辑关系很复杂,注解将有助于别人理解代码的意图。但如果逻辑关系直线向前,避免加上并非必须的注解。注释使用的语句要简洁,表达要清晰、准确,不要使人产生歧义,不可喧宾夺主。4.3 分开注释和代码,而不要混在一起。以免阅读代码时

7、注意力被分散尽可能少的在代码语句中嵌入注释,不要象下面的例子中的那样。void ClkUpdateTime (void) /* DO NOT comment like this! */ /* Update the seconds */ if (ClkSec = CLK_MAX_SEC) ClkSec = 0; /* Update the minutes */ if (ClkMin = CLK_MAX_MIN) ClkMin = 0; /* Update the hours */ if (ClkHour = CLK_MAX_HOURS) ClkHour = 0; else ClkHour+; e

8、lse ClkMin+; else ClkSec+; 4.4 注释要醒目,要使其易于同代码区分出来不要象下面的例子中的那样。/* This type of comment can lead to confusion especially when describing a function like ClkUpdateTime (). The function looks like actual code! */4.5 尽可能将注释放在语句尾部,并且对齐注释。4.6 使用合适的方法来屏蔽暂时不执行的代码块可以使用如下的方法来屏蔽暂时不执行的代码块,而不要修改注释。#if 0 /* Commen

9、ts out the following code */#define DISP_TBL_SIZE 5 /* Size of display buffer table */#define DISP_MAX_X 80 /* Max. number of characters in X axis */#define DISP_MAX_Y 25 /* Max. number of characters in Y axis */#define DISP_MASK 0x5F#endif5 命名规则5.1 总约定直观且可以拼读,可望文知义。标识符最好采用英文单词或其组合,便于记忆和阅读。切忌使用汉语拼音来

10、命名。#define constants:#define macros:typedefs:enum tags:所有的字母都用大写形式;标识符中的各个单词之间用下划线分开;Examples: DISP_BUF_SIZE, MIN(), MAX(), etc.Local variables (i.e. function scope):所有的字母都用小写形式;标识符中的各个单词之间用下划线分开;Use standard names (e.g. i, j, k用来作循环变量, p作指针变量等)File scope variables:用模块名称作前缀并使用下划线与后面分开;标识符中的各个单词之间用首字

11、母大写的方法来分隔开;要定义为静态;Examples: Disp_Buf, Comm_Ch, etc.Global variables:用模块名称作前缀;标识符中的各个单词之间用首字母大写的方法来分隔开;Examples: DispMapTbl, CommErrCtr, etc.Local functions:用模块名称作前缀并使用下划线与后面分开;标识符中的各个单词之间用首字母大写的方法来分隔开;要定义为静态;Example: static void Comm_PutChar()Global functions:用模块名称作前缀;标识符中的各个单词之间用首字母大写的方法来分隔开;Exampl

12、e: void CommInit()5.2 宏和自定义的数据类型,所有的字母都用大写形式。5.3 尽量避免局部变量与全局变量同名,如果必须同名一定要使用注释来说明。不要出现仅靠大小写区分的相似的标识符。5.4 用大写首字母的方式来分开名字中的几个词。5.5 使用公认的缩写(包括国际通用和项目专用的)经常用到的程序术语约定表可见附录。5.6 在命名时使用“模块名-对象-动作”、“形容词-名词”或“名词”的格式。6 关于数据类型6.1 所有的自定义数据类型都应该使用大写字母标识符中的各个单词之间用首字母大写的方法来分隔开。6.2 使之便于移植可以采用如下的方法:typedef unsigned c

13、har BOOLEAN; /* Logical data type (TRUE or FALSE) */typedef unsigned char INT8U; /* Unsigned 8 bit value */typedef signed char INT8S; /* Signed 8 bit value */typedef unsigned short INT16U; /* Unsigned 16 bit value */typedef signed short INT16S; /* Signed 16 bit value */typedef signed short INT32U; /

14、* Unsigned 32 bit value */typedef signed short INT32S; /* Signed 32 bit value */typedef signed short INT64U; /* Unsigned 64 bit value (if available)*/typedef signed short INT64S; /* Signed 64 bit value (if available)*/typedef float FP32; /* 32 bit, single prec. floating-point */typedef double FP64;

15、/* 64 bit, double prec. floating-point */6.3 数据作用范围如果数据只在执行文件(.C文件)中使用,就一定要定义在此执行文件中。如果是全局变量,就一定要定义在头文件(.H文件)中。7 层次7.1 每行只写一条语句。如:DispSegTblIx = 0;DispDigMsk = 0x80;而不是:DispSegTblIx = 0; DispDigMsk = 0x80;7.2 关于空格7.2.1 函数参数列表中的逗号之后要有一个空格。如下所示:DispStr(x, y, s);7.2.2 分号之后要有一个空格。如下所示:for (i = 0; i 0 ?

16、n : -n;a = 27.2.5 下面的这些操作不要加空格:操作内容举 例- 结构指针p-member. 成员引用s.member 数组下标ai7.3 函数调用语句函数调用语句中,在函数名和圆括号之间不要放空格。如下所示:DispInit();7.4 关键词在if、while、for、switch和return后跟随着放一个空格。如下所示:if (a b)while (x 0)for (i = 0; i 10; i+)switch (x)return (y);case后的语句要缩进5个空格。如下所示:case KEY_CR: *p = NUL; break;case KEY_LINE_FEE

17、D: p+; break;7.5 等号相连多个用等号赋值的语句时,上下要的等号和右边的数字或标识符要对齐。如下所示:DispSegTblIx = 0;DispDigMsk = 0x80;DispScale = 1.25;7.6 关于圆括号在括号括住的内容与括号之间不要有空格。如下所示:x = (a + b) * c;8 函数8.1 一定要定义函数的返回类型,不要省略返回值的类型。8.2 在函数内局部变量定义和代码之间空两行。8.3 书写时,在函数名的后面与定义函数参数的圆括号之间放一个空格。这样可以在方便地查找函数定义,而不会受函数调用语句的影响(在调用函数时不要放这样的空格)。8.4 不要在

18、定义局部变量的同时给其赋初值,而是分成两条语句。8.5 如果参数是指针,且仅作输入用,则应在类型前加const,以防止该指针在函数体内被意外修改。8.6 在函数体的“入口”处对参数的有效性进行检查。9 表达式和基本语句9.1 如果代码中的运算符比较多,就要使用圆括号来明确表达式的操作顺序,避免使用默认的优先级,以防止产生歧义并提高可读性。9.2 必要编写太复杂的复合表达式。不要有多用途的复合表达式。9.3 不可将浮点变量用“= =”或“!=”与任何数字比较。9.4 循环体内工作量最小化。9.5 在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的

19、次数。如下所示:效率低:长循环在最外层效率高:长循环在最内层for (row=0; row100; row+)for (col=0; col5; col+) sum = sum + arowcol;for (col=0; col5; col+)for (row=0; row100; row+) sum = sum + arowcol;9.6 如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。如下所示:效率低但程序简洁效率高但程序不简洁for (i=0; iN; i+)if (condition) DoSomething();else DoOtherthing();if

20、(condition)for (i=0; iN; i+) DoSomething();elsefor (i=0; iN; i+) DoOtherthing();9.7 在for循环体内修改循环变量时要慎重,防止for循环失去控制。9.8 建议for语句的循环控制变量的取值采用“半开半闭区间”写法。9.9 对于switch语句下的每个case语句结尾,不要忘记加break。如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释,以避免产生误解,误认为漏写“break”。9.10 对switch语句必须有default分支。10 其它系统运行之初,要初始化有关变量及运行环境,防止未经初始化的变量被引用。变量的定义集中放在一起。代码中尽量不用具体的大小数字。而是应使用宏定义代替数字,便于以后维护。与硬件相关和与编译器、处理器有关的操作(如:开/关中断、驱动输出引脚、内部定时等操作),建议定义成宏,便于今后维护和移植。仔细定义并明确全局变量的含义、作用、取值范围及全局变量间的关系。去掉没必要的全局变量。当心数据类型转换发生错误。尽量使用显式的数据类型转换(让人知道发生了什么事),避免让编译器静悄悄地

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论