Is there another alternative to break? - c++

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

Related

Do-for loop like do-while

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?

Issues with Sieve of Eratosthenes

I picked up "Programming Principles and Practice using C++", and was doing an early problem involving the Sieve of Eratosthenes, and I'm having unexpected output, but I cannot pin down exactly what the problem is. Here is my code:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> prime;
std::vector<int> nonPrime;
int multiple = 0;
for(int i = 2; i < 101; i++) //initialized to first prime number, i will
// be the variable that should contain prime numbers
{
for(int j = 0; j < nonPrime.size(); j++) //checks i against
// vector to see if
// marked as nonPrime
{
if(i == nonPrime[j])
{
goto outer;//jumps to next iteration if number
// is on the list
}
}
prime.push_back(i); //adds value of i to Prime vector if it
//passes test
for(int j = i; multiple < 101; j++) //This loop is where the
// sieve bit comes in
{
multiple = i * j;
nonPrime.push_back(multiple);
}
outer:
;
}
for(int i = 0; i < prime.size(); i++)
{
std::cout << prime[i] << std::endl;
}
return 0;
}
The question only currently asks me to find prime numbers up to 100 utilizing this method. I also tried using this current 'goto' method of skipping out of a double loop under certain conditions, and I also tried using a Boolean flag with an if statement right after the check loop and simply used the "continue;" statement and neither had any effect.
(Honestly I figured since people say goto was evil perhaps it had consequences that I hadn't foreseen, which is why I tried to switch it out) but the problem doesn't call for me to use modular functions, so I assume it wants me to solve it all in main, ergo my problem of utilizing nested loops in main. Oh, and to further specify my output issues, it seems like it only adds multiples of 2 to the nonPrime vector, but everything else checks out as passing the test (e.g 9).
Can someone help me understand where I went wrong?
Given that this is not a good way to implement a Sieve of Eratosthenes, I'll point out some changes to your code to make it at least output the correct sequence.
Please also note that the indentation you choose is a bit misleading, after the first inner loop.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> prime;
std::vector<int> nonPrime;
int multiple = 0;
for(int i = 2; i < 101; i++)
{
// you can use a flag, but note that usually it could be more
// efficiently implemented with a vector of bools. Try it yourself
bool is_prime = true;
for(int j = 0; j < nonPrime.size(); j++)
{
if(i == nonPrime[j])
{
is_prime = false;
break;
}
}
if ( is_prime )
{
prime.push_back(i);
// You tested 'multiple' before initializing it for every
// new prime value
for(multiple = i; multiple < 101; multiple += i)
{
nonPrime.push_back(multiple);
}
}
}
for(int i = 0; i < prime.size(); i++)
{
std::cout << prime[i] << std::endl;
}
return 0;
}

How to end a loop early without break

for (int att = 1; att < 11; att++)
{
<body>;
//break will completely finish running the program
}
I'm making a CodeBreaker(Mastermind) game, and I'm having trouble with ending a loop earlier than it needs to at less than 11, and then set the loop back to the initialization state of att = 1.
att stands for "attempts". The user can guess a randomly generated code up to a maximum of 10 times. Once the user guesses the correct code in less than 10 attempts, I want to prompt the user to play again and generate a new random code. But the loop shown above is still running.
How can I end the loop early, but still continue running the program? Majority of the program depends on this one loop, so break will completely stop it running.
To set the loop back to the initialization state of att = 1, you can use continue:
for (int att = 1; att < 11; att++)
{
if(you_want_to_set_loop_back) {
att = 1;
continue; //It will begin the loop back with att=1, but if any other variable is modified, they will remain as it is (modified).
}
}
OR
You can write your loop in a function with all the variable that you want at their initial value. And keep calling this function as long as you want. To break out the loop, use break and return from function or directly return from the loop instead of breaking it.
You could do something like:
while(true){
for (int att = 1; att < 11; att++)
{
<body>;
//game, and when it finishes
break;
}
//Asks player if he wants to continue, if not then break again
}
How about a while-loop around the for-loop?
while(programRunning){
for (int att = 1; att < 11; att++)
{
<body>;
if(answer==correct){
att = 12; // ends the for-loop
}
}
if(gameOver){
programRunning = false; // unless you want to end the game, starts the for-loop from att = 1
}
}
I think you might try in following way:
bool bQuitGame = false;
while(!bQuitGame)
{
for(att = 1; att < 10; ++att)
{
if(you want to only quit "for" but stay in "while")
{
<code...>
break;
}
else if(you want to quit "while")
{
<code...>
bQuitGame = true;
break
}
else if(you want to start the next iteration in "for")
{
<code..>
continue;
}
else //you want to stay in "for"
{
<code...>
}
}
}
It seems your problem can be solved by simple nested loops like these :
while(!success){
for (int att = 1; att < 11; att++){
<body>;
if(answer is correct){
success = true;
break;
}
//break will completely finish running the program
}
}

How to break out of inner for loop and get back to parent for loop

I have a code here,
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
//checking some conditions here for true or false
if(false)
{
break out of this for loop;
}
else if(true)
{
printf("true");
}
}
}
i want to break out of inner for loop and continue with the outer loop . I tried to use break but the control moved out of the parent for loop also.
Any solution for this?
I tried to use break but the control moved out of the parent for loop also.
You must be confused. break only breaks out of the innermost loop/switch, so it can't have stopped the outer loop too (unless by chance the outer loop was on its last iteration, which gave you this false impression).
When you are in doubt like this, you can either step through your code using a debugger, or at the very least insert "tracing" output in your code so that you can verify what it actually does:
for(int i=0;i<5;i++)
{
printf("outer loop %d\n", i);
for(int j=0;j<5;j++)
{
printf("inner loop %d\n", j);
//checking some conditions here for true or false
if(false)
{
printf("breaking out of inner loop\n");
break;
}
else if(true)
{
printf("true in inner loop\n");
}
}
printf("finishing the outer loop %d\n", i);
}
Yes your code is correct and it must work as you have expected.
Unless you have compiled this one and execute something another. :-)
6.8.6.3 The break statement
Constraints
1 A break statement shall appear only in or as a switch body or loop body.
Semantics
2 A break statement terminates execution of the smallest enclosing switch or iteration
statement.
Quoted from ISO/IEC 9899:TC3
So your break should work, as you don't use any pre alpha compiler.
but the problem is more
if (false) //will never be executed, as false is ever fals
{
//code gets never invoked
}
so you don't break out as you never invoke the break;
If you use break in the inner loop then it will definitely move the control to the outer loop.
I think what you might be missing is to reset your false condition after coming out of the inner loop.
It's all based on logic on when you want to break out from the inner loops. Consider the following steps.
Do
For Int x = 1 To 10
Do
Break, Break, Break
Loop
Next x
Loop
Try reconsidering your program logic and implement the break statements using flags.
If you want, you could just overcome by breaking from the inner loops by using the goto statements.
int num[5][5][5];
for (int x = 0; x < 5; x++)
{
for (int y = 0; y < 5; y++)
{
for (int z = 0; z < 5; z++)
{
if (num[x][y][z] == 256)
{
cout << "Number has been found at location: " << x << y << z;
//break the three for loops here, it's unnecessary to check any other locations
goto finish;
}
}
}
}
finish:
Break only breaks the loop in which it is used
and btw if that condition is false it will never execute
Try using a flag and checking it in your for loop conditional.
int stop = 0;
for (int i = 0; !stop && i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
if (false) {
stop = 1;
break;
}
// Condition when true does not need 'else' if breaking.
}
}

Can I use break to exit multiple nested 'for' loops?

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.