【发布时间】:2010-10-26 04:16:25
【问题描述】:
我有两个这样嵌套的 for 循环:
for(...) {
for(...) {
}
}
我知道有一个break 声明。但是我很困惑它是打破两个循环还是仅仅打破它被调用的那个?一旦我发现迭代更多次没有意义,我就需要打破这两个。
【问题讨论】:
标签: c objective-c loops
我有两个这样嵌套的 for 循环:
for(...) {
for(...) {
}
}
我知道有一个break 声明。但是我很困惑它是打破两个循环还是仅仅打破它被调用的那个?一旦我发现迭代更多次没有意义,我就需要打破这两个。
【问题讨论】:
标签: c objective-c loops
只是为了笑,如何将这个真/假检查更改为方法并使用return 语句:
- (bool) checkTrueFalse: parameters{
for ( ...) {
for ( ... ) {
if (...) {
return true;
}
}
}
return false;
}
【讨论】:
和最后一个完全一样,一般是这样的:
for(i=0;i<a;i++){
for(j=0;j<a;j++){
if(Something_goes_wrong){
i=a;
break;
}
}
}
【讨论】:
另一种解决方案是在函数中分解出第二个循环:
int i;
for(i=0; i<10 ; i++){
if !innerLoop(i) {
break;
}
}
bool innerLoop(int i)
int j;
for(j=0;j< 10; j++){
doSomthing(i,j);
if(endcondtion){
return false;
}
}
}
【讨论】:
除了已经提到的标志变量或转到您可以throw Objective-C 异常:
@try {
for() {
for() {
@throw ...
}
}
}
@catch{
...
}
【讨论】:
如果使用 goto 可以简化代码,那就合适了。
for (;;)
{
for (;;)
{
break; /* breaks inner loop */
}
for (;;)
{
goto outer; /* breaks outer loop */
}
}
outer:;
【讨论】:
for (;;) {for (;;) {break; /* breaks inner loop */} for (;;) {goto outer; /* breaks outer loop */}} outer:;
可能最简单的方法是使用“标志”变量
for(i=0; i<10 && (done==false); i++)
for(j=0;j< 10; j++){
..
..
if(...){done=true; break;}
}
【讨论】:
fast-enumeration 循环
break 跳出一个循环,但您可以在外循环中添加一个检查,当内循环中断时。
bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
for ( ... ) {
if (...) {
dobreak = true;
break;
}
}
}
【讨论】:
!dobreak 放错地方了;它应该进入条件(for的第二部分)而不是增量步骤(for的第三部分);我也会使用!dobreak && ..,以便在中断时不需要评估其他条件。我同意 sigjuice:goto 在正确使用时并不邪恶,这是goto 确实 编写更好的代码的情况。
break 替换为continue 语句来解决。不过,这只是更不明显的事情需要担心。
其他人已经提到如何设置标志或使用goto,但我建议重构您的代码,以便将内部循环变成一个单独的方法。然后该方法可以返回一些标志来指示外部循环应该break。如果您适当地命名您的方法,这将更具可读性。
for (int i = 0; i < 10; i++) {
if (timeToStop(i)) break;
}
-(bool) timeToStop: (int) i {
for (int j = 0; j < 10; j++) {
if (somethingBadHappens) return true;
}
return false;
}
伪代码,未经测试,但你明白了。
【讨论】:
break 语句只会让你跳出最里面的循环。如果您不希望在代码、内存和专用状态变量的性能方面增加开销,我建议将代码重构为自己的函数或方法,并使用return 摆脱所有循环:
void do_lots_of_work(void)
{
int i, j;
for(i=0; i<10 ; i++)
{
for(j=0;j< 10; j++)
{
..
..
if(disaster_struck())
return; /* Gets us out of the loops, and the function too. */
}
}
}
【讨论】:
goto 这样的危险旧做法。在任何实际使用中,性能问题也不应该引起注意。
在中断前更改顶部循环的计数器
for(i=0; i<10 ; i++)
for(j=0;j< 10; j++){
..
..
i = 10;
break;
}
【讨论】:
NSUInteger limit = 10; 然后:for(i=0; i<limit; i++) { for(j=0; j<10; j++) { .. .. i = limit; break; } }
break 语句跳出最里面的循环。需要额外的 test 和 break 语句来跳出外循环。
【讨论】:
break 语句只会跳出作用域内的循环,也就是父循环。如果你也想跳出第二个循环,你可以使用两个循环范围内的布尔变量
bool isTerminated = false;
for (...)
{
if (!isTerminated)
{
for(...)
{
...
isTerminated = true;
break;
}
}
else
{
break;
}
}
【讨论】:
如果从一组嵌套循环中执行中断,则仅终止执行中断的最内层循环。 (就像标准 C 一样)
【讨论】: