if嵌套相当于条件进行多级逻辑&&运算并且前面条件为真
最近,我在看我同事给我的代码,因为是他自己写的代码,编写规范,易读程度上远不如linux内核源码里面的程序那样容易理解,我分析了主要原因就是里面使用了大量的if-else嵌套,嵌套级数一多脑子就不够用了,因为要时刻记住前面的条件,而且有些变量定义的时候意思比较模糊,因此不容易理解。如下代码timer的中断服务函数所示:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) /**tim6用于电机转动控制,并且使用了普通更新中断 */
{
if(htim->Instance == TIM6)//////////////
{
if(step_num1 == cur_num1) /**设置的步进值等于当前值了,说明条件满足了 */
HAL_TIM_Base_Stop_IT(&htim6); /**停止中断后,就不会再进入 */
else /**条件没满足 */
{
if(HAL_GPIO_ReadPin(DET1_GPIO_Port,DET1_Pin)==GPIO_PIN_RESET) /**0:没检测到光电开关 */
{ /**心得:if的嵌套相当于两个条件&&运算,都满足才运行代码段 */
if(step_dir1 == 1) /**1:离开光电开关,这种情况是允许的,为什么呢?都相当于在中间位置,还希望往回走,或者这么说不允许这种情况,我们希望的是在中间位置,往边上走 */
{
HAL_TIM_Base_Stop_IT(&htim6);
cur_num1 = 0;
step_err1 = 0;
step_dir1 = 0; /**0:好像没有意义,可以理解为其他方向,但是这种情况不存在 */
}
else if(step_dir1 == 2) /**2: 去光电开关方向*/
{
cur_num1++;
step_period1 = SPEED_LOW;
/**重新计数 */
HAL_TIM_Base_Stop_IT(&htim6);
htim6.Init.Period = (uint16_t)step_period1; /**这里使用了强制类型转换 */
HAL_TIM_Base_Init(&htim6);
__HAL_TIM_CLEAR_FLAG(&htim6,TIM_IT_UPDATE);
HAL_TIM_Base_Start_IT(&htim6);
HAL_GPIO_TogglePin(PUL_GPIO_Port,PUL_Pin); /**输出一个方波,定时器6个脉冲引脚搭配,输出方波 */
}
}
else /**到了边界了 */
{
if((step_dir1==1)&&(cur_num1>0)) /**1:离开光电开关方向 */
{
cur_num1--;
if((cur_num1-step_num1>18000)&&(step_period1>SPEED_HIGH))
step_period1 = step_period1 - 0.01;
if((cur_num1-step_num1<18000)&&(step_period1< SPEED_LOW))
step_period1 = step_period1 + 0.01;
}
if(step_dir1==2) /**2:去光电开关方向 */
{
cur_num1++;
if((step_num1-cur_num1>18000)&&(step_period1>SPEED_HIGH))
step_period1 = step_period1 - 0.01;
if((step_num1-cur_num1<18000)&&(step_period1< SPEED_LOW))
step_period1 = step_period1 + 0.01;
}
if(step_err1 == 1)
step_period1 = SPEED_LOW;
/**重新加载计数值 */
HAL_TIM_Base_Stop_IT(&htim6);
htim6.Init.Period = (uint16_t)step_period1;
HAL_TIM_Base_Init(&htim6);
__HAL_TIM_CLEAR_FLAG(&htim6,TIM_IT_UPDATE);
HAL_TIM_Base_Start_IT(&htim6);
HAL_GPIO_TogglePin(PUL_GPIO_Port,PUL_Pin); /**输出方波 */
}
}
}
}
我们不看里面的内容,只看if-else的嵌套级数,前面的主if的嵌套级数为4层,后面主else的嵌套级数为5层,这样写不好,因为级数这么多,有if的条件还比较容易理解,else的条件需要自己在脑子里转换为反逻辑,级数一多,脑子就不够用了。
但是没变法,我最近主要目的是看懂里面的逻辑流程(当满足什么条件的时候需要干什么活),因此我同事写的代码我不会修改,等后面我能力再强一些并且有时间的时候再修改。(根据以前的印象,使用状态机或者内嵌freeRTOS这种实时操作系统是好办法)。
今天主要是讲解这样一个概念,当存在if-else多级嵌套的时候,嵌套的if-else的条件相当于与主if-else的条件做逻辑“&&”的运算,如果更多层的if-else嵌套,相当于逻辑&&的条件累加越来越多,有点向箱现在这个样子:
if(条件1 && 条件2 && ... 条件n),
在当前嵌套if的情况,说明前面的若干个条件1,条件2等等是满足的也就是都为true,当前嵌套if条件满足才进入当前的代码段;否则前面n个条件为真,最后条件如果为false,则进入else的代码段。
值得注意的事,if-else的多级嵌套形成的条件组合呈指数形式递增,有些组合在理论上存在,但是实际没有意义或者根本不可能发生,因此在编写代码过程中往往只关心可能的若干的有限组合的条件。编写对应代码块。
(2)if(条件1)-else if(条件2)
请看以下代码:
void cmd_send(uint8_t* buf_send, uint8_t buf_len) /**将数组buf_send[buf_len]中的数据打包发出去 */
{
if(cmd_rx_flag == 0x01)
CDC_Transmit_FS(buf_send, buf_len); /**使用USB接口将缓存数组中数据发出去 */
else if(cmd_rx_flag == 0x02)
udp_transimit(buf_send, buf_len); /**使用ETH接口将缓存数组中数据发出去 */
cmd_rx_flag = 0; /**消费完了,手动清空标志位 */
}
里面使用了if(条件1)-else if(条件2),这2种条件判断的语句,并且没有else进行结尾,这种情况相当于if条件反逻辑中一种是我们比较关心的,其他的条件不存在,或者我们不关系,这样就不会有else进行结尾了。这种写法编译器也是允许的,只是看起来像是有漏洞没填补,也就是像是else语句忘了写,这种写法不是很规范,因为如果加上else代码段,但是代码段为空的“;”太浪费代码的空白区域了。比较正规的就是else代码段有一个打印信息提示,linux内核中经常看到使用宏定义定义printf()打印内核信息,有时候这个宏值内容为空的。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)