Two for loops and an if statement inside it - c++

My code is something like this:-
for() //outer for
{
for() //inner for
{
if()
{
break;
}
}
}
If the break statement executes the next execution will be of which for loop?
I know this is a very abstract question but I really don't have time to write the full code. Thanks.

break will break the inner for **loop** only. It breaks the closest loop ONLY where it was called.
In your example, if your if condition is satisfied, it will stop iterations of the inner for loop and move back(continue) the outer for loop.

The break statement terminates the execution of the nearest enclosing do, for, switch, or while statement in which it appears. In this case, that means breaking out of the inner for only.
Edit: Standard Reference: 6.6.1 The break statement [stmt.break]
1 The break statement shall occur only in an iteration-statement or a
switch statement and causes termination of the smallest enclosing
iteration-statement or switch statement; control passes to the
statement following the terminated statement, if any.

You can use goto to break the outer loop as well if you like.

You'll need a way to break the outer loop as the break will only leave its enclosing scope. What you use to manage state can be anything, but in its most simple form you can just use a boolean and check for that as well as your original condition in the outermost loop.
bool breakLoop = false;
for(...; ... && !breakLoop; ...) //outer for
{
for() //inner for
{
if()
{
breakLoop = true;
break;
}
}
}

Related

C++ Will all code inside a nested 'if' statement run, even if that changes the boolean value of the outside statement?

