Is there a way to not evaluate the stopping condition before entering the for-loop? A sort of do-for loop?
for(int i = 0;
f(i); // This check is guaranteed to pass when i is 0,
// and the check is expensive
++i)
{
// body
}
Is the only option to convert it to a do-while loop?
If you're sure that the first time the loop condition is evaluated, it will pass, then the simplest refactor is to hoist the body out of the loop:
// body (replace uses of i with 0)
for (int i = 1; f(i); ++i) // start loop from 1 instead of 0
{
// body
}
bool skip_start = true;
for(int i = 0; skip_start || i < 10; i++)
{
if( i == 0 ) skip_start = false;
// ...
}
you mean something like this?
Related
I have problems with the break instruction;
Indeed, in my case I reproduce below an example of my calculation code, I work with two nested for loops and if loops.
I would like when the open_bound variable = 0, to completely exit the loops and thus display the value of time t. After execution I see the display of time t = 0 instead of 3 and I have trouble understanding why. Can you please enlighten me?
Is there another alternative to break? (I can't use goto, moreover I parallelize this part in the real code)
Thank you in advance
#include <iostream>
#include <vector>
using namespace std;
int main () {
int numtracers = 1000;
int save_t;
double t;
int open_bound = 0;
int tau = 5;
double int_step = 0.25;
for (int i = 0; i < numtracers; i++) {
// Variable to overwrite the successive positions of each particle
vector <double> coord(2);
coord[0] = 0.1;
coord[1] = 0.2;
int result_checkin;
for(t=0; t<tau-1; t+=int_step) {
save_t = t;
// Function to check if coordinates are inside the domain well defined
// result_checkin = check_out(coord);
if (t == tau-2) result_checkin = 1;
if (result_checkin == 1) { // Particle goes outside domain
if (open_bound == 0) {
break;
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
}
cout << save_t << endl;
return 0;
}
OK, let's first recap on what the break statement does (not counting its use in a switch block): it 'breaks' out of the innermost enclosing for, while or do ... while loop. Thus, if statements aren't considered here - and they aren't really loops, are they.
So, in your main code, you only really have two loops. Your own break will exit the innermost, jumping immediately to the point I've highlighted in the code below. Adding the extra if ... break; code, as I have done, will exit the outer loop:
for (int i = 0; i < numtracers; i++) {
int open_bound = 0; // MUST HAVE HERE to parallelize this loop!
// Variable to overwrite the successive positions of each particle
vector <double> coord(2);
coord[0] = 0.1;
coord[1] = 0.2;
int result_checkin;
for(t=0; t<tau-1; t+=int_step) {
save_t = t;
// Function to check if coordinates are inside the domain well defined
// result_checkin = check_out(coord);
if (t == tau-2) result_checkin = 1;
if (result_checkin == 1) { // Particle goes outside domain
if (open_bound == 0) {
break; // Exits the inner for loop and goes to the "-->HERE" line!
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
// Your "break" exits the for loop and execution continues -->HERE
if (open_bound == 0) break; // This will (always) exit the outer loop!
}
Does this help? Feel free to ask for further explanation!
EDIT - Note on Loop Parallelisation: If you want to parallelize the
outer loop, then you will only be able to do so if you move the declaration/definition of open_bound inside that outer loop (as I
have done in the code above)! You can't parallelize if your are trying
to modify and test a scalar variable declared outside the loop's
scope.
An alternative to exit all loops you want is to use a bool flag in order to decide when to force the loops to terminate. When you hit open_bound=0 you can first set the flag to false and then break.
Check the following to have an idea about what I mean:
bool go = true;
for (int i = 0; go && CONDITION1; i++)
for (int j = 0; go && CONDITION2; j++)
for (int k = 0; go && CONDITION3; k++)
....
if(open_bound==0){
go = false;
break;
}
A working version off your code is here
I have a loop that looks for 3 equal cards or 3 non equal cards and erases as it finds, if it doesn't find 2 equals/non-equals for the 1st chosen element it deletes that 1st element and goes to the other and so on...
Well, I'm using goto in this code to break from inside of two for loops and keep iterating throughout while.
To me, it makes good sense to use goto in this specific situation. But, since I'm not a very experienced programmer I think there would be a better way to do it, a more efficient way.
Is there? How would that be? not using goto in this case.
unsigned int i1 = 0;
while(gameCards.size() > 2)
{
for(unsigned int i2=1; i2<gameCards.size(); i2++)
{
if(i2 == 2) continue;
if(cannotMatch(gameCards.at(i1), gameCards.at(i2)))
{
for(unsigned int i3=2; i3<gameCards.size(); i3++)
{
if(cannotMatch3(gameCards.at(i1), gameCards.at(i2), gameCards.at(i3)))
{
SetMatches++;
gameCards.erase(gameCards.begin()+i2,gameCards.begin()+i3);
goto findAnother;
}
}
} else if(canMatch(gameCards.at(i1), gameCards.at(i2)))
{
for(unsigned int i3=2; i3<gameCards.size(); i3++)
{
if(canMatch3(gameCards.at(i1), gameCards.at(i2), gameCards.at(i3)))
{
SetMatches++;
gameCards.erase(gameCards.begin()+i2,gameCards.begin()+i3);
goto findAnother;
}
}
}
}
findAnother:
gameCards.erase(gameCards.begin()+(i1++));
}
You can just set an extra bool condition to break outer for loop. You can also simplify your inner loops when you notice that they are essentially the same, just invoke different match3 functions:
while(gameCards.size() > 2)
{
auto continue_outer_loop(true);
for(unsigned int i2=1; continue_outer_loop && (i2<gameCards.size()); i2++)
{
if(i2 == 2) continue;
auto const p_match_3_func
(
cannotMatch(gameCards.at(i1), gameCards.at(i2))
?
&cannotMatch3
:
&canMatch3
);
for(unsigned int i3=2; i3<gameCards.size(); i3++)
{
if((*p_match_3_func)(gameCards.at(i1), gameCards.at(i2), gameCards.at(i3)))
{
SetMatches++;
gameCards.erase(gameCards.begin()+i2,gameCards.begin()+i3);
continue_outer_loop = false;
break;
}
}
}
gameCards.erase(gameCards.begin()+(i1++));
}
You can add guard variable and check for it in your loops. But will work, only when you do it at the end of loop as it is not real break.
while (mainLoop) {
int goMain = 0;
for (int i = 0; i < 5 && goMain == 0; i++) {
for (int j = 0; j < 5 && goMain == 0; j++) {
if (wantExit) {
goMain = 1;
}
}
}
}
I have a code that looks something like this:
bool var = some condition...
if( var )
{
for( int i=0; i<10; ++i )
{
//execute some code ...
}
}
else
{
for( int i=9; i>=0; --i )
{
//execute some other code...
}
}
However, the code that needs to be executed inside the for loop is almost entirely identical, and so I don't want to write it twice. I know I can do something like this:
bool var = some condition...
for( int i = (var ? 0 : 9 ); (var ? i<10 : i>=0 ); (var ? ++i : --i ) )
{
//Execute my code
}
But this is a really un-elegant solution.
Is there a short, more elegant way of doing this? I checked std::iterator but I don't think it's what I need.
You're focusing on the wrong problem here. If you have a direction flag, don't get all hung up on the iteration variable being literally correct. Just interpret it as required:
for (int i = 0; i < n; ++i)
{
int j = var ? i : n - 1 - i;
// j goes from 0..n-1 or n-1..0
}
Unless you're doing billions of these calls, the overhead of the secondary variable will be insignificant.
You can just break the body of the loop out into a function/method and pass in sufficient context for the operation to occur. If the loop body uses mostly fields on this, making it a method should be fairly easy. Otherwise, you shouldn't need more parameters than the loop currently has.
If you're using C++11, you could implement this as a lambda capturing any necessary info, and call the lambda from within each of the loops (so as not to have a loose function). Using a function or method you can test independently is a good idea, though.
Does the code inside the loop depend on the value of the iterator, and if so, how? You might be able to use some basic math in a clever fashion, like transforming the start/end to always be 1..n, or using abs and negatives. This would leave you with one loop, and moving the body out into a function wouldn't be strictly necessary.
It's smart to want to minimize duplicate code, but that doesn't mean that your solution needs to fit in one line. Just write out the logic in a way that makes sense and is legible. Include comments to explain what you're doring and why.
bool var = some condition...
int start = 0;
int end = 9;
int increment = 1;
if (!var)
{
// Reverse direction
start = 9;
end = 0;
increment = -1;
}
// Loop (forwards if var; reversed if !var)
for (int i = start; i != end; i += increment)
{
}
You may use something like that.
for(int j = 0; j < 10; ++j) { // always increases
int i = var ? j : 10 - 1 - j;
//go
}
This looks suspiciously like iteration to me, so let's try to write a function that will help us out:
void incr(int& i) { ++i; }
void decr(int& i) { --i; }
template <typename Iter, typename Incr>
void do_work(Iter start, Iter finish, Incr incr)
{
for(Iter i = start, i != finish; incr(i))
{
// Do your code.
}
}
bool var = some condition...
if( var )
{
do_work(0, 10, &incr);
}
else
{
do_work(9, -1, &decr);
}
I want both loops to stop as soon as I find an object that has the same position in x.
Here is my C++ code:
for(int i = 0; i < sizeArray; ++i){
for(int j = i; j > 0; --j){
if (s[i].positionX == s[j-1].positionX){
s[i].positionY = s[j-1].positionY;
}
}
}
If I use break; it only breaks out of the inner for loop. What is the best way to stop both?
Options:
Set the indexes of the loops to max value (or min value) to terminate the loop.
Put all this inside a function and use return.
Use a goto
Use a Lambda
Set a boolean stop code to true, break, then listen for break and break out of other loop?
?
To break out of the innermost for loop, use break.
To break out of the outermost one, either use goto or use a combination of break and a "should stop" flag.
I would suggest lambda:
auto do_work = [&] {
for(int i = 0; i < sizeArray; ++i){
for(int j = i; j > 0; --j){
if (s[i].positionX == s[i-1].positionX){
s[i].positionY = s[i-1].positionY;
return;
}
}
}
};
do_work(); //you can call this multiple times if you need to!
No break, no goto. :-)
It serves the same purpose as break and goto in this case, but the technique seems to be clean, at least to me. Also, once you have the lambda with a name (a good name), you can use it multiple times if you need to — so this technique increases the code readability and encourages code-reuse.
Of course, if you don't need to call this multiple times, then probably you don't need a name. You just could do this:
[&]
{
//your code with the added return statement.
}();
But as I said, name increases readability even if you don't call it multiple times.
If you cannot use lambda for some reason, then you could still avoid using an extra variable such as stop and the extra work involving it (as #ssantos's answer suggested):
for(int i = 0; i < sizeArray; ++i){
for(int j = i; j > 0; --j){
if (s[i].positionX == s[i-1].positionX){
s[i].positionY = s[i-1].positionY;
i = sizeArray; //it will break the outer loop!
break;
}
}
}
Hope that helps.
I'm guessing you ask for stopping a for loop. The keyword you're looking for is break. However, if you want to exit both for loops, you'll need to add a variable to your code.-
bool stop = false;
for(int i = 0; i < sizeArray; ++i){
for(int j = i; j > 0; --j){
if (s[i].positionX == s[i-1].positionX){
s[i].positionY = s[i-1].positionY;
stop = true;
break;
}
}
if (stop) {
break;
}
}
Put the code you posted in its own function and return out of it after the assignment.
You can stop a for loop with break.
With nested for loops, things are not so easy. You can achieve your goal
either with setting a flag (done = 1; and use it with for(int j = i; j > 0 && !done; --j))
or with goto. Although goto is frowned upon by some people, it can, if used correctly and with care, be a legitimate solution for some problems, such as error handling, or in general, "finished handling".
Try the following
bool match = false;
for(int i = 0; i < sizeArray && !match; ++i){
for(int j = i; j > 0 && !match; --j){
if ( match = ( s[i].positionX == s[i-1].positionX ) ){
s[i].positionY = s[i-1].positionY;
}
}
}
Another way is the following
for(int i = 0; i < sizeArray; ++i){
int j = i;
while ( j != 0 && s[i].positionX != s[i-1].positionX ) --j;
if ( j != 0 ) {
s[i].positionY = s[i-1].positionY;
break;
}
}
I have been looking through some code and I have seen several examples where the first element of a for cycle is omitted.
An example:
for ( ; hole*2 <= currentSize; hole = child)
What does this mean?
Thanks.
It just means that the user chose not to set a variable to their own starting value.
for(int i = 0; i < x; i++)
is equivalent to...
int i = 0;
for( ; i < x; i++)
EDIT (in response to comments): These aren't exactly equivalent. the scope of the variable i is different.
Sometimes the latter is used to break up the code. You can also drop out the third statement if your indexing variable is modified within the for loop itself...
int i = 0;
for(; i < x;)
{
...
i++
...
}
And if you drop out the second statement then you have an infinite loop.
for(;;)
{
runs indefinitely
}
The for construct is basically ( pre-loop initialisation; loop termination test; end of loop iteration), so this just means there is no initialisation of anything in this for loop.
You could refactor any for loop thusly:
pre-loop initialisation
while (loop termination test) {
...
end of loop iteration
}
Some people have been getting it wrong so I just wanted to clear it up.
int i = 0;
for (; i < 10; i++)
is not the same as
for (int i = 0; i < 10; i++)
Variables declared inside the for keyword are only valid in that scope.
To put it simply.
Valid ("i" was declared outside of the loops scope)
int i = 0;
for (; i < 10; i++)
{
//Code
}
std::cout << i;
InValid ("i" does not exist outside the loop scope)
for (int i = 0; i < 10; i++)
{
//Code
}
std::cout << i;
It means that the initial value of hole was set before we got to the loop
That means loop control variable is initialized before the for loop .
For C code,
int i=0;
for( ; i <10 ; i++) { } //since it does not allow variable declaration in loop
For C++ code,
for(int i=0 ; i <10 ; i++) { }
You could omit any of the parameters of a for loop.
ie: for(;;) {} is about the same as while(true) {}
It means that the initial value of hole was set before we got to the loop.
Looks like a list traversal of some kind.
Suppose you wanted to
for (hole=1 ; hole*2 <= currentSize; hole = child)
But the value of hole just before the for loop was already 1, then you can slip this initilization part of the loop:
/* value of hole now is 1.*/
for ( ; hole*2 <= currentSize; hole = child)