I have 3 nested loops in which the code doesn't in anyway modify the counters, I need the value of the topmost-level loop counter to use later in the code. It looks like this
int i;
for( i = 0; !found && i <f_i.size();i++){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
}
//Stuff that uses i
The condition is fulfilled after 2 iteration of the innermost loop, so i has the value 0 at that point.
Using GDB I saw that the value of i jumps to 1 after the condition is checked in the topmost loop, which gives me a wrong later in my program, or worse an out of bounds access.
Thanks in advance
This is how for loops work. The increment is done before the condition is checked.
The proper way (easier to read, easier to maintain) to do what you want is to add a variable, outside the loop.
int index;
And set it when you find the element:
found = ...
if (found) index = i;
The variable i is incremented due to the third expression of the for loop
int i;
for( i = 0; !found && i <f_i.size();i++){
^^^^
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
}
To avoid this you can write for example
int i;
for( i = 0; !found && i <f_i.size();){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
i += !found;
}
Or instead of the expression statement
i += !found;
you can use the if statement like
if ( !found ) ++i;
Also the code will look more readable if the variable i will be initialized before the loops for example like
int i = 0;
while ( !found && i < f_i.size() ){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
i += !found;
}
As others have said (or, at least, implied): once the (outermost) for loop is entered†, the variable, i, will be incremented at the end of that loop, before the condition is tested, to see if another loop should be run ...
... that is, unless you 'jump out' of the loop using a break statement!
So, the following, slightly modified, code will not increment i (at all) if found becomes true during the first iteration of the outermost loop:
int i;
for (i = 0; !found && i < f_i.size(); i++) {
for (unsigned int j = 0; !found && j < f_g.size(); j++) {
for (unsigned int k = 0; !found && k < f_g.size(); k++) {
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
// If "found" becomes true, exit the loop immediately, AVOIDING THE INCREMENT:
if (found) break;
}
So, while the other answers are very good, and the code solutions they offer are perfectly valid, the proposal here is a far more 'minimal' adjustment to your code. I hope it helps.
Note: You could, of course, add similar break statements to the inner loops; however, as your j and k variables are declared locally to those loops, it would appear that undesired increments to their values is not relevant. Furthermore, break cannot be used to jump out of multiple, nested loops.
† Also, be aware that if the found variable is true before the outermost for loop is encountered, that loop will not be executed (obviously) and, thus, the i variable will not be incremented in that case.
I've been studying this tetris tutorial and I've come across the function that deletes lines and brings the row/s down one level. I'm kind of understanding what is going on with these functions, but some parts are confusing me. I'll try and explain it best I can, but here is the link to the lesson if you need it: http://javilop.com/gamedev/tetris-tutorial-in-c-platform-independent-focused-in-game-logic-for-beginners/
This, to me, looks like a function to get the array to start at the last number of a line:
void Board::DeleteLine (int pY)
{
// Moves all the upper lines one row down
for (int j = pY; j > 0; j--)
{
for (int i = 0; i < BOARD_WIDTH; i++)
{
mBoard[i][j] = mBoard[i][j-1];
}
}
}
Then, there is the function that is causing me problems, which I will explain:
void Board::DeletePossibleLines ()
{
for (int j = 0; j < 20; j++)
{
int i = 0;
while (i < 10)
{
if (mBoard[i][j] != 1) break;
i++;
}
if (i == 10) DeleteLine (j);
}
}
In case you're not familiar, the idea here is to delete a row that consists entirely of 1. But if (mBoard[i][j] != 1) break; would stop the loop if the first line wasn't 1. How would the loop reach a 1 that is somewhere in the middle of the mBoard[][] array if break stops it from doing anything possible straight away?
Am I missing something here? This is my interpretation of it. Perhaps somebody sees something I do't?
Edit:
Thanks for the replies, appreciated.
You could structure the code like this aswell:
for (int j = 0; j < 20; j++)
{
int i = 0;
while (i < 10)
{
if (mBoard[i][j] != 1)
{
break; //only breaks the while loop and will continue with if (i == 10)
}
else
{
i++;
}
}
if (i == 10)
{
DeleteLine (j);
}
}
Now you can clearly see, that the break; is only interrupting your while loop but not your for loop.
The break will jump out of the while loop. So if you encounter a line which has a non-1 somewhere in the middle, i will be the index in the line, and the for loop will continue with the next line (j), starting with i=0 again.
break only interrupts one loop, the while loop in your case. The for loop continues happily.
On a side note, this while could easily (and should) be refactored into a for, and can be compacted according to its recognizable for-if-break pattern :
for (int j = 0; j < 20; ++j)
{
int i;
for(i = 0; i < 10 && mBoard[i][j] == 1; ++i);
if (i == 10) DeleteLine (j);
}
for (int i = 0; i<10; i++)
{
//do some validation for record length
//if it is not valid
continue; // goes to the next iteration in for loop for 'i'
for (int j = 0; j<5; j+=2)
{
//do some more validation for individual record
//if it is not valid
Here it should go to the next i if i use continue. Here it will go to the next j
Can anyone please let me know how to do this?
You need to specifically test for a flag in the outer loop if there is something after the inner loop:
for(some_outer_vars){
bool should_skip = false;
// ...
for(some_inner_vars){
// ...
if(your_condition){
should_skip = true;
break;
}
}
if(should_skip)
continue;
// ...
}
Using break; inside the j loop will exit the j loop completely.
But at least spend a couple minutes deciding if an alternate algorithm, approach, or termination condition could remove the need to break in the middle of a loop.
Do you have anything after the inner loop? If not, you can just use break:
for (i = 0; i < 10; i++)
{
if (i is no good)
continue;
for (j = 0; j < 5; j++)
{
if (j is no good)
break;
}
}
If you do need to do something later, you can use break in combination with some other flag.
Place break; instead. This should get you out of the inner loop.
for (int i = o; i<10; i++)
{
}
for (int j = 0; j<5; j+=2)
{
break;
}
"break;" will end your current j loop and go to the next i.
If you can't arrange the logic so that break in the inner loop gets straight to continuing the outer loop, then do this:
for (int i = 0; i<10; i++)
{
if (!valid(i)) continue;
for (int j = 0; j<5; j+=2)
{
if (!valid(i,j)) goto continue_i;
do_whatever_with_i_and_j()
}
more_stuff_here();
continue_i:
}
There, I've said it. The code is shorter, simpler, easier to read and easier to analyse than the version that sets a flag, then breaks, then immediately checks the flag again and conditionally continues.
Another option is this
void inner_loop(int i) {
if (!valid(i)) return;
for (int j = 0; j<5; j+=2)
{
if (!valid(i,j)) return;
do_whatever_with_i_and_j()
}
more_stuff_here();
}
for (int i = 0; i<10; i++)
{
inner_loop(i);
}
Depending what the inner loop does, though, you might find yourself building quite a mechanism to give it access to whatever it's supposed to modify.
Community wiki, because this (or situations like it) has been argued so many times on SO as to practically define "subjective and argumentative".
I try to avoid break and continue when dealing with loops because they are easy to miss and their meanings change if you have to restructure the code later. You can use j=5; when you need to exit the inner loop. If you add a third loop or a switch the meaning of that line doesn't change. Sometimes you will need to add if statements inside your loops testing i and j or even a new variable like bool iIsInvalid but I think that makes the control flow easier to read.
while (status)
for (int i = 0; i < 3; i++)
Is the following syntactically correct:
for (int i = 0; i < 3; i++ && status)
I am trying to have the for loop break early if status is true.
Syntactically, you might want to use:
for (int i = 0; i < 3 && status; i++)
which is valid.
Some consider it bad form though, as it leads to more complicated loops and annoyed maintenance programmers. Another alternative you might want to explore would be:
for (int i = 0; i < 3; i++) {
if (!status) { break; }
}
"I am trying to have the for loop break early if status is true. "
The preferred way to do this is with an if statement in the body of the for loop.
for (int i = 0; i < 3; i++)
{
if(status)
break;
}
I suspect the following is syntactically correct:
for (int i = 0; i < 3; i++ && status)
but its probably not what you mean. As pointed out by Adam, you probably want:
for (int i = 0; i < 3 && status; ++i)
This has all the meaning you want and all the details of the loop conditions are in the for statement.
The alternative form:
for (int i = 0; i < 3; i++) {
if (!status) { break; }
}
is useful if you want some code before or after the if, but the if becomes less visible to the maintenance programmer.
Note:
With status in the for statement, the loop may never run if status is false.
Syntactically correct yes. But the meaning is different.
The first piece of code, run your for loop while status is equal to 1. The second piece of code, run only the for loop for 10 times and then exits.
Instead of setting status to true you should just use "break".
Is it possible to use the break function to exit several nested for loops?
If so, how would you go about doing this? Can you also control how many loops the break exits?
No, don't spoil it with a break. This is the last remaining stronghold for the use of goto.
AFAIK, C++ doesn't support naming loops, like Java and other languages do. You can use a goto, or create a flag value that you use. At the end of each loop check the flag value. If it is set to true, then you can break out of that iteration.
Just to add an explicit answer using lambdas:
for (int i = 0; i < n1; ++i) {
[&] {
for (int j = 0; j < n2; ++j) {
for (int k = 0; k < n3; ++k) {
return; // yay we're breaking out of 2 loops here
}
}
}();
}
Of course this pattern has a certain limitations and obviously C++11 only but I think it's quite useful.
Another approach to breaking out of a nested loop is to factor out both loops into a separate function, and return from that function when you want to exit.
Of course, this brings up the other argument of whether you should ever explicitly return from a function anywhere other than at the end.
break will exit only the innermost loop containing it.
You can use goto to break out of any number of loops.
Of course goto is often Considered Harmful.
is it proper to use the break function[...]?
Using break and goto can make it more difficult to reason about the correctness of a program. See here for a discussion on this: Dijkstra was not insane.
How about this?
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
//Some statement
if (condition)
{
j=50;
k=50;
}
}
}
}
Although this answear was already presented, i think a good approach is to do the following:
for(unsigned int z = 0; z < z_max; z++)
{
bool gotoMainLoop = false;
for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
{
for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
{
//do your stuff
if(condition)
gotoMainLoop = true;
}
}
}
A code example using goto and a label to break out of a nested loop:
for (;;)
for (;;)
goto theEnd;
theEnd:
One nice way to break out of several nested loops is to refactor your code into a function:
void foo()
{
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < 50; j++)
{
for(unsigned int k=0; k < 50; k++)
{
// If condition is true
return;
}
}
}
}
I know this is an old thread but I feel this really needs saying and don't have anywhere else to say it. For everybody here, use goto. I just used it.
Like almost everything, goto is not 100% either/xor "bad" or "good". There are at least two uses where I'd say that if you use a goto for them - and don't use it for anything else - you should not only be 100% okay, but your program will be even more readable than without it, as it makes your intention that much clearer (there are ways to avoid it, but I've found all of them to be much clunkier):
Breaking out of nested loops, and
Error handling (i.e. to jump to a cleanup routine at the end of a function in order to return a failure code and deallocate memory.).
Instead of just dogmatically accepting rules like "so-so is 'evil'", understand why that sentiment is claimed, and follow the "why", not the letter of the sentiment. Not knowing this got me in a lot of trouble, too, to the point I'd say calling things dogmatically "evil" can be more harmful than the thing itself. At worst, you just get bad code - and then you know you weren't using it right so long as you heard to be wary, but if you are wracking yourself trying to satisfy the dogmatism, I'd say that's worse.
Why "goto" is called "evil" is because you should never use it to replace ordinary ifs, fors, and whiles. And why that? Try it, try using "goto" instead of ordinary control logic statements, all the time, then try writing the same code again with the control logic, and tell me which one looks nicer and more understandable, and which one looks more like a mess. There you go. (Bonus: try and add a new feature now to the goto-only code.) That's why it's "evil", with suitable scope qualification around the "evil". Using it to short-circuit the shortcomings of C's "break" command is not a problematic usage, so long as you make it clear from the code what your goto is supposed to accomplish (e.g. using a label like "nestedBreak" or something). Breaking out of a nested loop is very natural.
(Or to put it more simply: Use goto to break out of the loop. I'd say that's even preferable. Don't use goto to create the loop. That's "evil".)
And how do you know if you're being dogmatic? If following an "xyz is evil" rule leads your code to be less understandable because you're contorting yourself trying to get around it (such as by adding extra conditionals on each loop, or some flag variable, or some other trick like that), then you're quite likely being dogmatic.
There's no substitute for learning good thinking habits, moreso than good coding habits. The former are prior to the latter and the latter will often follow once the former are adopted. The problem is, however, that far too often I find, the latter are not explicated enough. Too many simply say "this is bad" and "this needs more thought" without saying what to think, what to think about, and why. And that's a big shame.
(FWIW, in C++, the need to break out of nested loops still exists, but the need for error codes does not: in that case, always use exceptions to handle error codes, never return them unless it's going to be so frequent that the exception throw and catch will be causing a performance problem, e.g. in a tight loop in a high demand server code, perhaps [some may say that 'exceptions' should be 'used rarely' but that's another part of ill-thought-out dogmatism: no, at least in my experience after bucking that dogma I find they make things much clearer - just don't abuse them to do something other than error handling, like using them as control flow; effectively the same as with "goto". If you use them all and only for error handling, that's what they're there for.].)
goto can be very helpful for breaking nested loops
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
for (l = 0; l < 1000; l++){
....
if (condition)
goto break_me_here;
....
}
}
}
}
break_me_here:
// Statements to be executed after code breaks at if condition
I'm not sure if it's worth it, but you can emulate Java's named loops with a few simple macros:
#define LOOP_NAME(name) \
if ([[maybe_unused]] constexpr bool _namedloop_InvalidBreakOrContinue = false) \
{ \
[[maybe_unused]] CAT(_namedloop_break_,name): break; \
[[maybe_unused]] CAT(_namedloop_continue_,name): continue; \
} \
else
#define BREAK(name) goto CAT(_namedloop_break_,name)
#define CONTINUE(name) goto CAT(_namedloop_continue_,name)
#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y
Example usage:
#include <iostream>
int main()
{
// Prints:
// 0 0
// 0 1
// 0 2
// 1 0
// 1 1
for (int i = 0; i < 3; i++) LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << i << ' ' << j << '\n';
if (i == 1 && j == 1)
BREAK(foo);
}
}
}
Another example:
#include <iostream>
int main()
{
// Prints:
// 0
// 1
// 0
// 1
// 0
// 1
int count = 3;
do LOOP_NAME(foo)
{
for (int j = 0; j < 3; j++)
{
std::cout << ' ' << j << '\n';
if (j == 1)
CONTINUE(foo);
}
}
while(count-- > 1);
}
The break statement terminates the execution of the nearest enclosing do, for, switch, or while statement in which it appears. Control passes to the statement that follows the terminated statement.
from msdn.
I do think a goto is valid in this circumstance:
To simulate a break/continue, you'd want:
Break
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
goto theEnd;
}
}
}
theEnd:
Continue
for ( ; ; ) {
for ( ; ; ) {
/*Code here*/
if (condition) {
i++;
goto multiCont;
}
}
multiCont:
}
Break any number of loops by just one bool variable see below :
bool check = true;
for (unsigned int i = 0; i < 50; i++)
{
for (unsigned int j = 0; j < 50; j++)
{
for (unsigned int k = 0; k < 50; k++)
{
//Some statement
if (condition)
{
check = false;
break;
}
}
if (!check)
{
break;
}
}
if (!check)
{
break;
}
}
In this code we break; all the loops.
Other languages such as PHP accept a parameter for break (i.e. break 2;) to specify the amount of nested loop levels you want to break out of, C++ however doesn't. You will have to work it out by using a boolean that you set to false prior to the loop, set to true in the loop if you want to break, plus a conditional break after the nested loop, checking if the boolean was set to true and break if yes.
I know this is old post . But I would suggest a bit logical and simpler answer.
for(unsigned int i=0; i < 50; i++)
{
for(unsigned int j=0; j < conditionj; j++)
{
for(unsigned int k=0; k< conditionk ; k++)
{
// If condition is true
j= conditionj;
break;
}
}
}
bool found = false;
for(int i=0; i < m; ++i){
for(int j=0; j < n; ++j)
if(grid[i][j] == '*'){
q.push(make_pair(i,j));
found = true;
break;
}
if(found)
break;
}
My suggestion is use a check variable to break a desired loop. The result code may not be so pleasant.
You can use preprocessors in order to make desired breaking under the hood. This approach can hides ugly codes and extra complexity.
For example, I created my custom break mechanism as follow:
Wanted code:
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
for (int k = 0; k < 100; k++) {
//do something
if (desiredCondition) {
breakToLevel = 0;
}
if (breakToLevel < 3) {
break;
}
}
if (breakToLevel < 2) {
break;
}
}
if (breakToLevel < 1) {
break;
}
}
Defined macros:
#define BREAK_TO(L) breakToLevel = (L);
#define CHECK_BREAK(L) if (breakToLevel < (L)) break;
and result:
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
for (int k = 0; k < 100; k++) {
//do something
if (desiredCondition) {
BREAK_TO(0)
}
CHECK_BREAK(3)
}
CHECK_BREAK(2)
}
CHECK_BREAK(1)
}
while (i<n) {
bool shouldBreakOuter = false;
for (int j=i + 1; j<n; ++j) {
if (someCondition) {
shouldBreakOuter = true;
}
}
if (shouldBreakOuter == true)
break;
}
you can use "goto" to leave nested loops
below is my original code including "goto"
int main()
{
string str;
while (cin >> str)
{
if (str == "0")
break;
int sum = 0;
for (auto ch : str)
{
if (ch <= 'z' && ch >= 'a')
sum += (ch - 'a' + 1);
else if (ch >= 'A' && ch <= 'Z')
sum += (ch - 'A' + 1);
else
{
cout << "Fail" << endl;
goto fail;
}
}
cout << sum << endl;
fail:
}
return 0;
}
however, I could avoid "goto" by adding a function "calculate"
void calculate(const string &str)
{
int sum = 0;
for (auto ch : str)
{
if (ch <= 'z' && ch >= 'a')
sum += (ch - 'a' + 1);
else if (ch >= 'A' && ch <= 'Z')
sum += (ch - 'A' + 1);
else
{
cout << "Fail" << endl;
return;
}
}
cout << sum << endl;
}
int main()
{
string str;
while (cin >> str)
{
if (str == "0")
break;
calculate(str);
}
return 0;
}
You can use try...catch.
try {
for(int i=0; i<10; ++i) {
for(int j=0; j<10; ++j) {
if(i*j == 42)
throw 0; // this is something like "break 2"
}
}
}
catch(int e) {} // just do nothing
// just continue with other code
If you have to break out of several loops at once, it is often an exception anyways.
Breaking out of a for-loop is a little strange to me, since the semantics of a for-loop typically indicate that it will execute a specified number of times. However, it's not bad in all cases; if you're searching for something in a collection and want to break after you find it, it's useful. Breaking out of nested loops, however, isn't possible in C++; it is in other languages through the use of a labeled break. You can use a label and a goto, but that might give you heartburn at night..? Seems like the best option though.