收藏 分销(赏)

C语言编程规范.ppt

上传人:胜**** 文档编号:733719 上传时间:2024-02-27 格式:PPT 页数:40 大小:367.50KB
下载 相关 举报
C语言编程规范.ppt_第1页
第1页 / 共40页
C语言编程规范.ppt_第2页
第2页 / 共40页
C语言编程规范.ppt_第3页
第3页 / 共40页
C语言编程规范.ppt_第4页
第4页 / 共40页
C语言编程规范.ppt_第5页
第5页 / 共40页
点击查看更多>>
资源描述

1、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颗太阳风观察卫星到预定轨道,但因软件引发的问题导致火箭在发射3

2、9秒后偏轨,从而激活了火箭的自我摧毁装置。阿丽亚娜5型火箭和其他卫星在瞬间灰飞烟灭。(见图3)后来查明的事故原因是:代码重用。阿5型的发射系统代码直接重用了阿4型的相应代码,而阿4型的飞行条件和阿5型的飞行条件截然不同。此次事故损失3.7亿美元 软件缺陷的代价极其昂贵。2002年,美国国家标准与技术研究所的一项研究表明,软件缺陷给美国每年造成的损失高达595亿美元。想想全球这个数额会是多大。编码规范的意义编码规范的意义:C语言在铁路行业的应用,安全可靠性非常重要,所以遵守一定的编程规范的显得尤为重要,公司的C语言编码规范(安全系统)是基于2004年的Guidelines For The Use

3、 Of The C Language in Critical Systems而编写。l1、养成良好的编码习惯,摒弃那些可能存在风险的编程行为。编写出安全健壮的代码,进而保证我们产品的可靠性、稳定性、安全性;l2、增加软件的可读性,便于日后维护;l3、遵循良好的共通的编码规范,也是项目开发中相互协作开发的技术基础。规则规则2.2(强制)源代码只能采用(强制)源代码只能采用/*/风格的注释。风格的注释。(MISRA C:2004-Rule 2.2)规则规则2.3(强制)字符序列(强制)字符序列/*不能在注释中使用。不能在注释中使用。(MISRA C:2004-Rule 2.3)任何在注释中出现的“

4、/*“字符序列都是违背本规则的。#include c_standards.h*禁止使用嵌套的注释。*/void static_function(void)*这样的字符序列不符合规则 *规则规则5.1(强制)(强制)内内部部或外部的标识符的识别都不能依或外部的标识符的识别都不能依赖于赖于 31 个字符之后的差异个字符之后的差异。(MISRA C:2004-Rule 5.1)便于编译器识别,代码清晰易读,并保证可移植性。便于编译器识别,代码清晰易读,并保证可移植性。规则规则5.2(强制)内部标识符不能使用和外部标识符相(强制)内部标识符不能使用和外部标识符相同的名字,导致在内部范围内隐藏外部标识符

5、。同的名字,导致在内部范围内隐藏外部标识符。(MISRA C:2004-Rule 5.2)示例:int16_t i;void f(void)int16_t i;/*这是一个不同的内部变量*/i=3;/*代码不易理解,不知道这个 i 指那个变量*/国军标与本规则对应的准则:过程名禁止被重用;禁止参数与全局变量同名。如下例:#include“c_standards.h”void foo(uint32_t P_1)uint32_t x=P_l;void static_function(void)uint32_t foo=1u;/*过程名静止被重用。*/#include c_standardsh/*-

6、Global Declarations*uint32_t dwTmp=0;void static p(uint32_t dwTmp)/*禁止参数与全局变量同名。*/*/规则规则6.1(强制)(强制)普通普通 char 类型只能用来存储字符值。类型只能用来存储字符值。(MISRA C:2004-Rule 6.1)规则规则6.2(强制)(强制)signed 和和 unsigned char 只能作为数只能作为数据值存储和使用。据值存储和使用。(MISRA C:2004-Rule 6.2)有三种方式声明 char 类型:signed char;unsigned char 和 char 类型。前两种只

