For loop doesn't stop at zero index - c++

Sorry for a probably stupid question.
My loop does not stop at 0 and I have no idea why.
This loop will stop at i = 1
for (unsigned int i = 3 ; i > 0 ; i--)
Whereas this will stop at i = 4294967295 instead
for (unsigned int i = 3 ; i >= 0 ; i--)
Why? Do I miss anything?

In fact this i >= 0 for unsigned int is always true. So you cannot use it as loop invariant.
Use this instead:
for (unsigned int i = 4 ; i-- > 0 ;)
println(i);
it will print 3,2,1,0

A for loop iterates until the break condition evaluates to false.
In your case the loop will repeatedly check:
is i>0 (i>=0 respectively) true? If so, execute body and decrement i, else skip the loop-body.
Your first loop will at some point reach i=1. i>0 will evaluate to true. The body will be executed, i will be decremented. i will then be 0. Hence i>0 will evaluate to false and the body will not be executed and you will break out of the loop.
Your second loop will not stop (tested with g++). Why? Your i will reach 0. i>=0 will evaluate to true. The body will be executed, i will be decremented. But since you are using an unsigned int this will then assign 4294967295 to i. Since 4294967295>=0, the loop will continue, reach 0 again and again assign 4294967295 to i thus executing indefinitely.
This happens since an unsigned int represents 0 as all 0s in binary and subtracting 1 from it will yield all 1s which is interpreted as 4294967295.
How to avoid the problem? As mentioned in the comments a simple way out of it would be to use an int instead of an unsigned int.

Related

Does while loop consider zero 0 as a False Condition

I have a Question About While Loop.
int space = 4;
while(space){
cout<< "*";
space --;
}
This While Loop will run 4 times and stop when value reaches to Zero 0, So my Question is we do not specify any condition like while(space > 0){...} then why it Stop.
Or this Zero 0 consider as False , and first our while loop is true and when Reaches to 0 it becomes False and Stop.
Please Tell me , i am little confused about it.
int gets converted to bool in a boolean context using space != 0.
The while loop takes a condition which is a bool. In this case, you've passed in an int instead, which will get implicitly converted to bool. That bool will be false if the int is 0, and will be true for any other value.

Incomprehensible infinite backward loop C++

