Reputation: 51
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
Upvotes: 1
Views: 986
Reputation: 51835
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.
Upvotes: 0
Reputation: 310980
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;
}
Upvotes: 2
Reputation: 11410
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;
Upvotes: 2