7、能用于数值型数据,后一种用于字符数据。char 类型是否具有符号特性与具体的编译器有关。对于声明为 char 类型的变量,只有三种操作符可以使用,即:=,=,!=。规则规则6.3(强制)(强制)位域只能被定义为位域只能被定义为 unsigned int 或或者者 signed int 类型。类型。(MISRA C:2004-Rule 6.4)本规则与编译器的以下不确定行为有关:未定义的行为:位域中的元素使用 signed int/unsigned int 以外的类型定义。用 int 定义位域中的元素时,可能被处理为 signed int 或者 unsigned int,取决于具体的编译器。规则

8、规则6.4(强制)(强制)signed int 类型的位域元素的长度至少类型的位域元素的长度至少为为 2 bit。(MISRA C:2004-Rule 6.5)1 bit 的 signed int 类型是没有意义的。struct bs signed int a:1;/*只有一位没有意义,没有符号位*/signed int b:2;/*符合规则*/signed int c:3;/*符合规则*/bit,*pbit;规则规则7.1(强制)(强制)禁止使用八进制数及八进制转义序列。禁止使用八进制数及八进制转义序列。(MISRA C:2004-Rule 7.1)规则规则8.1(强制)(强制)函数都应该有

9、原型声明,且对函数函数都应该有原型声明,且对函数定义和调用可见。定义和调用可见。(MISRA C:2004-Rule 8.1)要求程序使用原型声明,是利用编译器检查函数调用时数据类型的一致性。如果调用函数时,没有进行原型声明,则编译器不会检查出函数形参与实参的个数、类型等的不一致。函数接口问题已经被证明是一些重大软件问题的原因,因此本条规则尤为重要。对外部函数来说,我们建议采用如下方法,在头文件中声明函数(亦即给出其原型),并在所有需要该函数原型的代码文件中包含这个头文件(见规则 8.8)。为具有内部链接的函数给出其原型也是良好的编程实践。规则规则8.2(强制)(强制)无论对一个对象和函数声明

10、或定义无论对一个对象和函数声明或定义时,它的类型都应该显式声明。时,它的类型都应该显式声明。(MISRA C:2004-Rule 8.2)示例:extern x;/*错误,没有类型说明*/extern int16_t x;/*正确*/const y;/*错误,没有类型说明*/const in16_t y;/*正确*/static foo(void);/*错误,没有类型说明*/static int16_t foo(void);/*正确*/规则规则8.3(强制)(强制)每个函数声明中的参数类型及返回每个函数声明中的参数类型及返回值应与函数定义一致。值应与函数定义一致。(MISRA C:2004-R

11、ule 8.3)函数声明中的参数类型及返回值应与函数定义中的一致,包括 typedef 名称、限定词都需一致,而不仅仅是基本类型一致。#include c_standards.h FLOAT_32 static_function(UINT_32,UINT_16);SlNT_32 static_function(UINT_32 p_l,UINT_16 p_2)/*定义的函数返回值与声明中不一致*/SINT_32 result=0;/*return result:规则规则8.5(强制)(强制)头文件中不要定义对象或者函数。头文件中不要定义对象或者函数。(MISRA C:2004-Rule 8.5)

12、如果该头文件被多个文件包含,会产生重复定义错误。当源文件包含某一头文件时,预处理器会将头文件的内容在包含指令处展开。显然,在头文件中函数的定义会在其他源文件中一模一样的出现,导致函数被重复定义。解决这一问题的关键是明确一个概念:所有可执行的代码或者对象和函数的定义都应在.C 的源文件中,头文件中只能存在其声明。具体的做法是:为全局变量的声明增加 extern 修饰符,并在相应的.C 源文件中定义对象或函数。/*在 Globle.h 中*/extern uint32_t GCounter;/*在 GlobleVariables.C 中*/uint32_t GCounter;规则规则8.7(强制)

