char i;
for (i = 1; i < 10, i++;)
{
cout << (i+1) << endl;
}
return 0;
I understand that for loop has the following syntax:
for(initialization; condition; increment)
{
}
As I run the debug, why it never checks the condition and it eventually stops at i = 0?
(Thank you Damien and Andars, I don't know why the "on purpose" statement was removed, but you interpret my question correctly. Could someone explain why the complier skips the condition before the comma, and why the loop stop at i = 0 instead of looping forever? Thanks!)
I believe he is indicating that he wrote the code that way on purpose.
To answer, i++ will always return true. The last value is the value that matters with comma separated statements, so the loop will not stop.
Edit for elaborations:
It isn't simply using a logical or, it disregards what is before the comma and only takes the last value. The value of anything non-zero is considered true, and since i starts at 1, and goes up, it will always be non-zero (until it overflows and wraps back around, which explains why i ends at 0).
If you say:
x = 4, 5, 6;
x will be equal to 6, the last value.
Change
for (i = 1; i < 10, i++;)
to
for (i = 1; i < 10; i++)
Change to
for (i = 1; i < 10; i++) //Notice correct placement of ;
It seems to me also that the code was written incorrectly on purpose. As others have mentioned, the comma operator will discard the value of the i<10 and only i++ will be evaluated as condition. This will return true until i overflows (values only from -127 to 127) and ends up at -1, when i++ will return 0 and the loop exits. Thus the final value for i will be 0.
Because you used the comma operator instead of a semi-colon
Related
I have known, '&' as bitwise and as an operator to get memory address of a variable.
What happens in this case of the code?
res = res & (a[i]<[a[i+1]]);
If it is bitwise and , as far as I know the second condition is also checked,
but what if I used logical and instead of it , wouldn't it still be the same?
As first part is (say) false , second parts get checked comes true, but still res remains false.
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
int a[] {1,3,4,2};
int pos = 3;
bool res = true;
for(int i = 0; i < pos; i++)
res &= (a[i] < a[i + 1]);
(Sorry for bad english)
If it is bitwise and , as far as I know the second condition is also checked, but what if I used logical and instead of it , wouldn't it still be the same?
No. Boolean and (written as && or and) has short circuit evaluation - if left part is false right part is not evaluated at all. This allows to write code like this:
if( pointer != nullptr && pointer->value > 100 ) ...
if not short circuit evaluation this code would have UB. For example this code:
if( pointer != nullptr & pointer->value > 100 ) ...
has Undefined Behaviour when pointer is equal to nullptr
Would it be same (for this case) to use logical and for this? or it has some other use (& operator) for this case?
You cannot, as there is no &&= operator in C++. You can write:
res = res && (a[i] < a[i + 1]);
and that would have short circuit as well and compiler may even be smart enough to stop the loop, though I doubt and it should be expressed explicitly anyway:
bool res = true;
for(int i = 0; res && i < pos; i++)
res = a[i] < a[i + 1];
which does the same, but cleaner and more efficient.
Anyway when you need logical or boolean and you should use one to make your intention clear and avoid unexpected surprises.
Besides the short circuiting issue, If res == 2 then:
res & 1 will return 0 which will be interpreted as false.
res && 1 will return true.
Your question is not clear.
Okay, let's dive into your code.
Your given code is very clear. You are performing bitwise and for pos(3) times. For every loop you are comparing a[i] with a[i+1]. Please note that for the last loop, I mean when variable i becomes 3, then i+1 will be 4. And your array a[] doesn't have a[4]. It only has the last element having index 3.
So for bitwise and operation the value of res isn't predictable as a[4] isn't defined.
Now let's think about logical AND operation. For logical and your expression inside the for loop will once generate a false boolean value for a[i] < a[i+1] as your array a[] = {1,3,4,2}. Here 4>2 not 4<2. Hence it will generate false boolean value and your entire response will be false 'cause you know logical AND will be eventually 0 if one of the operands is false.
I think you have got this.
Found as a user submission on leetcode for the problem Plus One.
vector<int> plusOne(vector<int>& digits) {
for (int i=digits.size(); i--; digits[i] = 0)
if (digits[i]++ < 9)
return digits;
digits[0]++;
digits.push_back(0);
return digits;
}
Normally there's something in the conditional like i >= 0; How is this for loop terminating and not accesing some -i element?
A for loop terminates when the second expression is false or when contextually converted to a bool value produces false. In C++, 0 is contextually converted to false; all other integers convert to true in a bool context. (Thanks to M.M.for the link.)
So at the beginning of each loop the expression i-- is evaluated. It's just an expression, so it will produce a result. If the result it produces is zero, the loop will end. If you haven't seen this expression before, here is how it works:
It both decrements i and returns the original value of i before it was decremented. So if i were 5, evaluating i-- will have the "result" 5, but as a side effect, i will be 4 after the evaluation.
The big picture: i is decremented by 1 each time, so assuming it starts off positive, it will get down to 0, at which time evaluating i-- will produce 0.
Like any normal C++ programmer, when I type this code...
for (int m = 0; m < 3; m++){
for (int n = 0; n < 3; n++){
if (A[m].substr(size,location) == B[n].substr(size,location)){
return false;
}
}
}
I expect the first value of m to be 0 in my iteration. (because I literally declared it as having a value of 0) However, my program was acting a tad funky, so I decided to look at it in the debugger. Interestingly, rather than having a starting value of 0, C++ decided that m should have a starting value of 32767.
Could someone explain to my why and how this could possibly happen?
Ah, templatetypedef was right. Once I stepped over to the next breakpoint its value was initialized. Thanks guys!
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.
I came across the following for loop with a very unusual condition
int main( int argc, const char* argv[] ) {
for ( int i = 0 ; i < ( 10, 20 ) ; i++ ) {
cout << i << endl;
}
}
This source code compiled successfully. It executed the loop with i with values from 0 to 19 (the 10 in the expression (10, 20) seems to have no effect on the number of iterations).
My question:
What is this condition syntax? Why doesn't it cause a compile error?
EDIT:
The bigger picture: this questions started with a bug, the original condition was supposed to be i < std::min( <expr A>, <expr B> ) and for some reason I omitted the std::min.
So, I was wondering why the code compiled in the first place. Now I see the bug is a legit (albeit useless) syntax.
Thanks!
It is the comma operator. It evaluates both sides of the expression, and returns the right one.
So, expression (10, 20) does nothing, but returns '20'.
See also
Uses of C comma operator.
http://en.wikipedia.org/wiki/Comma_operator
(10, 20) means evaluate the integer 10, then evaluate 20, then return 20 (the rightmost). So it just means 20.
The comma operator is often useful in for loops, as it allows things such as x = 0, y = 1 (i.e. two assignments in one expression), but here it's useless.
, operator in c++ work as a binary operator which checks first value, discard it and return the next value. In short.
for(int i=0;i<(10,20);i++) will be equal to for(int i=0;i<20;i++)