C语言编程规范.ppt_第1页
C语言编程规范.ppt_第2页
C语言编程规范.ppt_第3页
C语言编程规范.ppt_第4页
C语言编程规范.ppt_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

C语言编程规范,背景意义1,注释2,标示符3,类型4,常量,5,声明和定义6,初始化7,算术类型转换8,指针类型转换9,表达式,10,控制表达式11,控制流12,Switch语句13,函数14,指针和数组15,结构体和联合体16,预处理指令17,标准库,背景C语言是开发嵌入式应用的主要工具,然而C语言并非是专门为嵌入式系统设计,相当多的嵌入式系统较一般计算机系统而言对软件安全性(可靠性)有更苛刻的要求,所以因此会带来更多的安全隐患。,阿丽亚娜5型火箭爆炸瞬间,1996年6月4日,阿丽亚娜5型运载火箭的首航,原计划将运送4颗太阳风观察卫星到预定轨道,但因软件引发的问题导致火箭在发射39秒后偏轨,从而激活了火箭的自我摧毁装置。阿丽亚娜5型火箭和其他卫星在瞬间灰飞烟灭。(见图3)后来查明的事故原因是:代码重用。阿5型的发射系统代码直接重用了阿4型的相应代码,而阿4型的飞行条件和阿5型的飞行条件截然不同。此次事故损失3.7亿美元软件缺陷的代价极其昂贵。2002年,美国国家标准与技术研究所的一项研究表明,软件缺陷给美国每年造成的损失高达595亿美元。想想全球这个数额会是多大。,编码规范的意义:C语言在铁路行业的应用,安全可靠性非常重要,所以遵守一定的编程规范的显得尤为重要,公司的C语言编码规范(安全系统)是基于2004年的GuidelinesForTheUseOfTheCLanguageinCriticalSystems而编写。1、养成良好的编码习惯,摒弃那些可能存在风险的编程行为。编写出安全健壮的代码,进而保证我们产品的可靠性、稳定性、安全性;2、增加软件的可读性,便于日后维护;3、遵循良好的共通的编码规范,也是项目开发中相互协作开发的技术基础。,规则2.2(强制)源代码只能采用/*/风格的注释。(MISRAC:2004-Rule2.2)规则2.3(强制)字符序列/*不能在注释中使用。(MISRAC:2004-Rule2.3)任何在注释中出现的“/*“字符序列都是违背本规则的。#includec_standards.h*禁止使用嵌套的注释。*/voidstatic_function(void)*这样的字符序列不符合规则*,规则5.1(强制)内部或外部的标识符的识别都不能依赖于31个字符之后的差异。(MISRAC:2004-Rule5.1)便于编译器识别,代码清晰易读,并保证可移植性。规则5.2(强制)内部标识符不能使用和外部标识符相同的名字,导致在内部范围内隐藏外部标识符。(MISRAC:2004-Rule5.2)示例:int16_ti;voidf(void)int16_ti;/*这是一个不同的内部变量*/i=3;/*代码不易理解,不知道这个i指那个变量*/国军标与本规则对应的准则:过程名禁止被重用;禁止参数与全局变量同名。如下例:,#include“c_standards.h”voidfoo(uint32_tP_1)uint32_tx=P_l;voidstatic_function(void)uint32_tfoo=1u;/*过程名静止被重用。*/#includec_standardsh/*-GlobalDeclarations*uint32_tdwTmp=0;voidstaticp(uint32_tdwTmp)/*禁止参数与全局变量同名。*/*/,规则6.1(强制)普通char类型只能用来存储字符值。(MISRAC:2004-Rule6.1)规则6.2(强制)signed和unsignedchar只能作为数据值存储和使用。(MISRAC:2004-Rule6.2)有三种方式声明char类型:signedchar;unsignedchar和char类型。前两种只能用于数值型数据,后一种用于字符数据。char类型是否具有符号特性与具体的编译器有关。对于声明为char类型的变量,只有三种操作符可以使用,即:=,=,!=。规则6.3(强制)位域只能被定义为unsignedint或者signedint类型。(MISRAC:2004-Rule6.4)本规则与编译器的以下不确定行为有关:未定义的行为:位域中的元素使用signedint/unsignedint以外的类型定义。用int定义位域中的元素时,可能被处理为signedint或者unsignedint,取决于具体的编译器。,规则6.4(强制)signedint类型的位域元素的长度至少为2bit。(MISRAC:2004-Rule6.5)1bit的signedint类型是没有意义的。structbssignedinta:1;/*只有一位没有意义,没有符号位*/signedintb:2;/*符合规则*/signedintc:3;/*符合规则*/bit,*pbit;规则7.1(强制)禁止使用八进制数及八进制转义序列。(MISRAC:2004-Rule7.1),规则8.1(强制)函数都应该有原型声明,且对函数定义和调用可见。(MISRAC:2004-Rule8.1)要求程序使用原型声明,是利用编译器检查函数调用时数据类型的一致性。如果调用函数时,没有进行原型声明,则编译器不会检查出函数形参与实参的个数、类型等的不一致。函数接口问题已经被证明是一些重大软件问题的原因,因此本条规则尤为重要。对外部函数来说,我们建议采用如下方法,在头文件中声明函数(亦即给出其原型),并在所有需要该函数原型的代码文件中包含这个头文件(见规则8.8)。为具有内部链接的函数给出其原型也是良好的编程实践。,规则8.2(强制)无论对一个对象和函数声明或定义时,它的类型都应该显式声明。(MISRAC:2004-Rule8.2)示例:externx;/*错误,没有类型说明*/externint16_tx;/*正确*/consty;/*错误,没有类型说明*/constin16_ty;/*正确*/staticfoo(void);/*错误,没有类型说明*/staticint16_tfoo(void);/*正确*/,规则8.3(强制)每个函数声明中的参数类型及返回值应与函数定义一致。(MISRAC:2004-Rule8.3)函数声明中的参数类型及返回值应与函数定义中的一致,包括typedef名称、限定词都需一致,而不仅仅是基本类型一致。#includec_standards.hFLOAT_32static_function(UINT_32,UINT_16);SlNT_32static_function(UINT_32p_l,UINT_16p_2)/*定义的函数返回值与声明中不一致*/SINT_32result=0;/*returnresult:,规则8.5(强制)头文件中不要定义对象或者函数。(MISRAC:2004-Rule8.5)如果该头文件被多个文件包含,会产生重复定义错误。当源文件包含某一头文件时,预处理器会将头文件的内容在包含指令处展开。显然,在头文件中函数的定义会在其他源文件中一模一样的出现,导致函数被重复定义。解决这一问题的关键是明确一个概念:所有可执行的代码或者对象和函数的定义都应在.C的源文件中,头文件中只能存在其声明。具体的做法是:为全局变量的声明增加extern修饰符,并在相应的.C源文件中定义对象或函数。/*在Globle.h中*/externuint32_tGCounter;/*在GlobleVariables.C中*/uint32_tGCounter;,规则8.7(强制)对象如果只被单个函数访问,应定义在块作用域。(MISRAC:2004-Rule8.7)对象的作用域应尽可能限制在单个函数内,只有在对象需要内部或外部链接属性时才可在文件域声明,此时应遵守规则8.10的约束,即在文件域声明的对象应尽可能具有内部链接属性。如非必要,好的做法是尽量避免全局变量。选择是在最外一层的块域还是在最内一层的块域声明对象,很大程度上是编码风格的问题。规则8.8(强制)一个外部变量或者函数只能在文件中被声明一次。(MISRAC:2004-Rule8.8)一般来讲,对于外部变量和函数的声明都放在一个头文件中,任何定义或引用这些外部对象的源文件需包含这个头文件。示例:/*在FeatureX.h中*/externint16_ta;/*在FeatureX.c中*/int16_ta=0;,规则8.10(强制)所有在文件域中声明的对象或函数应具有内部链接属性(除非必须在别的文件中使用这个对象或函数)。(MISRAC:2004-Rule8.10)如果变量仅在本文件的函数中使用,则应使其具有内部链接属性,即对变量的声明使用static关键字。同理,如果一个函数仅在本文件的其它函数中调用,也使用static关键字。使用static声明是为了确保该标识符仅对本文件可见,因而避免相同的标识符在其它文件或库文件中出现而引起的混淆。规则8.12(强制)如果一个数组具有外部链接属性,那么它的大小需显式说明,或者通过初始化隐式定义。(MISRAC:2004-Rule8.12)示例:externintarray2/*可以通过编译,但不满足本规则*/externintarray310/*满足规则*/intarray110;/*满足规则*/intarray2=1,2,3;/*满足规则*/,规则9.1(强制)所有自动对象变量在使用之前都应该赋值。(MISRAC:2004-Rule9.1)本规则与编译器的以下不确定行为有关:未定义的行为:一个存储属性为auto的对象在初始化之前的值。本条款的目的是确保所有的变量在引用之前已经被写入了确定的值。但本规则不要求必须在定义的时候初始化。根据ISO标准,如果没有显式的初始化,具有静态存储属性的变量默认会自动初始化为0。但实际上许多嵌入式编译环境并没有执行这个操作。静态存储指一种存储属性,使用static关键字声明、或具有外部链接属性的变量具有静态存储属性。具有auto存储属性的变量通常不会自动初始化。voidstatic_function(void)intt,k;t=k+1;/*k在定义前被使用*/,规则9.3(强制)枚举列表中,“=“只能用于第一个成员初始化(除非所有的成员都已初始化)。(MISRAC:2004-Rule9.3)如果一个枚举列表没有显式的初始化,C语言会从0开始递增为每个元素自动赋值。如果只为第一个元素显式的赋值,则后续元素从第一个元素的值开始,自动依次递增。使用这种方法初始化枚举列表是本规则允许的,但需要确认后续的值不会超过int表示的范围。对所有元素显式的初始化也是本规则允许的,但不允许自动赋值和人工赋值混和。同时,程序员应确认所有的值都在规定范围内。示例:enumcolorred=3,blue,green,yellow=5;/*不符合本规则*/enumcolorred=3,blue=4,green=5,yellow=5;/*符合本规则*/,规则10.1(强制)以下情况下,整型表达式的值不允许隐式转换为其它不同的底层类型:1.整型操作数不是被扩充为更多位数的相同符号特性的整数;或2.表达式是复杂表达式;或3.表达式不是常数表达式,且是函数的参数;或4.表达式不是常数表达式,且是函数的返回表达式。(MISRAC:2004-Rule10.1)规则10.2(强制)以下情况下,浮点数表达式的值不允许隐式转换为其它不同类型:1.浮点型操作数不是被扩充为更多位数的同符号浮点数;2.表达式是复杂表达式;3.表达式是函数的参数;4.表达式是函数的返回表达式。(MISRAC:2004-Rule10.2),规则10.3(强制)整数类型的复杂表达式的结果只允许转换为(与表达式底层类型相比)更窄的同符号特性的数据类型。(MISRAC:2004-Rule10.3)规则10.4(强制)浮点类型的复杂表达式的结果只允许转换为更窄的浮点类型。(MISRAC:2004-Rule10.4)规则10.5(强制)如果位操作符或移位操作符)作用于底层类型为unsignedchar或者unsignedshort类型的操作数时,中间运算步骤的结果必须立刻显式转换为预期的底层类型。(MISRAC:2004-Rule10.5)/*执行以下程序,result_8的值?*/uint8_tport=0 x5aU;uint8_tresult_8;result_8=(port)4;result_8=(uint8_t)(port)4;result_16=(uint16_t)(uint16_t)port)4;,规则10.6(强制)所有无符号型的常量后必须加“U“。(MISRAC:2004-Rule10.6)规则11.1(强制)禁止函数指针和除整型外的任何数据类型相互转换。(MISRAC:2004-Rule11.1)规则11.2(强制)指向某一类型对象的指针,除整型、其它对象指针以及void指针外,禁止与其余类型相互转换。(MISRAC:2004-Rule11.2)规则11.3(强制)指针转换过程中不允许丢失指针的const,volatile属性。(MISRAC:2004-Rule11.5)规则12.1(强制)表达式的值必须在任何求值顺序下保持一致。(MISRAC:2004-Rule12.2),规则12.2(强制)不允许将sizeof运算符作用于有side-effect的表达式上。(MISRAC:2004-Rule12.3)int32_ti=0;int16_tj=0;j=sizeof(i=1234);规则12.3(强制)逻辑运算(,规则12.4(强制)逻辑运算符(“if(x=y)foo();规则13.2(强制)不允许对浮点数进行相等或者不相等的比较。(MISRAC:2004-Rule13.3),规则13.3(强制)for循环的控制表达式不应包含浮点数类型。(MISRAC:2004-Rule13.4)规则13.4(强制)for语句中的3个表达式只能和循环控制相关。(MISRAC:2004-Rule13.5)规则13.5(强制)for循环中,循环计数变量不允许在循环体中修改。(MISRAC:2004-Rule13.6)flag=1;for(i=0;(i10)if(s8a5)/*不符合规则:恒为TRUE*/,规则14.1(强制)不得遗留“不可到达”的代码。(MISRAC:2004-Rule14.1)switch(event)casee_wakeup:do_something();break;/*绝对跳转*/do_more();/*不符合规则:不能到达的代码*/default:/*/break;如果一个函数没有在任何地方被调用,则整个函数都是“不可到达”的。,规则14.2(强制)所有非空语句必须满足如下任意一条:a)产生至少一个side-effect(side-effect指表达式执行后对程序运行环境造成的影响。赋值语句、自增操作等都是典型的具有side-effect的操作);改变程序控制流。(MISRAC:2004-Rule14.2)x=3;/*不符合规则:x与3比较,然后结果被丢弃了*/规则14.3(强制)一行中如果有空语句,那么该行只能有这条空语句,除注释外不能有别的语句,并且在这条空语句前不能有注释,注释必须在其后,用空白字符隔开。(MISRAC:2004-Rule14.3);/*符合规则*/*不符合规则:注释放在空语句之前*/;/*不符合规则:注释与空语句之间没有空白字符*/规则14.4(强制)不得使用goto语句。(MISRAC:2004-Rule14.4),规则14.5(强制)不得使用continue语句。(MISRAC:2004-Rule14.5)规则14.6(强制)一重循环中最多只能出现一个break语句用于结束循环。(MISRAC:2004-Rule14.6)规则14.7(强制)函数只能有一个出口,这个出口必须在函数末尾。(MISRAC:2004-Rule14.7)规则14.8(强制)switch、while、do.while和for语句的主体必须是复合语句(即用大括号包含),即使该主体只包含一条语句。(MISRAC:2004-Rule14.8)规则14.9(强制)if结构后面必须是一个复合语句(即用大括号包含),else后面必须是一个复合语句(即用大括号包含)或者另一个if语句。(MISRAC:2004-Rule14.9),规则14.10(强制)if.elseif结构必须由一个else子句结束。(MISRAC:2004-Rule14.10)这个原则与规则15.3中,switch语句必须有default分支的原则是一致的。规则15.2(强制)所有非空的switch子句都应该用break语句结束。(MISRAC:2004-Rule15.2)规则15.3(强制)switch的最后一个分支必须是default分支。(MISRAC:2004-Rule15.3)规则15.4(强制)switch表达式的值不能是布尔值。(MISRAC:2004-Rule15.4)例如,以下例子是不符合本规则的:switch(x=0)/*不符合规则:x=0是布尔值表达式*/,规则15.5(强制)每条switch语句必须包含至少一个case分支。(MISRAC:2004-Rule15.5)switch(x)uint8_tvar;/*不符合规则:在第一个case语句之前定义*/case0:a=b;break;/*这里的break是必须的*/case1:/*空的分支中可以不用break*/case2:a=c;if(a=b)case3:/*不符合规则:case3最内的上层复合语句是if的主体*/case4:a=c;/*不符合规则:不为空的分支必须以break结束*/default:/*必须有default语句*/errorflag=1;/*default分支尽量不为空*/break;,规则16.1(强制)不允许定义参数数量不确定的函数。(MISRAC:2004-Rule16.1)规则16.1(强制)不允许定义参数数量不确定的函数。(MISRAC:2004-Rule16.1)规则16.3(强制)在函数的原型声明中应给出所有形参的标识符。(MISRAC:2004-Rule16.3)规则16.4(强制)在函数声明和定义中使用的标识符应当一致。(MISRAC:2004-Rule16.4)规则16.5(强制)无形参的函数应将形参类型声明为void类型。(MISRAC:2004-Rule16.5),规则16.7(强制)非空返回值的函数的所有退出路

温馨提示

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

评论

0/150

提交评论