C++ Assignment don't work - c++

Sorry for this very simple looking problem, but I have no idea what causes it:
In a C++ project I have a loop in a loop in a loop and have to leave the inner two so I have a variable for a query. In the first iteration it works fine, but in the second the assign from dtime to abbruch does not work. In the Debugger dtime has correctly the value "1" and abbruch "0" but this stays after the assignment. Both are of type long.
for (sect = 0; sect <= sections; sect++)
{
abbruch = 0;
for(line = 0; line < maxlines ; line ++)
{
abbruch = dtime[sect][0];
if(abbruch != 0)
{
break;
}
for (index = 0; index < 30; index ++)
{
if (complicated query)
{
dtime[sect][0] = DiffTime[maxlines * sect + line];
break;
}
}
}
}
I use VS2012 Ultimate.
Has anyone an idear how this can happen ot how to solve it?

Did you maybe mean to put this?
abbruch = dtime[sect][line];
(line instead of 0)
But also what Bathseba said is true. A break will only break one for-loop.

break will only take you out of the current for loop. In your case, the loop over index will not be called following a break when abbruch != 0 as that break will take you out of the loop over line. The other break statement will take you out of the loop over index.
That's the rationale, but, by far the best thing to do is to step through with a debugger. I wouldn't use break statements in this way as it's too confusing. Consider breaking the triple loop structure into function calls using return statements in place of breaks.
Also, it's a good idea to localise the interating variables in the for loops, e.g.
for (int sect = 0; sect <= sections; sect++)

Related

Is the Break keyword the most efficent way to exit a for loop? C/C++

Is break the most efficient way to exit a loop? In the code snippet below, would line A or line B be the more efficient way to exit the loop? Any links to material on how the break instruction works under the hood would be appreciated.
for (int i = 0; i < 10; i++) {
cout << i << endl;
if (i == 3) {
break; // A
i = 15; // B
}
}
I assume the difference is trivial in most situations, and that A is faster because B requires an assignment, an increment, and then a comparison, but I don't actually know how break works and it's better to know than assume. Thanks!
Let's compile the following code and look at the assembly:
#include <stdio.h>
int loop_with_break() {
for (int i = 0; i < 10; i ++) {
puts("Hello, world!");
if (i == 3) {
break;
}
}
}
int loop_with_assignment() {
for (int i = 0; i < 10; i ++) {
puts("Hello, world!");
if (i == 3) {
i = 10;
}
}
}
int main() {
loop_with_break();
loop_with_assignment();
}
As you can see, when you use break, if i == 3, it'll jump straight out of the loop to the end of the function, whereas if you use i = 10, it'll set i to 10, increment it by 1, then do the comparison, which is slower. However, this was compiled with no optimizations. If you use optimizations, they both end up becoming the same thing. However, since break is more readable and these optimizations are not guaranteed, you should use it for breaking out of loops.
The keyword break will just quit the loop without any comparison made in the loop condition. If you use i = 15 syntax, the loop will iterate next time to verify whether the variable i is greater than 10, if so, then quit.
In short words, break will break the loop without thinking anything, whereas i = 15 will lead one more iteration to look if the condition satisfies it.
You're right! Actually break keyword is very faster for breaking loop!
In your example, if you use line A, then as soon as control reaches this statement, it will immediately break the loop.
On the other hand, if you use line B, then first the assignment will be performed and again the control will go to the condition checking and when the condition will get false then it will exit from the loop!
if you choose while loop you can prefer to make condition false in the while loop. But in this case using break make sense.

Change for loop condition with respect to an external flag (cpp)

I have a code block as following, where the inner for loop code remains the same but only the loop condition changes based on the reverseFlag. Is there a better way to code this without having to copy paste the content of the for loop twice ?
bool reverseFlag=false;
if (reverseFlag)
{
for(int i = 1; i < TotalFrames; i++)
{...}
}
else
{
for(int i = TotalFrames-1; i >0; i--)
{...}
}
Yes, you can do it in a single for loop, like this:
int from, to, step;
if (reverseFlag) {
from = TotalFrames-1;
to = -1;
step = -1;
} else {
from = 0;
to = TotalFrames;
step = 1;
}
for (int i = from ; i != to ; i+= step) {
...
}
A single conditional ahead of the loop prepares loop's parameters - i.e. its starting and ending values and the step, and then the loop uses these three values to iterate in the desired direction.
There are several options. You can:
Use two loops but put the loop body in a separate function/object/lambda.. to avoid duplication.
Use an increasing loop and calculate the real index within the loop:
j = reverseFlag ? TotalFrames - i : i;
Pre-calculate the loop conditions as #dasblinkenlight suggested.
Note that if you have a performance critical loop, some of these methods could hurt performance. If in doubt, check what your compiler does and measure the elapsed time.

C++ character variable value of '\x1'