13、(强制)对象如果只被单个函数访问,应定对象如果只被单个函数访问,应定义在块作用域。义在块作用域。(MISRA C:2004-Rule 8.7)对象的作用域应尽可能限制在单个函数内,只有在对象需要内部或外部链接属性时才可在文件域声明,此时应遵守规则 8.10 的约束,即在文件域声明的对象应尽可能具有内部链接属性。如非必要,好的做法是尽量避免全局变量。选择是在最外一层的块域还是在最内一层的块域声明对象,很大程度上是编码风格的问题。规则规则8.8(强制)(强制)一个外部变量或者函数只能在文件一个外部变量或者函数只能在文件中被声明一次。中被声明一次。(MISRA C:2004-Rule 8.8)一般来

14、讲,对于外部变量和函数的声明都放在一个头文件中,任何定义或引用这些外部对象的源文件需包含这个头文件。示例:/*在 FeatureX.h 中*/extern int16_t a;/*在 FeatureX.c 中*/int16_t a=0;规则规则8.10(强制)(强制)所有在文件域中声明的对象或函数所有在文件域中声明的对象或函数应具有内部链接属性(除非必须在别的文件中使用这应具有内部链接属性(除非必须在别的文件中使用这个对象或函数)。个对象或函数)。(MISRA C:2004-Rule 8.10)如果变量仅在本文件的函数中使用,则应使其具有内部链接属性,即对变量的声明使用 static 关键字。

15、同理,如果一个函数仅在本文件的其它函数中调用,也使用static 关键字。使用 static 声明是为了确保该标识符仅对本文件可见,因而避免相同的标识符在其它文件或库文件中出现而引起的混淆。规则规则8.12(强制)(强制)如果一个数组具有外部链接属性,如果一个数组具有外部链接属性,那么它的大小需显式说明,或者通过初始化隐式定义。那么它的大小需显式说明,或者通过初始化隐式定义。(MISRA C:2004-Rule 8.12)示例:extern int array2 /*可以通过编译,但不满足本规则*/extern int array310/*满足规则*/int array110;/*满足规则*/

16、int array2=1,2,3;/*满足规则*/规则规则9.1(强制)(强制)所有自动对象变量在使用之前都所有自动对象变量在使用之前都应该赋值。应该赋值。(MISRA C:2004-Rule 9.1)本规则与编译器的以下不确定行为有关:未定义的行为:一个存储属性为 auto 的对象在初始化之前的值。本条款的目的是确保所有的变量在引用之前已经被写入了确定的值。但本规则不要求必须在定义的时候初始化。根据 ISO 标准,如果没有显式的初始化,具有静态存储属性的变量默认会自动初始化为 0。但实际上许多嵌入式编译环境并没有执行这个操作。静态存储指一种存储属性,使用 static 关键字声明、或具有外部

17、链接属性的变量具有静态存储属性。具有 auto 存储属性的变量通常不会自动初始化。void static_function(void)int t,k;t=k+1;/*k 在定义前被使用*/规则规则9.3(强制)(强制)枚举列表中,枚举列表中,“=“只能用于第一个只能用于第一个成员初始化(除非所有的成员都已初始化)。成员初始化(除非所有的成员都已初始化)。(MISRA C:2004-Rule 9.3)如果一个枚举列表没有显式的初始化,C 语言会从 0 开始递增为每个元素自动赋值。如果只为第一个元素显式的赋值,则后续元素从第一个元素的值开始,自动依次递增。使用这种方法初始化枚举列表是本规则允许的,

18、但需要确认后续的值不会超过 int 表示的范围。对所有元素显式的初始化也是本规则允许的,但不允许自动赋值和人工赋值混和。同时,程序员应确认所有的值都在规定范围内。示例:enum color red=3,blue,green,yellow=5;/*不符合本规则*/enum color red=3,blue=4,green=5,yellow=5;/*符合本规则*/规则规则10.1(强制)(强制)以下情况下,整型表达式的值不允许隐以下情况下,整型表达式的值不允许隐式转换为其它不同的底层类型式转换为其它不同的底层类型:1.整型操作数不是被扩充为更多位数的相同符号特性的整型操作数不是被扩充为更多位数的相

