Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to exit a for before time in C++, if an ending condition is reached?

I want to know if it is possible to end a for loop in C++ when an ending condition (different from the reacheing right number of iterations) is verified. For instance:

for (int i = 0; i < maxi; ++i)
    for (int j = 0; j < maxj; ++j)
        // But if i == 4 < maxi AND j == 3 < maxj, 
        // then jump out of the two nested loops.

I know that this is possible in Perl with the next LABEL or last LABEL calls and labeled blocks, is it possible to do it in C++ or I should use a while loop?

Thank you.

like image 414
tunnuz Avatar asked Jan 06 '09 13:01

tunnuz


3 Answers

You can use the return keyword: move the nested loop into a subroutine, invoke the subroutine to run the nested loops, and 'return' from the subroutine to exit [all] the loops.

like image 105
ChrisW Avatar answered Nov 13 '22 09:11

ChrisW


Despite the "goto considered harmful" arguments, this seems like the perfect place for goto. That's essentially what you are doing in Perl. Seriously... consider the alternatives:

Extra State Variables


for (int i=0; i<maxi; ++i) {
    bool leaveLoop = false;
    for (int j=0; j<maxj; ++j) {
        if (i == 4 && j == 3) {
            leaveLoop = true;
            break; // leave the inner loop
        }
    }
    if (leaveLoop) {
        break; // leave the outside loop
    }
}

Leave by Exception


try {
    for (int i=0; i<maxi; ++i) {
        for (int j=0; j<maxj; ++j) {
            if (i == 4 && j == 3) {
                throw leave_loop();
            }
        }
    }
} catch (leave_loop const&) {
}

Complex Logic


int j = 0;
for (int i=0; i<maxi && !(i==4 && j==3); ++i) {
    for (j=0; j<maxj && !(i==4 && j==3); ++j) {
        // inner loop
    }
}

goto


for (int i=0; i<maxi; ++i) {
    for (int j=0; j<maxj; ++j) {
        if (i==4 && j==3) {
            goto leave_loop;
        }
    }
}
leave_loop:

Is the last one less clear? I don't believe that it is. Is it any more fragile? IMHO, the others are quite error prone and fragile compared to the goto version. Sorry to be standing on the soapbox here but this is something that has bothered me for a while ;)

The only thing that you have to be congnizent of is that goto and exceptions are pretty similar. They both open up the opportunity for leaking resources and what not so treat them with care.

like image 47
D.Shawley Avatar answered Nov 13 '22 07:11

D.Shawley


Let me say this as emphatically (but politely ;-) as I can: The for construct in c-like language is not about counting.

The test expression which determines whether to continue can be anything which is relevant to the purpose of the loop; the update expression doesn't have to be "add one to a counter".

for (int i = 0, j = 0; i < maxi && j < maxj && i != 4 && j != 3;) {
    if (j < maxj) {
        ++j;
    } else {
        j = 0;
        ++i;
    }
}

would be one (fairly arbitrary) way to rewrite.

The point is that if establishing some condition is the point of an interation, it's usually possible to write a loop (using either while or for) in a way that states the continue/terminate condition more explicitly.

(If you could post a description of what's actually happening, it would likely to write something that doesn't look as arbitrary as the above.)

like image 13
joel.neely Avatar answered Nov 13 '22 07:11

joel.neely