MISRA C2012学习笔记(9)-Rules 8.14

news2024/11/13 10:13:58

文章目录

    • 8.14控制语句表达式
      • 规则14.1循环计数器本质上不能是浮点型
      • Rule 14.2 for 循环应为良好格式
      • Rule 14.3 控制表达式不得是值不变的
      • Rule 14.4 if 语句和循环语句的控制表达式的基本类型应为布尔型

8.14控制语句表达式

本节中的一些规则使用了术语循环计数器。循环计数器需要定义为满足以下条件的对象、数组元素或结构体或联合的成员:

  1. 它具有标量类型;
  2. 其值在给定循环实例的每次循环中单调变化;
  3. 参与退出循环的判定。

注意:第二个条件意味着循环计数器的值必须在循环的每次迭代中改变,并且对于给定的循环实例,它必须总是在相同的方向上改变。但是,在不同的实例上,它可能在不同的方向上发生变化,例如,有时向后读取数组的元素,有时向前读取它们。

根据这个定义,一个循环不需要只有一个循环计数器:一个循环可以没有循环计数器,也可以有多个循环计数器。有关for循环中循环计数器的更多限制,请参见规则14.2

下面的代码片段展示了循环及其对应的循环计数器的示例。

在这个循环中,i是一个循环计数器,因为它具有标量类型,单调变化(递增),并且涉及循环终止条件。

for ( uint16_t i = 0; a[ i ] < 10; ++i )
{
}

下面的循环没有循环计数器。对象计数具有标量类型且单调变化,但不涉及终止条件。

extern volatile bool_t b;
uint16_t  count = 0;
while ( b )
{
  count = count + 1U;
}

以下代码中,i 和 sum 均为标量且单调变化(分别减小和增大)。但 sum 并不是循环计数器,因为它不参与退出循环的判定。

uint16_t sum = 0;
for ( uint16_t i = 10U; i != 0U; --i )
{
  sum += i;
}

在接下来的循环中,p是一个循环计数器。它不涉及循环控制表达式,但它涉及通过break语句退出循环的决定。

extern volatile bool_t b;
extern char *p;
do
{
  if ( *p == '\0' )
  {
    break;
  }
  ++p;
} while ( b );

下面示例中的循环计数器是p->count。

struct s
{
  uint16_t count;
  uint16_t a[ 10 ];
};
extern struct s *p;
for ( p->count = 0U; p->count < 10U; ++( p->count ) )
{
  p->a[ p->count ] = 0U;
}

规则14.1循环计数器本质上不能是浮点型

等级:必要

分析:不可判定,系统范围

适用:C90,C99

原理:当使用浮点循环计数器时,舍入误差的累积可能导致预期迭代次数与实际迭代次数不匹配。当一个不是浮点基数幂的循环步长舍入到一个可以表示的值时,就会发生这种情况。

