1.前言
今天在写项目的多层循环时,有个需求是需要在满足某个条件的情况下跳出循环,当习惯性的在条件中写入break时,突然反应过来:break关键字,在此处是无法满足多层循环的打断的。然后引发了接下来的思考:break的作用,及多层循环的跳出;
2.执行环境
MCU:stm32f407zgt6
IDE:rt-thread studio 2.2.7
3.break
break关键字是用于立即终止其所在的最内层的循环(如for,while,do-while)或者switch的,当执行break语句后,将会跳出最靠近的一层循环或者switch语句,并执行之后的代码片段;
3.1break在两层嵌套的for循环中的打断
while (1)
{
for( i = 0; i < 3; i++ )
{
for( j = 0; j < 5; j++)
{
rt_kprintf("j[%d] is running\r\n",j);
if( (i==1) && (j==2) )
{
rt_kprintf("break\r\n");
break;
}
}
rt_kprintf("i[%d] is running\r\n",i);
rt_thread_delay(1000);
}
rt_kprintf("for is finish\r\n");
rt_thread_delay(5000);
}
打印结果如下图:
当满足条件(i==1)和(j==2)之后,break将打断该层循环,跳出j循环后,继续执行i循环,并在i循环满足条件下,继续执行j循环;
所以,break打断的,仅是当次循环中,最内层的j循环,而外层的i循环将会在满足条件下继续执行;
4.跳出多层循环
那么,如果在多层循环中,我们该如何去打断循环并跳出循环呢?
4.1使用goto语句
void foo(void)
{
uint8_t i,j;
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
if( (i==1) && (j==2) )
{
goto out_loop;
}
}
}
out_loop:
rt_kprintf("for is finish\r\n");
}
当i与j的值满足条件后,goto将跳转至out_loop标签位置,完成多层循环的打断;
4.2 重构代码
void foo(void)
{
uint8_t i,j;
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
if( (i==1) && (j==2) )
{
return ;
}
}
}
}
我们需要重新将多层循环函数重构包装为一个函数,在满足条件后直接使用return返回;
4.3使用标志位
void foo(void)
{
uint8_t i,j;
uint8_t find_flag = 0;
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
if( (i==1) && (j==2) )
{
find_flag = 1;
break; //跳出内层循环
}
}
/* i循环 */
if( find_flag == 1 )
{
break; //满足条件,跳出外层循环
}
}
}
在j循环中,当条件满足后,置位find_flag并使用break打断内层循环,在外层循环中,根据find_flag的值再将外层循环打断;
4.4手动跳转循环进度,结束循环
void foo(void)
{
uint8_t i,j;
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
if( (i==1) && (j==2) )
{
i = 3; //将i的值调整为3.即最大值,i将不再满足条件,退出循环
break;
}
}
}
}
在循环中,满足打断条件后,手动将i的值调整为最大条件值,然后执行break语句,break将内层中断打断跳出后,继续执行外层循环,此时新一轮的外层循环已不再满足i<3的条件了,i循环也将结束并退出;