如何终止嵌套循环
How to terminate the nested loop
这里我想跳出嵌套循环。我正在使用 break
语句来这样做。代码正在跳出 for
循环,但无法跳出无限 while
循环。当条件为真时,我想转到另一个名为 resetClock()
的函数。我已经尝试了所有可能的解决方案 return
、goto
和 break
,但我仍然面临同样的问题。
#define MUX_PORT P3
#define enable_int{EA=1;}
#define disable_int{EA=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;
}
}
在 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;
}
....
}
}
}
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 && loop_break == 0)
但在我看来,使用 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) {
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
语句是多余的。
同时使用“幻数”,如 9
和 6
被认为是不好的做法。考虑改用 const
s、enum
s 或 #define
s。
编写代码的正确方法,我认为是最易读的方法,是使用函数和 returns:
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)
}
这里我想跳出嵌套循环。我正在使用 break
语句来这样做。代码正在跳出 for
循环,但无法跳出无限 while
循环。当条件为真时,我想转到另一个名为 resetClock()
的函数。我已经尝试了所有可能的解决方案 return
、goto
和 break
,但我仍然面临同样的问题。
#define MUX_PORT P3
#define enable_int{EA=1;}
#define disable_int{EA=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;
}
}
在 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;
}
....
}
}
}
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 && loop_break == 0)
但在我看来,使用 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) {
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
语句是多余的。
同时使用“幻数”,如 9
和 6
被认为是不好的做法。考虑改用 const
s、enum
s 或 #define
s。
编写代码的正确方法,我认为是最易读的方法,是使用函数和 returns:
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)
}