19、同符号特性的整数;或整数;或 2.表达式是复杂表达式;或表达式是复杂表达式;或 3.表达式不是常数表达式,且是函数的参数;或表达式不是常数表达式,且是函数的参数;或 4.表达式不是常数表达式,且是函数的返回表达式。表达式不是常数表达式,且是函数的返回表达式。(MISRA C:2004-Rule 10.1)规则规则10.2(强制)(强制)以下情况下,浮点数表达式的值不允许以下情况下,浮点数表达式的值不允许隐式转换为其它不同类型隐式转换为其它不同类型:1.浮点型操作数不是被扩充为更多位数的同符号浮点数;浮点型操作数不是被扩充为更多位数的同符号浮点数;2.表达式是复杂表达式;表达式是复杂表达式;3.

20、表达式是函数的参数;表达式是函数的参数;4.表达式是函数的返回表达式。表达式是函数的返回表达式。(MISRA C:2004-Rule 10.2)规则规则10.3(强制)(强制)整数类型的复杂表达式的结果只允整数类型的复杂表达式的结果只允许转换为(与表达式底层类型相比)更窄的同符号特许转换为(与表达式底层类型相比)更窄的同符号特性的数据类型。性的数据类型。(MISRA C:2004-Rule 10.3)规则规则10.4(强制)(强制)浮点类型的复杂表达式的结果只允浮点类型的复杂表达式的结果只允许转换为更窄的浮点类型。许转换为更窄的浮点类型。(MISRA C:2004-Rule 10.4)规则规则