I'm failing to understand why would the loop exit at the value of character variable i = '\x1'
#include <iostream>
using namespace std;
int main()
{
char i;
for (i = 1; i < 10, i++;)
{
cout << i << endl;
}
return 0;
}
Can somebody please explain this behavior ?
This is wrong
for (i = 1; i < 10, i++;)
/* ^ should be ; */
You only declared 3 regions for the loop, but put your increment statement in the middle area, and left your increment area empty. I have no idea which statement in the middle area your compiler will choose to execute. Best not to try to be cute and deceive your compiler. Let alone some colleague who will read your code years from now and go WTF???
A for loop has 3 distinct areas delimited by semi-colons:
The initialization area. You can declare as many variables in here as you want. These can be delimited by commas.
The test area. This is where an expression goes to test if the loop should continue.
The post loop area. This region of code gets executed after every loop.
Try to keep it simple. If it is going to be more complicated then use a while loop.
The reason that i ends up being 1 is that when i++ is zero, which terminates the loop, then i will become 1 (That is what the form of the ++ operator you used does). As the other answered have pointed out, once you fix your code by moving i++ out of the condition by replacing the comma with a semicolon, then i will make it all the way to 10 as desired.
for (i = 1; i < 10; i++)
You wrote for statement wrong.

Issues of getting stuck into infinite loop while iterating through vectors

I want to search through a vector of pairs and in order to do so..i am doing the following:
vector<pair<double ,double> > vec_pairs;
for(vector<unsigned int>::size_type j = 0; j != vec_pairs.size(); j++ )
{
if(vec_pairs[j].first==12.6)
{
int z=7;
continue;
}
}
However my problem is...upon doing this...i am getting stuck in an infinite loop...
Can anyone help me in resolving the problem
First of all, the code that you posted works well 'as it is'.
The only reason for such type of a code to go into infinite loop is to modify j inside the loop.
If you increase j inside the loop, you will probably not get stuck because you will go out of bonds and might have your code crash.
for(vector<unsigned int>::size_type j = 0; j != vec_pairs.size(); j++ )
{
if(vec_pairs[j].first==12.6)
{
j++;//You will go out of vector bonds and might get an error here.
continue;
}
}
However, if you do something like this:
for(vector<unsigned int>::size_type j = 0; j != vec_pairs.size(); j++ )
{
if(vec_pairs[j].first==12.6)
{
j--;//j is decreased each time you get in here, so you will be stuck on one element,
continue;
}
}
Then you will get stuck inside, because when you go into the if statement (say, on element 7), j will decrease to 6, then you will continue the loop, j will increase back to 7, you will go inside the if again, and so on.
I have tested your code in codepad. Check it here! And it is working fine. Check the value of the variable j while debugging. As SingerOftheFall said, It might be getting decremented or reset somewhere. It can also go on an infinite loop if you are adding elements inside the loop which increase the value of vec_pairs.size() and the condition j != vec_pairs.size() will never be true in that case. Can't find anything wrong in the code you given.

Beginner for loop problem

