Code
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i < 10)
if (i++ % 2 == 0)
cout << i << endl;
return 0;
}
The output is
3
5
7
9
Since i is 1, I thought that the if statement satisfies 2% 2 == 0 and 2 should be output, but why 3?
if (i++ % 2 == 0) means evaluate i%2 and compare to 0, and increment i at some point after evaluating it but before cout << i
That's why you're seeing odd numbers printed. In every case, an even value of i caused the statement controlled by the if to be executed, and the increment changed the even value to an odd one.
You are using post-increment, which increments the variable and then returns the old value before the increment. You are then printing the incremented value.
So, lets look at your loop step-by-step:
On the 1st iteration, i is 1. i++ sets i to 2, but returns 1. So the if compares 1 % 2 == 0, which is false.
On the 2nd iteration, i is 2. i++ sets i to 3, but returns 2. So the if compares 2 % 2 == 0, which is true, so cout << i prints 3.
On the 3rd iteration, i is 3. i++ sets i to 4, but returns 3. So the if compares 3 % 2 == 0, which is false.
On the 4th iteration, i is 4. i++ sets i to 5, but returns 4. So the if compares 4 % 2 == 0, which is true, so cout << i prints 5.
And so on...
It sounds like perhaps you were expecting i++ to pre-increment instead, returning the new value rather than the old value. In which case, there is a slightly different syntax for that purpose:
#include <iostream>
using namespace std;
int main()
{
int i = 1;
while (i < 10)
if (++i % 2 == 0) // <-- ++i vs i++
cout << i << endl;
return 0;
}
Note the position of ++ in relation to i. Both syntaxes increment i, but positioning ++ to the left of i returns the new value after i is incremented, while positioning ++ to the right of i returns the old value before i was incremented.
Same with the decrement operator --, too. It has pre-decrement and post-decrement versions.
According to the C++ 14 Standard (5.2.6 Increment and decrement)
1 The value of a postfix ++ expression is the value of its
operand. [ Note: the value obtained is a copy of the original value
— end note ] The operand shall be a modifiable lvalue. The type of the
operand shall be an arithmetic type or a pointer to a complete object
type. The value of the operand object is modified by adding 1 to
it, unless the object is of type bool, in which case it is set to
true.
So for example in the second iteration of the while loop the variable i is indeed equal to 2 after incrementing it in the first iteration of the loop
while (i < 10)
if (i++ % 2 == 0)
cout << i << endl;
Thus the condition of the if statement
if (i++ % 2 == 0)
evaluates to true. But the value of the variable i after the evaluation of the condition was incremented. So this statement
cout << i << endl;
outputs the new value 3.
You can equivalently rewrite the while loop the following way
while (i < 10)
if (i % 2 == 0)
cout << ++i << endl;
else
++i;
Related
#include <iostream>
using namespace std;
int main()
{
int arr[8];
int n = 0;
while (n < 8)
{
arr[n] = ++n;
}
for (n = 0; n < 8; n++)
{
cout << arr[n]<<" ";
}
}
output- garbage 1 2 3 4 5 6 7
expected output- 1 2 3 4 5 6 7 8
The statement arr[n] = ++n; has Undefined Behavior because it is unspecified if n is incremented before being used as the subscript in arr.
In your case, with your compiler, the increment happens first, so that you never assign anything to arr[0] and write past the end arr[8] of the array.
One way to address this is to split it into two statements:
arr[n] = n;
++n;
The evaluation order is known as sequencing, and the rules have changed as the language has evolved. Of significance, with C++17 the increment of n will happen before calculating the address to store the result in, so you'll always end up with an uninitalized first element and the write past the end of the array.
Turn on your warning flags! Your program can have undefined behavior;
main.cpp:34:18: warning: operation on 'n' may be undefined [-Wsequence-point]
34 | arr[n] = ++n;
| ^~~
main.cpp:34:16: warning: iteration 7 invokes undefined behavior [-Waggressive-loop-optimizations]
34 | arr[n] = ++n;
| ~~~~~~~^~~~~
main.cpp:32:14: note: within this loop
32 | while (n < 8)
Maybe you could do this instead:
int arr[8] { };
int n = 0;
while ( n < 8 )
{
arr[n] = n + 1;
++n;
}
for ( n = 0; n < 8; ++n )
{
std::cout << arr[n] << " ";
}
In C++ the expression on the right hand side (RHS) of the = sign is evaluated first, because you can't store (assign) a value in a variable if you haven't calculated what it is!
int myAge = 10 + 10; // calculates 20 first, then stores it.
You're changing the value of n before assigning to position n in your array - increasing it from 0 to 1 in the first iteration of the loop - and so assigning the result, 1, to array[1].
Why? Well, ++n and n++ are complicated (and frequently confusing) operators in c++, in that that they're both mathematical and assignment operators. ++n is essentially equivalent to:
n = n + 1;
return n;
Where n++ is closer to:
n = n+1;
return n -1;
You can code it more explicitly with simpler operators:
arr[n] = n+1;
n = n+1;
.. or use a for loop as you did in your output code. Using the same looping structures for both might help you achieve consistent outcomes.
You're not alone in struggling with this one. Chris Lattner felt the ++ and -- unary operators' potential for obfuscation and bugs sufficiently outweighed their benefits that they were dropped from Swift 3.
For clarification, let's consider the following program:
#include <iostream>
int main(void) {
short int i; // declaration
short int value;
short int sum;
i = value = sum = 0; // initialization
std::cout << "Enter a value: ";
std::cin >> value;
while (i != value) { // ### here's the confusion ###
sum += i;
i++;
}
std::cout << "Total sum: " << sum << std::endl;
return 0;
}
Look at the while (i != value), when this expression is given, the results shows Total sum: 45 whereas if we put while (i <= value), it shows Total sum: 55. (Input's given 10 for example)
Here, the confusion is, when should we use != and <= or >= operations in loops, any specific condition?
According to TutorialsPoint's Operators Reference
it tells that != (returns true used when two operands are unequal).
<= (returns true when used when we need to ensure if the first operand is lesser than or equal to second).
It was expected to get no difference in output, but something's misunderstood.
This while loop
while (i != value)
does not include the iteration when i is equal to value because in this case the condition i != value evaluates to false.
This while loop
while (i <= value)
includes the iteration when i is equal to value because in this case the condition i <= value evaluates to true.
In fact the first condition can be rewritten the following way (provided that initially i is less than value)
while ( i < value )
Now compare it with the condition in the second loop that in turn can be rewritten like
while ( i < value || i == value )
That is you have two different conditions.
With
while( i <= value)
the last iteration is with i == value. With
while ( i != value)
The body of the loop will not be executed when i == value. That is the reason you observe the difference.
This is a good chance to learn how to use a debugger. And/Or realize that your example is already too complicated to directly see what is going on. You would have spotted the difference more easily with
int i = 0;
int value = 5;
while ( i != value) {
std::cout << i << " ";
}
i = 0;
while ( i <= value) {
std::cout << i << " ";
}
I came accross this expression, and can't understand the meaning of line 3 in the following snippet:
int A=0, B=0;
std::cout << A << B << "\n"; // Prints 0, 0
A += B++ == 0; // how does this exp work exactly?
std::cout << A << B << "\n"; // Prints 1, 1
A adds B to it, and B is Post incremented by 1, what does the "==0" mean?
Edit:
Here's the actual code:
int lengthOfLongestSubstringKDistinct(string s, int k) {
int ctr[256] = {}, j = -1, distinct = 0, maxlen = 0;
for (int i=0; i<s.size(); ++i) {
distinct += ctr[s[i]]++ == 0; //
while (distinct > k)
distinct -= --ctr[s[++j]] == 0;
maxlen = max(maxlen, i - j);
}
return maxlen;
}
B++ == 0
This is a boolean expression resulting in true or false. In this case the result is true, true is then added to A. The value of true is 1 so the (rough) equivalent would be:
if(B == 0)
A += 1;
++B;
Note that this isn't particulary good or clear to read code and the person who wrote this should be thrown into the Gulags.
Lets break this expression into pieces: A += value, whereas value = B++ == 0. As later cout suggests, value == 1. Why is that? Here is why: value is result of comparison of B++ and 0, but ++ (increment) operation, when written after operand, is being processed after the comparison, i.e. if you write A += ++B == 0 the later cout should (and does) print 0, 1.
In the following algorithm for merge-sort, within the 3rd definition, first while loop there is:
a[k++] = (a[j] < b[i]) ? a[j++] : b[i++].
I understand that the RHS is a conditional statement stating that if the first operand is satisfied, then we should perform the second operand, and if it is not satisfied, we should perform the third operand.
What element does a[k++], a[j++] and b[i++] correspond to?
From my understanding, it should mean in each successive while loop, the element is incremented.
ie. beginning with the initialised values (i=1, j=m+1, k=1) for the first while loop, the next while loop will consist of (i=2, j=m+2, k=2), and so on.
Here is the entire algorithm:
# split in half
m = n / 2
# recursive sorts
sort a[1..m]
sort a[m+1..n]
# merge sorted sub-arrays using temp array
b = copy of a[1..m]
i = 1, j = m+1, k = 1
while i <= m and j <= n,
a[k++] = (a[j] < b[i]) ? a[j++] : b[i++]
→ invariant: a[1..k] in final position
while i <= m,
a[k++] = b[i++]
→ invariant: a[1..k] in final position
a[k] takes the kth element of the array a.
k++ increases the value of k, but returns the previous value.
Thus, a[k++] returns a[k] with the side-effect of increasing k after returning the value of a[k]. a[k++] = 4 is equivalent to:
a[k] = 4
k = k + 1
On the other hand, ++k would increase k before returning it, so a[++k] = 4 would be
k = k + 1
a[k] = 4
The increment and decrement operators work the same in array subscripts as they do in other locations. The postfix version increments the variable and returns its original value, and the prefix version increments the variable and returns its new value.
int i = 0;
do {
if (i++) { std::cout << "i > 0" << std::endl; }
} while (i < 10);
// Checks "i"'s original value.
// First check fails, because i was 0 before incrementing.
// Outputs line 9 times.
// -----
int i = 0;
do {
if (++i) { std::cout << "i > 0" << std::endl; }
} while (i < 10);
// Checks "i"'s incremented value.
// First check succeeds, because i is incremented before being read.
// Outputs line 10 times.
Similarly, if we have this:
int arr[5] = { 1, 2, 3, 4, 5 };
int i = 0;
do {
std::cout << arr[i++] << std::endl;
} while (i < 5);
The variable's original value will be used as the index, and the output will be:
1
2
3
4
5
However, if we have this:
int arr[5] = { 1, 2, 3, 4, 5 };
int i = 0;
do {
std::cout << arr[++i] << std::endl;
} while (i < 5);
The variable's incremented value is used as the index, and the output will be:
2
3
4
5
Considering this, we can take your example line, a[k++] = (a[j] < b[i]) ? a[j++] : b[i++], and read it as meaning this:
Assign value to a[k], then increment k.
Value is conditionally determined based on:
(a[j] < b[i])
If true, value is:
Read a[j], then increment j.
If false, value is:
Read b[i], then increment i.
It can be a useful time-saver if you know how to use it properly, but it can also make things harder to parse if used improperly.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Please explain the output:
#include<iostream.h>
int main()
{
int i= -3, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
OUTPUT :
-2 2 0 1
Here's what I thought:
(++i || ++j) && (++k) //Considering the precedence order
++i becomes -2 so first part of OR true, so it won't check 2nd part.
(Thanks Joachim Pileborg for telling me the short circuit evaluation)
So overall, first part of AND is true.
But that is not enough for statement to be true, 2nd part must be true to.
So ++k makes k = 1
Here's where I get it wrong. Why is k not increasing?
whereas, in this case:
#include<iostream.h>
int main()
{
int i= -1, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
OUTPUT:
0 3 1 1
I got this one too considering short circuit evaluation.
Let's start with this code snippet
#include<iostream.h>
int main()
{
int i= -3, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
It is obvious that m will be have a boolean value converted to int. As ++i is equal to -2 that is unequal to zero then all other expressions will not be evaluated because it is already known that the whole expression is equal to true. So after statement
m = ++i || ++j && ++k;
m is equal to 1 and i is equal to -2 All other variables were not changed.
In this code snippet
#include<iostream.h>
int main()
{
int i= -1, j=2, k=0, m;
m = ++i || ++j && ++k;
cout<< i <<" " << j << " " << k <<" "<<m;
return 0;
}
++i will be equal to 0. So the right operand of operator || will be evaluated. This operand is
++j && ++k
As ++j will be equal to 3 and is not equal to 0 then ++k also will be evaluated and will be equal to 1. As the both operands of operator && is not equal to zero then the result is equal to true
Thus you will get i == 0, j == 3, k == 1, m == 1.
From the C++ Standard
5.14 Logical AND operator
1 The && operator groups left-to-right. The operands are both
contextually converted to bool (Clause 4). The result is true if both
operands are true and false otherwise. Unlike &, && guarantees
left-to-right evaluation: the second operand is not evaluated if the
first operand is false.
5.15 Logical OR operator
1 The || operator groups left-to-right. The operands are both
contextually converted to bool (Clause 4). It returns true if either
of its operands is true, and false otherwise. Unlike |, ||
guarantees left-to-right evaluation; moreover, the second operand is
not evaluated if the first operand evaluates to true.
In logical expressions, such as: ... || ... && ... C++ can omit executing statements that would not change the output value of expression. For example: if it computes first value and it's output is not equal to 0, then expression: true || ... && ... is always true, therefore execution of further expressions is not necessary
Below is your second case:-
int i= -1, j=2, k=0, m;
m = ++i || ++j && ++k;
In
( cond1 || cond2)
expression if cond1 is true then compiler does not go on to check for cond2. It will evaluate cond2 only if cond1 returns false.
So, in second ++i makes first expression to be false and forces compiler to go on to evaluate further whereas in first case first expression returns true.