I am new to C++ and I am trying to achieve a backward for loop, I founded solutions which works very well but I want to know what my version is not correct and making an infinite loop.
Here is a working version that I founded (I don't understand how we can decrease i in the condition..) :
for (unsigned i = size ; i-- > 0 ; )
{
// do stuff with i
}
Here is a version I wrote which works but don't go down to 0 (this way seems more logical to me) :
for (unsigned i = size-1 ; i > 0 ; i--)
{
// do stuff with i
}
If I say for exemple n=10, I will get this if I print i in the loop :
9
8
7
6
5
4
3
2
1
And here is the version which for me is the more logical and should go down to zero but is providing an infinite loop.
for (unsigned i = size-1 ; i >= 0 ; i--)
{
// do stuff with i
}
Could someone explain to me why the last version isn't working and what is the best choice to make ?
An unsigned number is always >= 0. (When it reaches zero a further decrement sets it to std::numeric_limits<unsigned>::max())
So your final for loop is equivalent to
for (unsigned i = size-1 ; true ; i--)
which, of course, loops forever.
In your first loop, you have i-- > 0 as the stopping condition. When i is zero, i-- is an expression with value zero (so the loop halts), despite the fact that i is then set to std::numeric_limits<unsigned>::max(). Some folk like (me included; cue the downvotes) to write i-->0 and regard --> as the slide operator. See What is the "-->" operator in C++?
The statement i >= 0 is always true because i is unsigned which means that is never below zero. If you decrease the value while i is zero, there will occur a so-called underflow and it will have a very high number.
The first version certainly gets the job done, so I would stick to it.

Why does this for loop execute five times and stop?

int i, j;
for (i=0, j=5; i=j;)
{
cout<<i<<j<<endl;
i++;
j--;
}
It executes five times:
55
44
33
22
11
When j=0, why does it stop?
for (i=0, j=5; i=j;)
sets i to j before every iteration. So the loop breaks as soon as j == 0 which happens after you decreased j five times. An integer converted to a boolean expression results in false if it is zero, and true otherwise.
Note the difference between = (assignment) and == (comparison).
The expression i=j evaluates to the value of i after the assignment. And a zero value is false when evaluated in a boolean context. So whenever i is assigned the value 0, the loop condition is false and the loop stops.

Need to understand for loop better - post increment operator

I was not really clear with the post increment operator that I always used with for loops.
My latest and newly acquired understanding of post increment operator is the following:
int a = 5
int b = a++ //a will increment and return back its old value 5
so b = 5
Armed with this new knowledge i decided to understand/apply it to the places where i commonly used the post increment operator as in a for loop . Now it seems like I am lost
since I am ending up with the wrong output theoretically
Consider the following code
for(int i=0 ; i< 3 ; i++)
{
std::cout << i;
}
First loop
i starts with 0 which is less than 3 so ( increment by 1 however since its i++ it returns old value 0)
so cout should display 1 // But it displays 0
Second Loop
i is now 1 which is less than 3 so i++ is applied - Now i is 2 and returns back 1
so cout should display 2 //But it display 1
Third Loop
i is now 2 which is less than 3 so i++ is applied - Now i is 3 and returns back 2
so cout should display 3 //But it display 2
Fourth Loop
i is now 3 which is not less than 3 so loop exits
Could anyone please clear my understanding and point me in the right direction.
The output should be 0,1,2 where am i going wrong ?
What you're missing is when each of those sections of the for statement happen:
for (int i = 0 ; i < 3 ; i++)
// 111111111 22222 333
The first bit happens once before any iterations are done.
The second expression is evaluated before each potential iteration and, if false, no further iterations are done.
The third bit is done at the end of each iteration, before returning to evaluate the second bit.
Now re-read that last bullet point carefully. The i++ is done at the end of an iteration, after the cout << i. And, immediately after that, the continuation condition is checked (the second part).
So the loop is effectively the same as:
{ // Outer braces just to limit scope of i, same as for loop.
int i = 0;
while (i < 3) {
cout << i;
i++;
}
}
That's why you get 0 1 2.
The semicolons in a for loop delimit three different expressions. The value of the third expression is irrelevant to the behavior of the loop. You could replace i++ with ++i and your loop would behave the same; either way, i is incremented by 1.
To observe the behavior of the increment operators, consider the following loops:
for(int i = 0 ; i++ < 3 ; ) cout << i;
/* ^^^ Nothing here! */
Note that the third expression is empty. The output is 123—0 is skipped because the test, including increment, occurs before every iteration of the loop.
How does the postincremented loop behave compared to a similar one with the preincrement operator?
for(int i = 0 ; ++i < 3 ; ) cout << i;
Now the output is 12—3 is not printed because the conditional test sees the value 3 as soon as it is incremented to that, so the loop exits.
You just need to know that the statement int i = 0 is executed first , i.e , i takes first the value 0 , checks if the condition is true and then what the loop body is executed .
Then , i is incremented.

For loop condition (cpp)

for (; cnt--; dp += sz)
{
pair_sanitize_struct(rec_id, ctx->api_mode, dp, FALSE);
}
Could some one explain how this for loop works? It belongs to a cpp file.
I dont understand the condition in the for loop and how it is being checked. (The function is being invoked)
The general form of for statement looks like this:
for (init-statement; condition; expression)
statement
init-statement is used to initialize or assign a starting value that is modified over the course of the loop. condition serves as the loop control. As long as condition evaluates as true, statement is executed. expression is evaluated for each iteration only if condition is true
Back to your code:
for (; cnt--; dp += sz)
init-statement here is a null statement that does nothing. condition is cnt-- which evaluates its value as cnt then decrements 1. If cnt is non-zero, condition is true, if cnt is zero, condition is false.
The condition is being interpreted as a true or false scenario.
If it's 0, then it will be false, else true.
This is equivalent to the following code -
for(; cnt-->0; dp += sz);
Because as long as a value is not equal to 0, it is considered to be true.
Remember that normal integers can be used as boolean values as well, where zero is false and everything non-zero is true.
This means that the loop will continue until cnt is zero, and then the loop will end. However that's not the whole story, since the post-decrement operator is used the value of cnt after the loop have ended will be -1.
It is similar to
while(cnt--)
{
pair_sanitize_struct(rec_id, ctx->api_mode, dp, FALSE);
dp += sz;
}
hope this is helpful.
So syntax for for loop is
for (<initialization(optional)>; <condition(Optional)>; <increment(Optional)>)
{
...
}
Say for cnt is 2 your loop works as follows,
for(; cnt--; dp+=size)
{
...
}
Execution flow is,
1. initialization statement will be executed once. Since you dont have one nothing will be executed
2. Next condition statement will be executed. In your case cnt-- which result in cnt value is considered as condition result. So, if cnt is 2 then value 2 is considered as condition result. Hence all non-zero are considered as TRUE and zero is considered as FALSE. After evaluating to TRUE it decrements cnt by 1
3. Once the condition results in TRUE then it executes the statement part say, pair_sanitize_struct(rec_id, ctx->api_mode, dp, FALSE);
4. At the last it executes the increment statement of for loop,in you case it is dp-=size;
5. It executes from 2 till condition evaluated to ZERO ie FALSE it comes out of loop.
In c++, the value for a condition being true or false is determined by being non 0 (true) or 0 (false).
The above loop would continue iterating as long as cnt is NOT 0. It will terminate when cnt becomes 0.
UPDATE:
To clear an important point here, it is the value 0 that terminates the loop. If for some reason, cnt already starts with a negative value, the loop will never terminate