21、10.5(强制)(强制)如果位操作符如果位操作符或移位操作符或移位操作符)作用于底层类型为作用于底层类型为unsigned char 或者或者 unsigned short 类型的操作数时,中间运算步骤的结果必须立类型的操作数时,中间运算步骤的结果必须立刻显式转换为预期的底层类型。刻显式转换为预期的底层类型。(MISRA C:2004-Rule 10.5)/*执行以下程序,result_8 的值?*/uint8_t port=0 x5aU;uint8_t result_8;result_8=(port)4;result_8=(uint8_t)(port)4;result_16=(uint16_

22、t)(uint16_t)port)4;规则规则10.6(强制)(强制)所有无符号型的常量后必须加所有无符号型的常量后必须加“U“。(MISRA C:2004-Rule 10.6)规则规则11.1(强制)(强制)禁止函数指针和除整型外的任何数禁止函数指针和除整型外的任何数据类型相互转换。据类型相互转换。(MISRA C:2004-Rule 11.1)规则规则11.2(强制)指向某一类型对象的指针,除整型、(强制)指向某一类型对象的指针,除整型、其它对象指针以及其它对象指针以及 void 指针外,禁止与其余类型相互指针外,禁止与其余类型相互转换。转换。(MISRA C:2004-Rule 11.2

23、)规则规则11.3(强制强制)指针转换过程中不允许丢失指针的指针转换过程中不允许丢失指针的 const,volatile 属性。属性。(MISRA C:2004-Rule 11.5)规则规则12.1(强制)表达式的值必须在任何求值顺序下(强制)表达式的值必须在任何求值顺序下保持一致。保持一致。(MISRA C:2004-Rule 12.2)规则规则12.2(强制)不允许将(强制)不允许将 sizeof 运算符作用于有运算符作用于有 side-effect 的表达式上。的表达式上。(MISRA C:2004-Rule 12.3)int32_t i=0;int16_t j =0;j=sizeof(

24、i=1234);规则规则12.3(强制)(强制)逻辑运算逻辑运算(&和和|)的右操作数的右操作数不允许为具有不允许为具有 side-effect 的表达式。的表达式。(MISRA C:2004-Rule 12.4)if(istrue|do_something_with_side_effect s()do_something;规则规则12.4(强制)逻辑运算符(强制)逻辑运算符(“&”或或“|”)的操作的操作数必须是一个基本表达式。数必须是一个基本表达式。(MISRA C:2004-Rule 12.5)这里基本表达式包括标识符、常量和括号括起来的表达式。规则规则12.5(强制)(强制)不允许对底

25、层类型为有符号的类型不允许对底层类型为有符号的类型进行位操作。进行位操作。(MISRA C:2004-Rule 12.7)规则规则12.6(强制)(强制)移位操作的右操作数只能在移位操作的右操作数只能在 0 和操和操作数的位数减作数的位数减 1 之间。之间。(MISRA C:2004-Rule 12.8)规则规则12.7(强制)(强制)不允许对底层类型为无符号的表达不允许对底层类型为无符号的表达式进行一元负(式进行一元负(“-”)运算符。)运算符。(MISRA C:2004-Rule 12.9)规则规则12.8(强制)(强制)不允许使用逗号表达式。不允许使用逗号表达式。(MISRA C:200

26、4-Rule 12.10)规则规则12.9(强制)(强制)不得以位的形式操作或表示浮点不得以位的形式操作或表示浮点型数值。型数值。(MISRA C:2004-Rule 12.12)规则规则13.1(强制)(强制)赋值表达式不能用在需要布尔值赋值表达式不能用在需要布尔值的地方。的地方。(MISRA C:2004-Rule 13.1)uint8_t x,y;if(x=y)foo();规则规则13.2(强制)(强制)不允许对浮点数进行相等或者不不允许对浮点数进行相等或者不相等的比较。相等的比较。(MISRA C:2004-Rule 13.3)规则规则13.3(强制)(强制)for 循环的控制表达式不

27、应包含浮循环的控制表达式不应包含浮点数类型。点数类型。(MISRA C:2004-Rule 13.4)规则规则13.4(强制)(强制)for 语句中的语句中的 3 个表达式只能和循个表达式只能和循环控制相关。环控制相关。(MISRA C:2004-Rule 13.5)规则规则13.5(强制)(强制)for 循环中,循环计数变量不允许循环中,循环计数变量不允许在循环体中修改。在循环体中修改。(MISRA C:2004-Rule 13.6)flag=1;for(i=0;(i5)&(flag=1);i+)/*/flag=0;/*符合规则*/i=i+3;/*不符合规则*/规则规则13.6(强制)(强制

28、)禁止使用结果为常量的布尔表达式。禁止使用结果为常量的布尔表达式。(MISRA C:2004-Rule 13.7)如果使用一个布尔表达式,但这个表达式的结果可以证明总为“真”或总为“假”,这种情况很大可能是代码错误。if(u16a 0)/*不符合规则:恒为 FALSE*/if(u16a=0 xffff)/*不符合规则:恒为 TRUE*/if(s8a 20)/*不符合规则:恒为 FALSE*/if(s8a 10)if(s8a 5)/*不符合规则:恒为 TRUE*/规则规则14.1(强制)(强制)不得遗留不得遗留“不可到达不可到达”的代码。的代码。(MISRA C:2004-Rule 14.1)s

29、witch(event)case e_wakeup:do_something();break;/*绝对跳转*/do_more();/*不符合规则:不能到达的代码*/default:/*/break;如果一个函数没有在任何地方被调用,则整个函数都是“不可到达”的。规则规则14.2(强制)所有非空语句必须满足如下任意(强制)所有非空语句必须满足如下任意一条一条:a)产生至少一个产生至少一个 side-effect(side-effect 指表达式执指表达式执行后对程序运行环境造成的影响。赋值语句、自增行后对程序运行环境造成的影响。赋值语句、自增操作等都是典型的具有操作等都是典型的具有side-ef

30、fect 的操作的操作);b)改变改变程序控制流。程序控制流。(MISRA C:2004-Rule 14.2)x =3;/*不符合规则:x 与 3 比较,然后结果被丢弃了*/规则规则14.3(强制)(强制)一行中如果有空语句,那么该行一行中如果有空语句,那么该行只能有这条空语句,除注释外不能有别的语句,并只能有这条空语句,除注释外不能有别的语句,并且在这条空语句前不能有注释,注释必须在其后,且在这条空语句前不能有注释,注释必须在其后,用空白字符隔开。用空白字符隔开。(MISRA C:2004-Rule 14.3);/*符合规则*/*不符合规则:注释放在空语句之前*/;/*不符合规则:注释与空语

31、句之间没有空白字符*/规则规则14.4(强制)(强制)不得使用不得使用 goto 语句。语句。(MISRA C:2004-Rule 14.4)规则规则14.5(强制)(强制)不得使用不得使用 continue 语句。语句。(MISRA C:2004-Rule 14.5)规则规则14.6(强制)(强制)一重循环中最多只能出现一个一重循环中最多只能出现一个 break 语句用于结束循环。语句用于结束循环。(MISRA C:2004-Rule 14.6)规则规则14.7(强制)(强制)函数只能有一个出口,这个出函数只能有一个出口,这个出口必须在函数末尾。口必须在函数末尾。(MISRA C:2004-

32、Rule 14.7)规则规则14.8(强制)(强制)switch、while、do.while 和和 for 语句的主体必须是复合语句语句的主体必须是复合语句(即用大括号包含即用大括号包含),即使该主体只包含一条语句。,即使该主体只包含一条语句。(MISRA C:2004-Rule 14.8)规则规则14.9(强制)(强制)if 结构后面必须是一个复合语结构后面必须是一个复合语句句(即用大括号包含即用大括号包含),else 后面必须是一个复合后面必须是一个复合语句语句(即用大括号包含即用大括号包含)或者另一个或者另一个 if 语句。语句。(MISRA C:2004-Rule 14.9)规则规则

33、14.10(强制)(强制)if.else if 结构必须由一个结构必须由一个 else 子句结束。子句结束。(MISRA C:2004-Rule 14.10)这个原则与规则 15.3中,switch 语句必须有 default 分支的原则是一致的。规则规则15.2(强制)所有非空的(强制)所有非空的 switch 子句都应该用子句都应该用 break 语句结束。语句结束。(MISRA C:2004-Rule 15.2)规则规则15.3(强制)(强制)switch 的最后一个分支必须是的最后一个分支必须是 default 分支。分支。(MISRA C:2004-Rule 15.3)规则规则15.

34、4(强制)(强制)switch 表达式的值不能是布尔值。表达式的值不能是布尔值。(MISRA C:2004-Rule 15.4)例如,以下例子是不符合本规则的:switch(x=0)/*不符合规则:x=0 是布尔值表达式*/规则规则15.5(强制)(强制)每条每条 switch 语句必须包含至少一个语句必须包含至少一个 case 分支。分支。(MISRA C:2004-Rule 15.5)switch(x)uint8_t var;/*不符合规则:在第一个 case 语句之前定义*/case 0:a=b;break;/*这里的 break 是必须的*/case 1:/*空的分支中可以不用 bre

35、ak*/case 2:a=c;if(a=b)case 3:/*不符合规则:case 3 最内的上层复合语句是 if 的主体*/case 4:a=c;/*不符合规则:不为空的分支必须以 break 结束*/default:/*必须有 default 语句*/errorflag=1;/*default 分支尽量不为空*/break;规则规则16.1(强制)(强制)不允许定义参数数量不确定的函数。不允许定义参数数量不确定的函数。(MISRA C:2004-Rule 16.1)规则规则16.1(强制)(强制)不允许定义参数数量不确定的函数。不允许定义参数数量不确定的函数。(MISRA C:2004-R

36、ule 16.1)规则规则16.3(强制)(强制)在函数的原型声明中应给出所有形在函数的原型声明中应给出所有形参的标识符。参的标识符。(MISRA C:2004-Rule 16.3)规则规则16.4(强制)(强制)在函数声明和定义中使用的标识符在函数声明和定义中使用的标识符应当一致。应当一致。(MISRA C:2004-Rule 16.4)规则规则16.5(强制)(强制)无形参的函数应将形参类型声明为无形参的函数应将形参类型声明为 void 类型。类型。(MISRA C:2004-Rule 16.5)规则规则16.7(强制)(强制)非空返回值的函数的所有退出路径非空返回值的函数的所有退出路径必

37、须有一显式的带表达式的必须有一显式的带表达式的return 语句。语句。(MISRA C:2004-Rule 16.8)规则规则16.8(强制)(强制)函数标识符只允许以下两种用法:函数标识符只允许以下两种用法:使用一个使用一个&前缀前缀+函数标识符,或者函数标识符函数标识符,或者函数标识符+(参参数列表数列表)。参数列表可以为空。参数列表可以为空。(MISRA C:2004-Rule 16.9)if(fun)/*不符合规则*/*.*/规则规则17.1(强制)(强制)只有指向数组的指针才允许进行指只有指向数组的指针才允许进行指针算术运算。针算术运算。(MISRA C:2004-Rule 17.

38、1)此处的指针算术运算只仅仅限定于指针加减某个整数,比如 ppoint=ppoint-5,ppoint+等。对于不是指向类似 array 对象的元素的指针,执行加或减的操作是没有定义的。即使是指向 array 对象元素的指针,由于不能保证运算后得到的是有效的地址(比如超过数组长度),所以对指针进行代数运算是不安全的,应谨慎对指针进行代数运算。规则规则17.2(强制)(强制)只有指向同一个数组的两个指针才只有指向同一个数组的两个指针才允许相减。允许相减。(MISRA C:2004-Rule 17.2)指针的相减操作只有在它们指向同一个 array 对象时,结果才是充分定义的,例如,UINT_16

39、*q=p+i,那么可以通过 q-p 得到 i 的值。两个指针可指向同一数组的不同成员。规则规则17.3(强制)(强制)只有指向同一个数组的两个指针只有指向同一个数组的两个指针才允许用才允许用、=、=等关系运算符进行比较。等关系运算符进行比较。(MISRA C:2004-Rule 17.3)规则规则17.4(强制)(强制)只允许用数组索引只允许用数组索引(下标)(下标)做指做指针运算。针运算。(MISRA C:2004-Rule 17.4)uint8_t a10;unit8_t*p;p=a;*(p+5)=0 /*不符合规则:指针显式运算*/p5=0 /*符合规则*/void my_fun(uin

40、t8_t*p1,uint8_t p2)uint8_t index=0;uint8_t*p3;uint8_t*p4;*p1=0;p1+;/*不允许,p1 不是指向数组的指针*/p1=p1+5;/*不允许,p1 不是指向数组的指针*/p15=0;/*不允许,p1 不是指向数组的指针*/p3=&p15;/*不允许:p1 不是指向数组的指针*/p20=0;index+;index=index+5;p2index=0;/*允许*/*(p2+index)=0;/*不允许*/p4=&p25;/*允许*/规则规则17.6(强制)(强制)设对象设对象 A 的存储特性为的存储特性为 auto,如,如果可能发生果可

41、能发生 A 已经不存在,而另一对象已经不存在,而另一对象 B 仍然存在的仍然存在的情况,那么不允许将情况,那么不允许将 A 的地址赋给对象的地址赋给对象 B。(MISRA C:2004-Rule 17.6)int8_t*foobar(void)int8_t local_auto;return(&local_auto);/*不符合规则*/规则规则18.2(强制强制)不能将对象赋值给与之内存区域重叠不能将对象赋值给与之内存区域重叠的另一个对象。的另一个对象。(MISRA C:2004-Rule 18.2)规则规则18.4(强制强制)不允许使用联合体。不允许使用联合体。(MISRA C:2004-R

42、ule 18.4)规则规则20.3(强制强制)传给标准库函数的值的有效性需要检传给标准库函数的值的有效性需要检查。查。(MISRA C:2004-Rule 20.3)规则规则20.4(强制强制)动态内存分配不能使用。动态内存分配不能使用。(MISRA C:2004-Rule 20.4)规则规则19.1(强制强制)#include 预处理指令只能跟预处理指令只能跟或或”filename”。(MISRA C:2004-Rule 19.3)规则规则20.7(强制强制)setjmp 宏及宏及 longjmp 函数不能使用。函数不能使用。(MISRA C:2004-Rule 20.7)规则规则20.9(强制强制)产品代码中禁止使用输入产品代码中禁止使用输入/输出库函输出库函数数。(MISRA C:2004-Rule 20.9)规则规则20.10(强制强制)stdlib.h 中的库函数中的库函数 atof,atoi 及及 atol 不能使用。不能使用。(MISRA C:2004-Rule 20.10)谢谢大家!

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 品牌综合 > 行业标准/行业规范

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服