I have a couple of if statements in my C++ code (one nested inside the other), and I want to be sure that they will run as I expect- the code is:
if(state == entry){
if(abs(distance < 0.05){
state = arcing;
...
startAngle = positionAC;
}
// Some more statements here...
}
If the second if statement condition is met, will the code where my comment "// Some more statements here..." be run now that the value of state has changed to arcing rather than entry? I would have thought that they should be run because the code will still be executing from when the first condition was true, even though it now no longer will be. Is this correct?
The if-check
if(state == entry)
will be performed exactly once, at the moment that line is reached in the code.
From then on, it doesn't matter if the values of state or entry are modified - the entirety of the code inside the if-block will be executed, if state was equal to entry when that line was reached.
Yes. I remember once having this doubt about the Pascal while loop. The text book we had didn't describe the workings of the loop in very concrete terms, but only that it iterated “while” the condition was true. Some experimentation convinced me that the condition was only checked once per iteration, namely at the start of the loop. But the thing is, I should not have had to check that: the book should have been clear on that.
So, clarity:
A C++ if statement like
if( condition )
{
action_1;
action_2;
action_3;
}
something_more;
is 1equivalent to:
const bool do_it = condition; // The single evaluation of condition
if( do_it ) goto do_actions;
goto do_more_things;
do_actions: // Just a name for this place in the code, a "label".
action_1;
action_2;
action_3; // The next executed statement is something_more.
do_more_things:
something_more;
And yes, both are valid C++ code.
1) This equivalence ignores possible name collisions, and it assumes that none of the actions are declarations. Declarations can foil the equivalence in two ways. First, it's not permitted to goto-jump over a declaration that executes initialization and that's in scope at the point jumped to. Second, destructors are executed when the execution leaves a block, and to capture that one has to imagine that those destructor executions are among the actions.
If the condition in the if statement
if(state == entry){
will be evaluated to true (it is evaluated only once in this point) then the compound statement of the if will be executed.
The statements under the comment will be executed exactly once, unless the first condition itself is NOT within a loop, or a method which is called recursively.
But if you want to make sure that the code after the comment is executed only when the state == entry at that point of time you can change your code as below
if((state == entry) && (abs(distance < 0.05)) {
state = arcing;
...
startAngle = positionAC;
}
else if (state == entry)
{
// Some more statements here...
}

Meaning of do-while in this code

In the tutorial of Nextpeer you can see such code:
CCScene* GameLayer::scene() {
CCScene * scene = NULL;
do {
// 'scene' is an autorelease object
scene = CCScene::create();
CC_BREAK_IF(! scene);
// 'layer' is an autorelease object
GameLayer *layer = GameLayer::create();
CC_BREAK_IF(! layer);
// add layer as a child to scene
scene->addChild(layer);
} while (0);
// return the scene
return scene;
}
What is the meaning of do-while block in this code?
CC_BREAK_IF is a macro for if(condition) break. (Edit: I've confirmed that it is.)
This is an idiom used for a structured goto:
do {
if (!condition0) break;
action0();
if (!condition1) break;
action1();
} while(0);
do...while(0); exists only to allow a break statement to skip some section of code.
This would be similar to:
if (!condition0) goto end;
action0();
if (!condition1) goto end;
action1();
end:
Except it avoids the use of goto.
The use of either of these idioms is to avoid a nested if:
if (condition0) {
action0();
if (condition1) {
action1();
}
}
In C and C++ the break statement works only in select contexts: a while, do/while or for loop or in a switch statement. The CC_BREAK_IF macro presumably executes a break if the condition is met. This is a simple method for handling exceptional/error conditions in C (a poor man's exception handling, if you will).
The do/while loop that never loops simply provides a context for the break statements to work.
The meaning is to make CC_BREAK_IF statements work correctly, that is to break the loop and jump to return scene;.
It's a common method when you have several conditional statements which would otherwise result in a chain of if/else clauses. Instead you use a single iteration loop and use break statements to exit the loop (CC_BREAK_IF is probably a macro which tests an expression and break if true).

While loop within a while loop, how to both conditions work?

I am writing a program that involves reading numerous bits of data from files, and I have ran into a bit of a dilemma (being a relatively inexperienced programmer). If a while loop is contained within another while loop, which conditions need to be fulfilled in order to leave the loop?
My specific situation is shown below, (emptyLineFound is a Boolean set to be true when empty line has been found)
while(!file.eof()) {
....
while(!emptyLineFound) {
....
}
}
Which condition takes priority? Must they both be satisfied to leave that section of code? e.g if it is at the end of the file and an empty line can not be found as there is no line, will it mess up?
Both sections do not have to be satisfied for the nested while to exit.
while(!file.eof()) {
Will continue to run while the file is not at the end of the stream.
while(!emptyLineFound) { .... }
Will continue to run while an empty line is not found.
Once an empty line is found, you will drop out of the nested loop and the parent loop will continue until the condition is satisfied (EOF is reached).
While(ExitCondition)
{
// you are at this point if ExitCondition fails .
while(another-ExitCondition)
{
// you are at this point if another-ExitCondition fails
}
// you will come at this point once another-ExitCondition becomes true
}
// you will be at this point once ExitCondition becomes true .
In your question, the inner loop will end when emptyLineFound is true. The outer loop will continue until file.eof() is true. Presumably something in the inner loop sets emptyLineFound to false before the next loop.
Note that the conditions are tested as the code gets there, so, in theory you could have something like this:
while(!file.eof())
{
while(!emptyLineFound)
{
... do some reading ...
if (file.eof())
{
... reset file so we can do more reading ...
}
}
}
and the loop would continue forever, except if file.eof() is true from the very beginning of the loop.
By the way, in general, using !file.eof() as a loop control is a pretty poor idea. It is much better to use the read operation itself, e.g. while (file >> var) ... - since while (!file.eof()) tends to lead to an extra iteration, because file.eof() isn't true until you have read PAST the end.
Each time the outer loop is repeated, the inner loops are reentered and start new.
Perhaps the code becomes clear if expressed differently:
void f()
{
// ...
while (!file.eof()) {
// ...
}
}
int main()
{
// ...
while (!emptyLineFound) {
f();
}
}
This is semantically the same as your program; it has the same overall logic.
From here, you can clearly see that a call to f() will not terminate until f.eof() is true, and that main will repeatedly call f() (and thus perform the "inner" loop) until emptyLineFound is true.

Weirdest C++ stack empty() fault

My program crashes because it reaches a stack.top() it shouldn't reach, as the stack is empty.
I have an if which checks just that:
if(!st.empty());
//do stuff
(I have initialized
stack<int> st;
).
But although I can see in the debug that the stack is empty, it still goes in the if!
I even wrote this code:
if(st.size()>0);
cout<<st.size();
And it prints 0!
What is going on and how can I fix it? Thanks!
The semicolons after the if statements are the problem
BAD:
if(st.size()>0); // <-- this should not be here!!!!!!!!
cout<<st.size();
Properly rewritten:
if(st.size()>0) {
cout<<st.size();
}
Also, as #WhozCraig pointed out, the other statement has a semicolon too!
BAD:
if(!st.empty()); // <--BAD!
//do stuff
Good:
if(!st.empty()) {
//do stuff
}
ALWAYS!! use brackets with branches (if, switch), and loops (for, while, do-while)!!! It pays off big time! (Not to mention, a cute kitten dies each and every time such a block is written without brackets!) ALWAYS!!
For example this can kill a day in debugging:
BAD:
int i=0;
...
while(i++<1000);
doStuff(i);
Good:
int i=0;
...
while(i++<1000) {
doStuff(i);
}
Beware (as #WhozCraig pointed out again) this does not automagically solve the problem of semicolon terminated branch and loop statements, as this is perfectly valid syntax:
if (condition);{ ...code... }
Or
if (condition);
{
...code...
}
But in my opinion and experience (this is totally subjective!) - as I myself have fallen into this trap a couple of times - I experienced that when I have the curly bracket after the aforementioned statements, I didn't ever make the mistake of typing a semicolon again. Adhering to this convention was a silver bullet - for me, and others could benefit from this too. Also, if there was a semicolon there, it would immediately catch my eye, just by looking, as it is an "uncommon pattern of characters".
There is no "in the if", as your if contains only an empty statement:
if(!st.empty());
//do stuff -- that's outside the if!!!!
(Background: The syntax is if (condition) block, with block being either a statement or a block of statements. ; is an empty statement, so if (...) ; means "if condition fulfilled then do nothing" -- which probably never is what you have in mind.)
You should write
if(!st.empty()) {
//do stuff -- now it's inside!
}
Be careful! Do NOT write
if(!st.empty()); // notice the semicolon making it wrong; without the semicolon it would be ok
{
// outside again
}

Using continue in a switch statement

I want to jump from the middle of a switch statement, to the loop statement in the following code:
while (something = get_something())
{
switch (something)
{
case A:
case B:
break;
default:
// get another something and try again
continue;
}
// do something for a handled something
do_something();
}
Is this a valid way to use continue? Are continue statements ignored by switch statements? Do C and C++ differ on their behaviour here?
It's fine, the continue statement relates to the enclosing loop, and your code should be equivalent to (avoiding such jump statements):
while (something = get_something()) {
if (something == A || something == B)
do_something();
}
But if you expect break to exit the loop, as your comment suggest (it always tries again with another something, until it evaluates to false), you'll need a different structure.
For example:
do {
something = get_something();
} while (!(something == A || something == B));
do_something();
Yes, continue will be ignored by the switch statement and will go to the condition of the loop to be tested.
I'd like to share this extract from The C Programming Language reference by Ritchie:
The continue statement is related to break, but less often used; it causes the next iteration of the enclosing for, while, or do loop to begin. In the while and do, this means that the test part is executed immediately; in the for, control passes to the increment step.
The continue statement applies only to loops, not to a switch statement. A continue inside a switch inside a loop causes the next loop iteration.
I'm not sure about that for C++.
Yes, it's OK - it's just like using it in an if statement. Of course, you can't use a break to break out of a loop from inside a switch.
It's syntactically correct and stylistically okay.
Good style requires every case: statement should end with one of the following:
break;
continue;
return (x);
exit (x);
throw (x);
//fallthrough
Additionally, following case (x): immediately with
case (y):
default:
is permissible - bundling several cases that have exactly the same effect.
Anything else is suspected to be a mistake, just like if(a=4){...}
Of course you need enclosing loop (while, for, do...while) for continue to work. It won't loop back to case() alone. But a construct like:
while(record = getNewRecord())
{
switch(record.type)
{
case RECORD_TYPE_...;
...
break;
default: //unknown type
continue; //skip processing this record altogether.
}
//...more processing...
}
...is okay.
While technically valid, all these jumps obscure control flow -- especially the continue statement.
I would use such a trick as a last resort, not first one.
How about
while (something = get_something())
{
switch (something)
{
case A:
case B:
do_something();
}
}
It's shorter and perform its stuff in a more clear way.
Switch is not considered as loop so you cannot use Continue inside a case statement in switch...