如何终止嵌套循环

Posted

技术标签:

【中文标题】如何终止嵌套循环【英文标题】:How to terminate the nested loop 【发布时间】:2018-08-11 07:03:34 【问题描述】:

在这里,我想跳出嵌套循环。我正在使用break 语句来做到这一点。代码突破了for 循环,但无法摆脱无限的while 循环。当条件为真时,我想转到另一个名为 resetClock() 的函数。我已经尝试了所有可能的解决方案returngotobreak,但我仍然面临同样的问题。

 #define MUX_PORT  P3
 #define enable_intEA=1;
 #define disable_intEA=0;

 void timer0() interrupt 1 
     TL0 = 0x33;
     TH0 = 0xF5;
     MUX_PORT = 0x00;
     dig1 = dig2 = dig3 = dig4 = 0;
     DATA_PORT = 0x00;
     if (dig_disp > 4)
         dig_disp = 0;
     dig_disp++;

     switch (dig_disp) 
     case 1:
         dig1 = 1;
         MUX_PORT = seg_hex[sec0];
         break;
     case 2:
         dig2 = 1;
         MUX_PORT = seg_hex[sec1];
         break;
     case 3:
         dig3 = 1;
         MUX_PORT = seg_hex[min0];
         break;
     case 4:
         dig4 = 1;
         MUX_PORT = seg_hex[min1];
         break;
     
 

 void msDelay() 
     unsigned int i;
     for (i = 0; i <= 8; i++) 
         TMOD = 0x10;
         TH1 = 0x4B;
         TL1 = 0xFD;
         TR1 = 1;
         while (TF1 == 0);
         TR1 = 0;
         TF1 = 0;
     
 

 void start_Clock() 
     unsigned int loop_break = 0;
     TMOD = 0x01;
     TH0 = 0xF5;
     TL0 = 0x33; //63293
     IE = 0x82;
     TR0 = 1;
     while (SW_SHIFT == 1) 
         for (min1 = 0; min1 < 6; min1++) 
             for (min0 = 0; min0 <= 9; min0++) 
                 for (sec1 = 0; sec1 < 6; sec1++) 
                     for (sec0 = 0; sec0 <= 9; sec0++) 
                         msDelay();
                         if (SW_SHIFT == 0) 
                             loop_break = 1;
                             disable_int;
                             MUX_PORT = 0xFF;
                             dig1 = dig2 = dig3 = dig4 = 0;
                             break;
                         
                         if (min0 == 2 && min1 == 1) 
                             min0 = 1;
                             min1 = 0;
                             sec0 = 0;
                             sec1 = 0;
                             continue;
                         
                     
                     if (loop_break == 1) break;
                 
                 if (loop_break == 1) break;
             
             if (loop_break == 1) break;
         
         if (loop_break == 1) 
             resetClock();
         
     
 

 void main() 
     unsigned int i, j;
     sec0 = sec1 = min0 = min1 = 0;

     SW_SET = 1;
     SW_SHIFT = 1;

     for (i = 0; i <= 250; i++)
         for (j = 0; j <= 1257; j++);

     start_Clock();
 

 void resetClock() 
     unsigned int i, j, k, l;
     i = j = k = l = 0;
     SW_SHIFT = 1;
     SW_SET = 1;

     if (SW_SHIFT == 0) 
         dig_disp++;
         if (dig_disp > 3)
             dig_disp = 0;
     
     switch (dig_disp) 
     case 0:
         while (SW_SET == 0) 
             dig1 = 1;
             i++;
             sec0 = i;
             MUX_PORT = seg_hex[sec0];
             if (i == 9)
                 i = 0;
         
         break;

     case 1:
         while (SW_SET == 0) 
             dig2 = 1;
             j++;
             sec1 = j;
             MUX_PORT = seg_hex[sec1];
             if (j == 5)
                 j = 0;
         
         break;

     case 2:
         while (SW_SET == 0) 
             dig3 = 1;
             k++;
             min0 = k;
             MUX_PORT = seg_hex[min0];
             if (k == 9)
                 k = 0;
         
         break;

     case 3:
         while (SW_SET == 0) 
             dig4 = 1;
             l++;
             min1 = l;
             MUX_PORT = seg_hex[min1];
             if (l == 1)
                 l = 0;
         
         break;
     
 

【问题讨论】:

if(dig_disp&gt;4) 的行为可能与您的预期不同。它只影响后面的第一个语句。 一般来说,您应该尽量避免嵌套超过 3 层。如果是,则需要重新考虑解决问题的方式。 感谢您的回复。问题不在于 dig_disp 它在 if(dig_disp>3) 上也可以正常工作,并且这种情况在中断功能中,我在继续之前禁用了中断。问题出在 while(1) 循环内。 您可能会发布另一个问题,解释此代码需要做什么并要求更简单的解决方案。您似乎将一件简单的事情变得过于复杂,然后就该复杂性引起的问题提出了问题。您没有尝试退出外部 while 循环,为什么会感到惊讶? @Clifford 我已经尝试了所有可能的解决方案。我什至使用 goto break 和 return 来解决这个问题。我的代码中可能有一些拼写错误,但我将 break 语句放在了 while 循环之外。 【参考方案1】:

