编程规范化.doc_第1页
编程规范化.doc_第2页
编程规范化.doc_第3页
编程规范化.doc_第4页
全文预览已结束

下载本文档

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

文档简介

前言做为一个编程员,应该尽早培养自己的编程规范。这些规范可以保持工程文件的一致性,和降低对工程文件的维护,因此很有必要。下面的几个习惯有助于我们增加产品的功能和简化工程的维护。有许多风格可以用来编写我们的C语言程序。但你的风格要能够使你的程序达到以下几点:可移植性持续性整洁易于维护易于理解简单无论你采用哪种风格,我要强调的是,这种风格应该贯穿你的整个工程。除此之外,我还要强调的是,在一个大的工程中,这种风格应是所有项目小组成员所能习惯采用的。采用相同的编程风格能够减少程序的维护问题和代价,同时也可避免不必要的返工。下面就介绍我所一直采用的编程风格。2.00 基本原则这些标准的根本目的是促进代码的可维护性。这样就要求你的程序代码必须便于阅读,便于理解,便于检验和便于移植。勇于树立标准在你编写程序时,如果你发现还没有一种直接的标准,你应该勇于树立标准所有的代码必须符合ANSI C规范保持代码的简洁性直接了当避免语言含蓄晦涩,应该直接说出你的意思。持续性尽量采用同一种规定避免复杂的声明包含多个意思的声明会很难理解不要使用goto更新旧的代码在对已有文件进行修改时要更新相关说明文档。源文件 行的宽度 不要因为以前的显示器只能够显示80个字符而限制一行代码的长度。代码的宽度应该基于8.5*11的页面以合适的字体大小能够打印多少字符。你应该能够能够安排下132个字符,并且在页面的左边要有足够的空间用来将文档装订成册。每行132个字符可以阻止注释嵌在代码中。如果一行需要更多有字符才能够让你的代码更清楚,便不应该将代码限制在132个字符之内。实际上,你可以让你的代码宽度达到300多个字符。当然,你不可能看出(或者打印)所有的部分,但是至少在不同的地方,代码是排列整齐的。TAB字符的使用不能够使用TAB字符,缩进必须用空格来完成。制表符TAB的宽度在不用的电脑和打印机是不同的,避开使用它可以预定间距不变。缩进是4个空格缩进由4个空格组成。注意:case语句要缩进5个字符。在4的倍数个空格后开始编写代码,如第1、5、7、9列等。包含一个文件的标题在每个文件的开头,包含一段注释,明说公司的名称、地址、版权,程序员和文件内容的描述等等。看下面的:/* * * Company Name * Company Address * City, State ZIP * Country * * (c) Copyright YYYY, Company Name, City, State * * All rights reserved. Company Names source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code contains * confidential, trade secret material of Micrium, Inc. Any attempt or participation * in deciphering, decoding, reverse engineering or in any way altering the source * code is strictly prohibited, unless the prior written consent of Company Name * is obtained. * * Filename : * Programmer(s) : Joe Programmer (JP) * John Doe (JD) * Created : YYYY/MM/DD * Description : */ 执行文件包含执行语句然而头文件没有。这两种文件应该使用相同的书写格式。这些文件应该包含下面所列的所有或者其中的部分。没有的可以省略,但是如果存在则必须以下面的顺序列出: 执行文件格式:文件标题 版本#include#define 常量 宏局部结构体局部变量局部数组内部函数声明(顺序应与它们被执行的顺序相同)外局函数定义内部函数定义 头文件格式 文件标题 版本 #define 常量 全局宏 全局结构体 全局变量Externals外部函数声明(顺序与执行文件的定义顺序相同,独立的部分应在其它文件中声明)#error 区域(不合法的#define和漏掉的标志)各个部分要分开每一个区域在前面都应该有一个注释段,看下面的例子/* * * DATA TYPES */ typedef unsigned char BOOLEAN; /* * PROTOTYPES * */ BOLEAN OSIsTaskRdy(void); 通过检测某个值的定义保证头文件没有被重复包含 注意:!Defined(x)比#ifndef x更可取#if !defined(module_h)#define module_H 头文件的内容#endif通过使用 #error 来标志丢失的#define,并且检查无效的值 标准的C预处理语句#error应该被用来提醒程序员#define常量或宏没有出现,或者一个#define 常量超过它的实际大小。这样的声明应该能在一个模块的头文件中找到。当某个条件没有满足时#error应该显示出相关的错误信息。#ifndef OS_MAX_TASKS #error OS_CFG.H, Missing OS_MAX_TASKS: Max. number of tasks in your application #else#if OS_MAX_TASKS = 2 #endif #if OS_MAX_TASKS 63 #error OS_CFG.H, OS_MAX_TASKS must be = 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+; else ClkMin+; else ClkSec+; 用#if 0和#endif 注释掉不要程序段注释绝不能够嵌套!取而代之,你可以用#if 0和#endif 来注释掉很长的程序代码#if 0 /* 说明你要注释掉这段代码的原因 */ #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#endif 一对注释符不能注释几个行决不能这样:/* This type of comment can lead to confusion especially when describing a function like ClkUpdateTime (). The function looks like actual code! */ 不同部分的代码要用注释块来分开注释块如下所示。注意,注释块的标题要放在中间,而且要用大写字母。注释中不能出现带有感情色彩的句子比如,不要用这样的注释:Lets make this one big happy structure !语言要尽量的有组织,可以用大写字母来强调其中的意思,如果其它人都能够理解,可以使用助记符,缩写词。注释尽量要尾随代码尽可能的在同一行注释代码。如果代码太长需要占用几行的位置,注释应该放在最上面的一行。尽可能的把注释符对齐,这样可以使代码和注释一眼就能分开。void ClkUpdateTime (void) if (ClkSec = CLK_MAX_SEC) /* Update the seconds */ ClkSec = 0; if (ClkMin = CLK_MAX_MIN) /* Update the minutes */ ClkMin = 0; if (ClkHour = CLK_MAX_HOURS) /* Update the hours */ ClkHour = 0; else ClkHour+; else ClkMin+; else ClkSec+; 用特别的注释来说明现存的漏洞,以前和未来的implementations。比如说,你可以用下面的方法。你能够方便的搜索你的程序来找到这样的例子/*? Bug or known technical issue */ /*$ Future function that needs to be implemented */ /* Old code to leave as-is because */ 5.00 命名习惯一般的习惯 #define 常量 #define 宏 数据类型定义: 枚举量: 全部用大写字符 单词用下划线(_)分开例子:DISP_BUF_SIZE, MIN(), MAX() 局部变量:全部用小写字符单词用下划线(_)分开用标准名称(如:i,j,k用于循环计数器,p用于指针)文件作用域内的变量(静态外部变量) 在前面加上该模块的名称和下横线 单词的首字母大写 声明为 static 例如:Disp_Buf,Comm_Ch全局变量: 以模块名为前缀 单词的首字母要大写 例如:DispMapTbl,CommErrCtr内部函数 以模块名为前缀并在后面加下划线(_) 单词的首字母要大写 声明为“static” 例如:static void Comm_PutChar()外部函数 以模块名为前缀 单词的首字母要大写 例如:void CommmInit() 名字用每个单词的首字母分开 使用首字母略缩词和缩写词、助记码 可以创建一个基本的首字母缩写,简称和助记码的字典,供所有人使用。下面是一部分例子:用模块-对象-操作的格式 在创建一个全局常数,变量,函数时,首先指定模块的名称,然后是对象的名称最后是操作的名称。Acronyms, Abbreviation and Mnemonics (AAM) Dictionary Description Acronym, Abbreviation, or Mnemonic Argument Arg Buffer Buf Clear Clr Clock Clk Compare Cmp Configuration Cfg Context Ctx Delay Dly Device Dev Display Disp Error Err Function Fnct Hexadecimal Hex High Priority Task HPT I/O System IOS Initialize Init Mailbox Mbox Manager Mgr Maximum Max Message Msg Minimum Min Operating System OS Overflow Ovf Pointer Ptr Previous Prev Priority Prio Read Rd Ready Rdy Schedule Sched Semaphore Sem Stack Stk Synchronize Sync Timer Tmr Trigger Trig Write Wr 坚持使用标准首字母略缩词、缩写词和记忆术 坚持使用首字母略缩词和缩写词即使你愿意写下整个单词。例如:要使用 Init而不是Initialize! 6.00 数据类型所有的数据类型必须全部用大写字母来声明 单词需要用下划线来分开 使用可以移植的数据类型要避免使用所有的C的数据类型,因为它们的大小是不可以移植 的。取而代之的应该是下面的数据类型Typedef unsigned char BOOLEAN; /* 逻辑类型 (TRUE 或 FALSE) */ typedef unsigned char CHAR; /* 无符号8位char */ typedef unsigned char INT08U;/* 8位无符号整数类型 */ 两个空格typedef signed char INT08S; /* 8位有符号整数类型 */ typedef unsigned int INT16U; /* 16位无符号整数类型 */ typedef signed int INT16S; /* 16位有符号整数类型 */ typedef unsigned long INT32U; /* 32位无符合整数类型*/ typedef signed l long INT32S; /* 32位有符号整数类型e */ typedef float FP32; /* 32位浮点数据类型 */ typedef double FP64; /* 64 位数据类型 */ 结构体和联合体必须先定义类型所有结构体和联合体必须用下面的格式定义,并且数据类型必须使用大写字母。typedef struct char RxBufCOMM_RX_SIZE; /* Storage of characters received */ char *RxInPtr; /* Pointer to next free loc. in buffer */ char *RxOutPtr; /* Pointer to next char. to extract */ INT16U RxCtr; /* Number of characters in Rx buffer */ char xBufCOMM_TX_SIZE; /* Storage for characters to send */ char *TxInPtr; /* Pointer to next free loc. in Tx Buf */ 缩进4个字符char *TxOutPtr; /* Pointer to next char to send */ INT16U TxCtr; /* Number of characters left to send */ COMM_BUF; 结构成员结构体的成员必须缩进4个空格,而且上下要排成一条直线。注意,注释也要在同一列开始注释。数据的作用域 如果一个数据类型只在执行文件中使用,那么它必须在执行文件中声明。如果它是全局的,那么必须把它放在模块的头文件中。7.00格式 每行只能有一条语句例1: DispSegTblIx = 0; DispDigMsk = 0x80; 而非: DispSegTblIx = 0; DispDigMsk = 0x80; 例2: ptcb+; *ptcb = (OS_TCB *)0; 而非: *+ptcb = (OS_TCB *)0;Separate code chuncks with blank lines or comments 在调用函数时,函数名与圆括号之间没有空格DispInit(); 至少需要一个空格用在函数的形参之后DispStr(x, y, s);单目运算符和操作数之间没有空格!value bits +i j- (INT32U)x *ptr &x sizeof(x) 双目运算符和它的操作数之间至少有一个空格至少一 个空格c1 = c2; x + y i += 2; n 0 ? n : -n; a = 2 在每个分号(“;”) 之后至少要有一个空格for (i = 0; i b) while (x 0) for (i = 0; i 0) y = 10; Z = 5;if (z LIM)x = y + z; z = 10;多个“=”要对齐“;”后面要留一个空格elsex = y - z; z = -25;for (i = 0; i 0);switch (key)case KEY_BS: if (cnt 0)p-; cnt-;case后面跟5个空格Break;case KEY_LINE_PEND: p+ break;default: break;9.00 函数 函数的格式应该如下所示/* * 注释块的格式可以是这样的,选择一种适合你的格式后,不要轻易改变* static void AI_Upadata (void)*功能: 更新AD口的模拟信号输入. * * 参数:无 * * 返回值:无 返回类型声明的两边要空两格* * 注意事项 :无 * */ 内部函数就该在模块名后面加上一条下划线static void AI_Update (void) 函数名后面就空上一格,但应注意只在定义时才空一格,这样可以方便自己快速找到函数的定义位置 INT8U i; AIO *paio; paio = &AITbl0; /* Point at first analog input channel */ 局部变量和程序代码间应空两行 for (i = 0; i AIOBypassEn = FALSE) /* See if analog input channel is bypassed */ 不要在声明一个局部变量时,便初始化该变量paio-AIOPassCtr-;/* Decrement pass counter */ if (paio-AIOPassCtr = 0) /* When pass counter reaches 0, read and scale AI */ paio-AIOPassCtr = paio-AIOPassCnts; /* Reload pass counter */ paio-AIORaw = AIRd(i); /* Read ADC for this channel */ paio-AIOScaleIn = (FP32)paio-AIORaw + paio-AIOOffset) * paio-AIOGain; 一条语句不要超过第120列,如果一行写不下,接着下一行的开始写,并且为“*”应与“=”对齐 if (void *)paio-AIOScaleFnct != (void *)0) /*See if scaling function defined */ (*paio-AIOScaleFnct)(paio); /* Yes, execute function */ else paio-AIOScaleOut = paio-AIOScaleIn; /* No, just copy data */ paio-AIOEU = paio-AIOScaleOut; /* Output of scaling fnct to E.U. */ 注释跟在代码后面,注意注释的长度不要超过121列 paio+; /* Point at next AI channel */ 具有多个形参的函数当一个函数具有多个形参时,用一行把所有的形参列出来往往不容易让人理解。因此,用下面的格式来声明一个函数:INT8U OSTaskCreateExt ( 缩进四个空格void (*task)(void *pd), void *pdata, OS_STK *ptos, 形参的所有首字母就对成一条线INT8U prio, INT16U id, OS_STK *pbos, INT32U stk_size, void *pext, INT16U opt) /* Function body */ 每页一个函数尽可能一个函数用一页,如果有多个非常小的函数,也可以把它们写在同一张页面上。然而,它们必须包含这些函数的注释块,写完一个函数后,应该先空两到三行再写下一个函数。一个函数书写完成后,应该适合一页纸的大小。很少有函数的长度连续超过几页的,如果不得不这样,那也应该在合理的位置跳页。如果一个函数只在当前文件使用,则必须把它声明为 static ,以避免被其它文件调用。初始化数组把数组中相同的部分排成一条直线有时经常用到像下面例子中的结构数组,你应该注意在初始赋值时把它们整齐的排成一列一列。这样可以增加程序的易读性。typedef struct INT16U ParamNbr; void *ParamAddr; void *ParamMin; void *P

温馨提示

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

评论

0/150

提交评论