[EDIT]Whoops there was a mistake in the code, and now all the responses to the question seem bizzare, but basically the for loop used to be, for(i=0; i<15; i++). I also edited to make the question more clear.[/EDIT]
I am trying to make a for loop, that checks a 16 element array, so it loops from 0 to 15. I then use the i variable later, however sometimes i == 16, which causes problems by being out of bounds.
I have a solution but it doesnt seem elegant, which makes me think I am missing something. I've tried while loops, but I can never get any loop to go from 0 to 15, and never end at a value greater than 15.
Is there any way to make a loop go and check all 16 elements of the array, while never being greater than 15 at the end of the loop?
int i;
for(i=0; i<16; i++)
{
someClass.someMethod(i);
if(someClass.Test())
{
break;
}
}
if (i == 16)
{
i = 15;
}
I suggest using some other variable other than i after your loop is finished. The criteria of using a for loop instead of a while loop is that you know beforehand exactly how many times a for loop will execute. If you already know this, just set some other variable to the ending value of your loop and use it instead of giving i a dual purpose.
int j = 15;
for(int i=0; i <= j; i++)
{
someClass.array[i];
}
// continue on using j, which value hasn't changed
Well for starters, your sample code loops from 0 to 14. But if you loop from 0 to 15, naturally i has to be 16 before the loop can end. What happens is it becomes 16, THEN your loop notices it's out of bounds and breaks out. If you want it to end at 15, honestly the easiest thing to do is just decrement just after the loop end.
i is incremented on last check to be 16, which is not less than 15, so loop exits with i being 16.
Maybe it's useful to know that:
for (before; check; after) { body }
it's the same as:
before
while(check) {
body
after
}
If you think at your for loop in that term, maybe you'll find out easily why i, at the exit, is 16.
There seems to be some fundamental flaws in your approach.
You shouldn't really use an index variable outside the scope of the loop.
You should use a variable or function to determine the limit of the loop.
It would be better to use iterators instead of numeric indexes.
Generic algorithms can remove the need for loops.
Just my $0.02.
So - if you're checking a 16 element array, normally you'd do this:
for(i=0; i<16; i++)
How for works, is it starts with the first statement of three:
i=0
Then it does your check, in the second statement:
i < 16 // True here, since 0 < 16
That happens before your loop. Then it runs the block of your loop with that set:
someClass.array[i]; //0
Finally, it does the final statement:
i++
Then it repeats the second and third statements, in a sequence.
Before the last run, i == 14, then it does i++, setting i to 15, and executes the block. Finally, it does i++, setting:
i==16
At this point, the condition is no longer true:
i < 16 // False, since i==16
At this point, your block does not execute, but i is still set to 16.
You must have missed something.
In this loop it wouldn't even hit 15, you'd need to say i <= 15, as soon as i = 14 it'd run once and bail.
The for loop is equivalent to the following while loop:
i = 0;
while(i < 16) {
someClass.array[i];
i++;
} // while
i needs to reach 16 to get out of the loop correctly.
Technically there are ways of writing the loop such that i is 15 on exiting the loop, but you shouldn't do them:
int i = 0;
while (1) {
someclass.someMethod(i);
if (i < 15) {
i++;
} else {
break;
}
}
Yes, it does what you ask. But the flow is horrible.
You cannot accomplish this with the built-in loop structures, and as Bill The Lizard said, you probably don't really want to reuse the for-loop variable.
But, if you really want to, here's a way to do it. The trick is to put the loop condition in the middle of the loop:
int i = 0;
while (true)
{
someclass.array[i];
if (i == 15)
break;
++i;
}
The key issue to understand here is that there are 17 different answers to the question "What value of i causes the test to succeed?". Either i can be in {0, 1, ..., 15}, or no value of i causes the test to succeed, which is denoted by i == 16 in this case. So if i is restricted to only 16 values, the question cannot be answered.
There are legitimate cases where you do not want to go past the last valid value. For instance, if you had 256 values and for some reason you only have one byte to count with. Or, as happened to me recently, you want to examine only every ith element of an array, and the last addition to your iterator takes you far beyond the end of the array. In these cases loop unrolling is necessary.
However, for this problem it would be cleaner to use a flag:
bool flag = false;
for (int i = 0; i < 15; ++i)
{
someClass.someMethod(i);
if (someClass.Test())
{
flag = true;
break;
}
}
Then it's clear whether or not the test ever succeeded.
If your loop terminates natuarally, rather than with a break, i will be 16. There's no way to avoid this. Your code is perfectly acceptable if what you want is for i to end up as 15 or less:
int i;
for (i=0; i<16; i++) {
someClass.someMethod(i);
if (someClass.Test())
break;
}
if (i == 16)
i = 15;
Anything that changes i from 16 to 15 after the loop body will do:
if (i == 16) i = 15;
i = (i == 16) ? 15 : i;
i = MAX (15,i); /* where MAX is defined :-) */
and so on.
However that assumes that i is going to be used for something meaningful as a post-condition with respect to that loop. I find that's rarely the case, people tend to re-initialize it before re-use (such as another for loop).
In addition, what you are doing makes it very difficult (impossible, even) to figure out as a post-condition, wheteher your loop terminated normally or whether it terminated prematurely because someClass.Test() returned true for i == 15. This means using i to make further decision is fraught with danger.
My question would be: Why do you think you need to leave i as 15 or less?
I am trying to make a for loop, that
checks a 16 element array, so it loops
from 0 to 15. I then use the i
variable later, however sometimes i ==
16, which causes problems by being out
of bounds.
You need to check for the case where your for loop didn't break, because this information determines whether or not whatever you wanted to do with i is valid.
There are a couple of ways to do this. One is to keep track of it in a bool, such as "foundClass" or "testSucceeded". Default it to false, then set it to true on your break. Enclose any uses of i later in the function in "if (foundClass) { }" blocks.
Another is to just do what you've done. Although your fallback doesn't look right at all. If you're setting i to 15, you're lying to your code and telling it that someClass.Test() succeeded for i == 15, which isn't true. Avoid setting the value to something that's wrong just so your code doesn't error later on. It's much better to put bounds checks around the actual usage of i later in the code.
for(int i=0; i<17; i++)
{
if(i<16)
{
someClass.someMethod(i);
if(someClass.Test())
{
break;
}
}
else if(i==16)
{
i=15;
}
}
if you say you have an array with 16 elements, you don't have to define that, use the array to get that info (DO NOT DUPLICATE INFORMATION)
afterwards if you want to get the last index again use the array to get that info.
for(int i = 0; i < myArray.length; ++i){
myArray[i].somemethod();
}
// lastindex = myArray.length-1;