while 条件中,尝试添加另一个检查,只要您想继续嵌套的for 循环,它就会保持true。每当您设置条件以跳出for 循环时,请确保此检查变为false

while((SW_SHIFT==1) && (cond_to_break_while == false)) 
for1() 
    for2() 
         ....
         forN() 
             cond_to_break_all_the_forloops = true;
             cond_to_break_while = true;
         
         ....
    


【讨论】:

哇 - 如果这是答案,我真的不明白这个问题!该问题并不表明退出while循环的需要与退出for循环的需要无关。【参考方案2】:

goto 的好用法并不多,但打破嵌套循环就是其中之一。

试试这样的:

while (SW_SHIFT == 1) 
    for (min1 = 0; min1 < 6; min1++) 
        for (min0 = 0; min0 <= 9; min0++) 
            for (sec1 = 0; sec1 < 6; sec1++) 
                for (sec0 = 0; sec0 <= 9; sec0++) 
                    msDelay();
                    if (SW_SHIFT == 0) 
                        disable_int;
                        MUX_PORT = 0xFF;
                        dig1 = dig2 = dig3 = dig4 = 0;
                        goto myLabel;
                    
                    if (min0 == 2 && min1 == 1) 
                        min0 = 1;
                        min1 = 0;
                        sec0 = 0;
                        sec1 = 0;
                        continue;
                    
                
            
        
    


myLabel:
    resetClock();

当然,您也可以将该条件添加到 while 条件中,例如:while (SW_SHIFT == 1 &amp;&amp; loop_break == 0),但在我看来,goto 看起来更简洁。

【讨论】:

【参考方案3】:

只需将所有计数器设置为其最终值即可:

while (SW_SHIFT == 1) 
     for (min1 = 0; min1 < 6; min1++) 
         for (min0 = 0; min0 <= 9; min0++) 
             for (sec1 = 0; sec1 < 6; sec1++) 
                 for (sec0 = 0; sec0 <= 9; sec0++) 
                     msDelay();
                     if (SW_SHIFT == 0) 
                         min1 = 6;
                         min0 = 9+1;
                         sec1 = 6;
                         sec0 = 9+1;
                     
                     else if (min0 == 2 && min1 == 1) 
                         min1 = 0;
                         min0 = 1;
                         sec1 = 0;
                         sec0 = 0;
                     
                 
             
         
     
 

如果在内循环的其余部分使用else,则不需要break

根据您的代码,continue 语句是多余的。

同时使用像96 这样的“幻数”被认为是不好的做法。考虑改用consts、enums 或#defines。

【讨论】:

【参考方案4】:

编写代码的正确方法,我认为是最易读的方法,是使用函数和返回:

void start_Clock() 
     unsigned int loop_break = 0;
     TMOD = 0x01;
     TH0 = 0xF5;
     TL0 = 0x33; //63293
     IE = 0x82;
     TR0 = 1;

     delay(); // give this some meaningful function name

     resetClock();
 

void delay (void)

  while (SW_SHIFT == 1) 
    for (min1 = 0; min1 < 6; min1++) 
      for (min0 = 0; min0 <= 9; min0++) 
        for (sec1 = 0; sec1 < 6; sec1++) 
          for (sec0 = 0; sec0 <= 9; sec0++) 
            msDelay();

            if (SW_SHIFT == 0) 
              disable_int; // NOTE: this looks fishy, likely bug
              MUX_PORT = 0xFF;
              dig1 = dig2 = dig3 = dig4 = 0;
              return ;
            

            if (min0 == 2 && min1 == 1) 
              min0 = 1;
              min1 = 0;
              sec0 = 0;
              sec1 = 0;
            

           // for (sec0 = 0; sec0 <= 9; sec0++)
         // for (sec1 = 0; sec1 < 6; sec1++)
       // for (min0 = 0; min0 <= 9; min0++)
     // for (min1 = 0; min1 < 6; min1++) 
   // while (SW_SHIFT == 1)
 

【讨论】:

以上是关于如何终止嵌套循环的主要内容,如果未能解决你的问题,请参考以下文章

嵌套在 async.eachSeries 循环中的 async.series 终止提前发送 POST 响应

关于Qt的事件循环以及QEventLoop的简单使用(QEventLoop::quit()能够终止事件循环,事件循环是可以嵌套的)

在VB中 for 循环嵌套语句的用法语解释(必须清楚!!)

循环嵌套

js中循环嵌套

for 循环与嵌套