Situation: You have a nested loop, and you need to break out of it.
Let's take this classic example (classic because it came from Goto Considered Harmful Considered Harmful): Given a 2-dimensional NxN
square integer matrix X
, find the first row with no zeroes.
I'll go through a few ways that different languages would solve this. I suppose I should start with how it could be written, but isn't.
//using "chained breaks"
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if( X[i][j] == 0 ){
//this row isn't non-zero, so go to the next row
break continue;
//break out of the inner loop and continue the outer loop
}
}
//if we get to here, we know this row doesn't have zeroes
return i;
}
return -1; //failure; exact val doesn't matter for this question
C and its mostly-faithful derivatives:
//goto
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if( X[i][j] == 0 ){
//this row isn't non-zero, so go to the next row
goto next; //skip past the return
}
}
//if we get to here, we know this row doesn't have zeroes
return i;
label next;
}
return -1; //failure; exact val doesn't matter for this question
Java:
//labeled loops and labeled break/continue
outer: for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if( X[i][j] == 0 ){
//this row isn't non-zero, so go to the next row
continue outer; //go to the next row
}
}
//if we get to here, we know this row doesn't have zeroes
return i;
}
return -1; //failure; exact val doesn't matter for this question
PHP:
//this PHP may be wrong, it's been a while
for($i=0;$i<$N;$i++){
for($j=0;$j<$N;$j++){
if( $X[$i][$j] == 0 ){
//this row isn't non-zero, so go to the next row
continue 2;
//continue the outer loop
}
}
//if we get to here, we know this row doesn't have zeroes
return $i;
}
return -1; //failure; exact val doesn't matter for this question
Using a flag:
//using a flag
for(int i=0;i<N;i++){
bool foundzero = false;
for(int j=0;j<N;j++){
if( X[i][j] == 0 ){
//this row isn't non-zero, so go to the next row
foundzero = true;
break; //go to the next row
}
}
//if we get to here, we know this row doesn't have zeroes
if(!foundzero)
return i;
}
return -1; //failure; exact val doesn't matter for this question
Exporting the inner loop to a function:
//using a function call
for(int i=0;i<N;i++){
if(haszero(X[i],N))
return i;
}
return -1; //failure; exact val doesn't matter for this question
//and the haszero function
bool haszero(int arr[], int N){
for(int i=0;i<N;i++){
if( arr[i] == 0 ){
return false;
}
}
return true;
}
Now, all of these work, but some with function call overhead (bad if the language wants to allow for deep loops), flags (distasteful or unintuitive for some), goto
(more powerful than you might need),or weird syntax (Java's silliness).
So why don't languages have break break
, break continue
, break break continue
, etc.? (continue break
makes little sense to no sense, as it means to go to the next iteration and then leave it). Are there problems with adding this sort of thing to the language?