即使带有浮点循环计数器的循环在一个实现上表现正确,它也可能在另一个实现上给出不同的迭代次数。(不同编译器设置,浮点数取整方式可能不一样

示例:
在下面的违规示例中,在循环结束时counter的值可能不是1 000

uint32_t counter = 0u;
for ( float32_t f = 0.0f; f < 1.0f; f += 0.001f )
{
  ++counter;
}

下面的合规示例使用整数循环计数器来保证 1000 次循环,并在循环内使用它生成 f。

float32_t f; 
 
for (uint32_t counter = 0u; counter < 1000u; ++counter) 
{ 
f = (float32_t)counter * 0.001f; 
} 

下面的 while 循环违规,因为浮点数 f 被用作循环计数器

float32_t f = 0.0f; 
 
while (f < 1.0f) 
{ 
f += 0.001f; 
} 

下面的 while 循环合规,因为浮点数 f 未被用作循环计数器。

float32_t f; 
uint32_t u32a; 
f = read_float32(); 
do 
{ 
u32a = read_u32(); 
/* f 在循环内未被修改, 所以不作为循环计数器处理 */ 
} while (((float32_t)u32a - f) > 10.0f); 

解读:该规则需要被实施,不过应该一般编程中都不会使用浮点数作为循环的变量

Rule 14.2 for 循环应为良好格式

等级:必要

分析:不可判定,系统范围

适用:C90,C99

展开:for 循环语句包含三个子句,此规则对它们的要求为:第一个子句

不得为空,或

◆ 应为循环计数器分配一个值,或

◆ 应定义并初始化循环计数器(C99)。

第二个子句

◆ 应该是没有持久副作用的表达式,并且

◆ 应使用循环计数器和可选的循环控制标志,并且

◆ 不得使用在 for 循环主体中修改的任何其他对象。

第三个子句

◆ 应该是一个表达式,其唯一的持久副作用是修改循环计数器的值,并且

◆ 不得使用在 for 循环主体中修改的对象。

for循环中只能有一个循环计数器,不能在for循环体中修改。

循环控制标志定义为:在第二个子句使用的基本型为布尔型的对象的单个标识符。

for 循环主体的行为包括了在该主体内调用的所有函数的行为

原理:for 循环语句提供了一种通用循环工具。使用形式受限的循环可使代码更易于查看和分析

例外:三个子句都可以为空,例如 for (;; ),以便允许无限循环。

示例:在下面的 C99 示例中,i 是循环计数器,flag 是循环控制标志。

bool_t flag = false;
for ( int16_t i = 0; ( i < 5 ) && !flag; i++ )
{
  if ( C )
  {
    flag = true;                /* 合规 - 允许提前终止循环                */
  }
  i = i + 3;                    /* 违规 - 循环主体内不允许改变循环计数器   */                     
}

解读:for循环格式必须要遵守,该规则需要被实施

Rule 14.3 控制表达式不得是值不变的

等级:必要

分析:不可判定,系统范围

适用:C90,C99

展开:此规则适用于:

◆ if,while,for,do…while 和 switch 语句的控制表达式;

◆ ?:运算符的第一个操作数。

原理:如果控制表达式的值不变,则意味着可能存在编程错误。因存在不变表达式而无法到达的任何代码都可以由编译器删除。例如,这可能会导致从可执行文件中删除防御性代码。

例外:

  1. 允许使用用于创建无限循环的不变的控制表达式。
  2. 允许 do…while 循环使用值为 0 的布尔型控制表达式。

示例

s8a = ( u16a < 0u ) ? 0 : 1;/* 违规- u16a总是>= 0 */
{ 
} 
if ( u16a <= 0xffffu )
{
                                /* 违规 - always true      */
}
if ( 2 > 3 )
{
                                /* 违规 - always false     */
}
for ( s8a = 0; s8a < 130; ++s8a )
{
                                /* 违规 - always true      */
}
if ( ( s8a < 10 ) && ( s8a > 20 ) )
{
                                /* 违规 - always false     */
}
if ( ( s8a < 10 ) || ( s8a > 5 ) )
{
                                /* 违规 - always true      */
}
while ( s8a > 10 )
{
  if ( s8a > 5 ) 
  {
                                /* 违规 - s8a not volatile */
  }
}
while ( true )
{
  /* 例外1,合规 */
}
do
{
  /* 例外2,合规 */
} while ( 0u == 1u );
const uint8_t numcyl = 4u;
/*
 * 违规 - 条件一直满足
 */
if ( numcyl == 4u )
{
}
const volatile uint8_t numcyl_cal = 4u;
/*
 * 合规- volatile 属性可能导致外部修改其值
 */
if ( numcyl_cal == 4u )
{
}
uint16_t n;     /* 10 <= n <= 100 */
uint16_t sum;
sum = 0;
for ( uint16_t i = ( n - 6u ); i < n; ++i )
{
  sum += i;
}
if ( ( sum % 2u ) == 0u )
{
  /*
   * 违规 - sum是6个连续的非负整数的和, 因此必为奇数, if语句的控制表达式将始终为false  
   */
}

解读:该规则需要被实施,可以检查出异常的控制代码

Rule 14.4 if 语句和循环语句的控制表达式的基本类型应为布尔型

等级:必要

分析:可判定,单一编译单元

适用:C90,C99

展开:for 循环语句的控制表达式是可选的。 此规则不要求表达式存在,但如果存在,则要求表达式的基本类型为布尔型

原理:强类型要求if语句或迭代语句的控制表达式本质上具有布尔类型

示例:

int32_t *p, *q;
while ( p )           /* 违规 - p 为指针 */
{
}
whil e ( q != NULL )   /* 合规 */
{
}
while ( true )        /* 合规 */
{
}
extern bool_t flag;
while ( flag )        /* 合规 */
{
}
int32_t i;
if ( i )              /* 违规                   */
{
}
if ( i != 0 )         /*  合规 */
{
}

解读:该规则需要被实施,但在检查过程中,可能由于bool量无法被正确识别,导致可能会误报出该项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2237800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS教程(三)- CSS 三大特性

1. 层叠性 介绍 多组CSS样式共同作用于一个元素&#xff0c;就会出现 覆盖&#xff08;层叠&#xff09; 另一个冲突的样式。 层叠原则 样式冲突&#xff1a;遵循就近原则&#xff08;哪个样式离结构近&#xff0c;就执行哪个样式&#xff09; 样式不冲突&#xff0c;就不会重…

CyclicBarrier使用详解及遇到的坑

上一篇文章讲的是关于是使用CountDownLatch实现生成年底报告遇到的问题&#xff0c;这个计数器和CyclicBarrier也有类似功能&#xff0c;但是应用场景不同。 一、应用场景 CountDownLatch&#xff1a; 有ABCD四个任务&#xff0c;ABC是并行执行,等ABC三个任务都执行完…

Java-I/O框架14:Properties集合及使用

视频链接&#xff1a;16.32 Properties使用&#xff08;2&#xff09;_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Tz4y1X7H7?spm_id_from333.788.player.switch&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5&p32 1.Properties集合 特性&#xff1a; 存储…

Windows下mysql数据库备份策略

Windows下mysql的增量备份和全量备份&#xff0c;并利用schtasks设置定时任务执行bat脚本。 一、备份要求 序号 备份类型 备份频次 备份时间 1 增量备份 每周一-每周六各一次 18:00:00 2 全量备份 每周日一次 18:00:00 二、备份方法 2.1增量备份 2.1.1准备工作…

架构师备考-概念背诵(软件工程)

软件工程 软件开发生命周期: 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体可分成问题定义、可行性研究、需求分析等。软件开发时期:就是软件的设计与实现,可分成概要设计、详细设计、编码、测试等。软件运行和维护:就是…

【Linux】Linux入门实操——vim、目录结构、远程登录、重启注销

一、Linux 概述 1. 应用领域 服务器领域 linux在服务器领域是最强的&#xff0c;因为它免费、开源、稳定。 嵌入式领域 它的内核最小可以达到几百KB, 可根据需求对软件剪裁&#xff0c;近些年在嵌入式领域得到了很大的应用。 主要应用&#xff1a;机顶盒、数字电视、网络…

【Java项目】基于SpringBoot的【生鲜交易系统】

技术简介&#xff1a; 系统软件架构选择B/S模式、java技术和MySQL数据库等&#xff0c;总体功能模块运用自顶向下的分层思想。 系统简介&#xff1a; 考虑到实际生活中在生鲜交易方面的需要以及对该系统认真的分析,将系统权限按管理员&#xff0c;用户这两类涉及用户划分。 (…

AI Weekly『11月4-10日』: Anthropic发布Claude 3.5 Haiku,腾讯开源混元-Large模型!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

贪心算法day3(最长递增序列问题)

目录 1.最长递增三元子序列 2.最长连续递增序列 1.最长递增三元子序列 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;我们只需要设置两个数进行比较就好。设a为nums[0]&#xff0c;b 为一个无穷大的数&#xff0c;只要有比a小的数字就赋值…

vue实现图片无限滚动播放

本人vue新手菜鸡&#xff0c;文章为自己在项目中遇到问题的记录&#xff0c;如有不足还请大佬指正 文章目录 实现效果代码展示总结 因为刚接触vue&#xff0c;本想着看看能不能用一些element的组件实现图片的轮播效果&#xff0c;尝试使用过element-UI里的走马灯Carouse&#x…

[ 内网渗透实战篇-2 ] 父域子域架构的搭建与安装域环境判断域控定位组策略域森林架构配置信任关系

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Follow软件的使用入门教程

开篇 看到很多兄弟还不知道怎么用这个当下爆火的浏览器&#xff01;在这里简单给需要入门的小伙伴一些建议&#xff1a; 介绍 简单解释一下&#xff0c;RSS 意思是简易信息聚合&#xff0c;用户可以通过 RSS 阅读器或聚合工具自主订阅并浏览各个平台的内容源&#xff0c;不用…

esp32学习:用虫洞ESP32开发板,快速实现无线图传

我们的虫洞ESP32-S3-EYE开发板&#xff0c;能够完美运行esp who AI代码&#xff0c;所以实现无线图传那是非常容易的&#xff0c;我们先看看esp who代码库中examples目录&#xff1a; 里面有比较多的web例程&#xff0c;在这些例程下&#xff0c;稍作修改&#xff0c;就可以快速…

最新三维视觉下的扩散模型综述——Diffusion Models in 3D Vision: A Survey

目录 摘要 一、引言 二、扩散模型简介 A.扩散模型的介绍 B.扩散模型的数学基础 C.扩散模型的变体 D.三维视觉中的生成过程 三、三维视觉基础 A.三维表示 B.三维视觉中的深度学习方法 C.3D视觉中的挑战 四、三维扩散生成任务 A.无条件生成 B.图像到三维 C.文本到…

JavaSE:运算符 (学习笔记)

目录 一&#xff0c;算术运算符 【1】 共同点&#xff1a; 【2】 不同点&#xff1a; 二&#xff0c;关系运算符 三&#xff0c;逻辑运算符 2&#xff0c;&和&&的区别和联系 { |和||的区别和联系 }---两题类似 四&#xff0c;赋值运算符 五&#xff0c;拓展…

strtok函数详解

strtok函数 strtok 函数是一个字符串分割函数&#xff0c;用于将字符串分割成一系列的标记。这个函数通过一组分隔符字符来确定标记的边界&#xff0c;每次调用都会返回字符串中的下一个标记&#xff0c;并且将原始字符串中的分隔符替换为空字符‘\0’&#xff0c;从而实际上是…

题目练习之二叉树那些事儿(续集)

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨个人…

【入门篇】确定字符串是否包含唯一字符——多语言版本

题目跳转&#xff1a;确定字符串是否包含唯一字符 题目解析 这个问题要求我们判断一个字符串中的字符是否唯一&#xff08;忽略字母的大小写&#xff09;&#xff0c;并输出相应的结果。如果字符串中所有的字符都是唯一的&#xff0c;输出 YES&#xff1b;否则&#xff0c;输…

ConcurrentModificationException:检测到并发修改完美解决方法

&#x1f6a6; ConcurrentModificationException&#xff1a;检测到并发修改完美解决方法 &#x1f4a1; &#x1f6a6; ConcurrentModificationException&#xff1a;检测到并发修改完美解决方法 &#x1f4a1;摘要1. 什么是ConcurrentModificationException&#xff1f;&…

并查集 How many tables(hdu 1213) How many answers are wrong(hdu 3038)

目录 前言 并查集 并查集的初始化 并查集的合并 并查集合并的优化&#xff0c;路径压缩 How many tables(hdu 1213) 问题描述 输入 输出 问题分析 代码 带权并查集 How many answers are wrong(hdu 3038) 问题描述 输入 输出 问题分析 代码 前言 感觉并查集总共有两个应…