What is the "-->" operator in C++? - c++

After reading Hidden Features and Dark Corners of C++/STL on comp.lang.c++.moderated, I was completely surprised that the following snippet compiled and worked in both Visual Studio 2008 and G++ 4.4.
Here's the code:
#include <stdio.h>
int main()
{
int x = 10;
while (x --> 0) // x goes to 0
{
printf("%d ", x);
}
}
Output:
9 8 7 6 5 4 3 2 1 0
I'd assume this is C, since it works in GCC as well. Where is this defined in the standard, and where has it come from?

--> is not an operator. It is in fact two separate operators, -- and >.
The conditional's code decrements x, while returning x's original (not decremented) value, and then compares the original value with 0 using the > operator.
To better understand, the statement could be written as follows:
while( (x--) > 0 )

Or for something completely different... x slides to 0.
while (x --\
\
\
\
> 0)
printf("%d ", x);
Not so mathematical, but... every picture paints a thousand words...

That's a very complicated operator, so even ISO/IEC JTC1 (Joint Technical Committee 1) placed its description in two different parts of the C++ Standard.
Joking aside, they are two different operators: -- and > described respectively in §5.2.6/2 and §5.9 of the C++03 Standard.

x can go to zero even faster in the opposite direction in C++:
int x = 10;
while( 0 <---- x )
{
printf("%d ", x);
}
8 6 4 2
You can control speed with an arrow!
int x = 100;
while( 0 <-------------------- x )
{
printf("%d ", x);
}
90 80 70 60 50 40 30 20 10
;)

It's equivalent to
while (x-- > 0)
x-- (post decrement) is equivalent to x = x-1 (but returning the original value of x), so the code transforms to:
while(x > 0) {
x = x-1;
// logic
}
x--; // The post decrement done when x <= 0

It's
#include <stdio.h>
int main(void) {
int x = 10;
while (x-- > 0) { // x goes to 0
printf("%d ", x);
}
return 0;
}
Just the space makes the things look funny, -- decrements and > compares.

The usage of --> has historical relevance. Decrementing was (and still is in some cases), faster than incrementing on the x86 architecture. Using --> suggests that x is going to 0, and appeals to those with mathematical backgrounds.

Utterly geek, but I will be using this:
#define as ;while
int main(int argc, char* argv[])
{
int n = atoi(argv[1]);
do printf("n is %d\n", n) as ( n --> 0);
return 0;
}

while( x-- > 0 )
is how that's parsed.

One book I read (I don't remember correctly which book) stated: Compilers try to parse expressions to the biggest token by using the left right rule.
In this case, the expression:
x-->0
Parses to biggest tokens:
token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0
The same rule applies to this expression:
a-----b
After parse:
token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b

This is exactly the same as
while (x--)

Anyway, we have a "goes to" operator now. "-->" is easy to be remembered as a direction, and "while x goes to zero" is meaning-straight.
Furthermore, it is a little more efficient than "for (x = 10; x > 0; x --)" on some platforms.

This code first compares x and 0 and then decrements x. (Also said in the first answer: You're post-decrementing x and then comparing x and 0 with the > operator.) See the output of this code:
9 8 7 6 5 4 3 2 1 0
We now first compare and then decrement by seeing 0 in the output.
If we want to first decrement and then compare, use this code:
#include <stdio.h>
int main(void)
{
int x = 10;
while( --x> 0 ) // x goes to 0
{
printf("%d ", x);
}
return 0;
}
That output is:
9 8 7 6 5 4 3 2 1

My compiler will print out 9876543210 when I run this code.
#include <iostream>
int main()
{
int x = 10;
while( x --> 0 ) // x goes to 0
{
std::cout << x;
}
}
As expected. The while( x-- > 0 ) actually means while( x > 0). The x-- post decrements x.
while( x > 0 )
{
x--;
std::cout << x;
}
is a different way of writing the same thing.
It is nice that the original looks like "while x goes to 0" though.

There is a space missing between -- and >. x is post decremented, that is, decremented after checking the condition x>0 ?.

-- is the decrement operator and > is the greater-than operator.
The two operators are applied as a single one like -->.

It's a combination of two operators. First -- is for decrementing the value, and > is for checking whether the value is greater than the right-hand operand.
#include<stdio.h>
int main()
{
int x = 10;
while (x-- > 0)
printf("%d ",x);
return 0;
}
The output will be:
9 8 7 6 5 4 3 2 1 0

C and C++ obey the "maximal munch" rule. The same way a---b is translated to (a--) - b, in your case x-->0 translates to (x--)>0.
What the rule says essentially is that going left to right, expressions are formed by taking the maximum of characters which will form a valid token.

Actually, x is post-decrementing and with that condition is being checked. It's not -->, it's (x--) > 0
Note: value of x is changed after the condition is checked, because it post-decrementing. Some similar cases can also occur, for example:
--> x-->0
++> x++>0
-->= x-->=0
++>= x++>=0

char sep = '\n' /1\
; int i = 68 /1 \
; while (i --- 1\
\
/1/1/1 /1\
/1\
/1\
/1\
/1\
/ 1\
/ 1 \
/ 1 \
/ 1 \
/1 /1 \
/1 /1 \
/1 /1 /1/1> 0) std::cout \
<<i<< sep;
For larger numbers, C++20 introduces some more advanced looping features.
First to catch i we can build an inverse loop-de-loop and deflect it onto the std::ostream. However, the speed of i is implementation-defined, so we can use the new C++20 speed operator <<i<< to speed it up. We must also catch it by building wall, if we don't, i leaves the scope and de referencing it causes undefined behavior. To specify the separator, we can use:
std::cout \
sep
and there we have a for loop from 67 to 1.

Instead of regular arrow operator (-->) you can use armor-piercing arrow operator: --x> (note those sharp barbs on the arrow tip). It adds +1 to armor piercing, so it finishes the loop 1 iteration faster than regular arrow operator. Try it yourself:
int x = 10;
while( --x> 0 )
printf("%d ", x);

Why all the complication?
The simple answer to the original question is just:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x = x-1;
}
}
It does the same thing. I am not saying you should do it like this, but it does the same thing and would have answered the question in one post.
The x-- is just shorthand for the above, and > is just a normal greater-than operator. No big mystery!
There are too many people making simple things complicated nowadays ;)

Conventional way we define condition in while loop parenthesis"()" and terminating condition inside the braces"{}", but this -- & > is a way one defines all at once.
For example:
int abc(){
int a = 5
while((a--) > 0){ // Decrement and comparison both at once
// Code
}
}
It says, decrement a and run the loop till the time a is greater than 0
Other way it should have been like:
int abc() {
int a = 5;
while(a > 0) {
a = a -1 // Decrement inside loop
// Code
}
}
Both ways, we do the same thing and achieve the same goals.

(x --> 0) means (x-- > 0).
You can use (x -->)
Output: 9 8 7 6 5 4 3 2 1 0
You can use (-- x > 0) It's mean (--x > 0)
Output: 9 8 7 6 5 4 3 2 1
You can use
(--\
\
x > 0)
Output: 9 8 7 6 5 4 3 2 1
You can use
(\
\
x --> 0)
Output: 9 8 7 6 5 4 3 2 1 0
You can use
(\
\
x --> 0
\
\
)
Output: 9 8 7 6 5 4 3 2 1 0
You can use also
(
x
-->
0
)
Output: 9 8 7 6 5 4 3 2 1 0
Likewise, you can try lot of methods to execute this command successfully.

This --> is not an operator at all. We have an operator like ->, but not like -->. It is just a wrong interpretation of while(x-- >0) which simply means x has the post decrement operator and this loop will run till it is greater than zero.
Another simple way of writing this code would be while(x--). The while loop will stop whenever it gets a false condition and here there is only one case, i.e., 0. So it will stop when the x value is decremented to zero.

Here -- is the unary post decrement operator.
while (x-- > 0) // x goes to 0
{
printf("%d ", x);
}
In the beginning, the condition will evaluate as
(x > 0) // 10 > 0
Now because the condition is true, it will go into the loop with a decremented value
x-- // x = 9
That's why the first printed value is 9
And so on. In the last loop x=1, so the condition is true. As per the unary operator, the value changed to x = 0 at the time of print.
Now, x = 0, which evaluates the condition (x > 0 ) as false and the while loop exits.

--> is not an operator, it is the juxtaposition of -- (post-decrement) and > (greater than comparison).
The loop will look more familiar as:
#include <stdio.h>
int main() {
int x = 10;
while (x-- > 0) { // x goes to 0
printf("%d ", x);
}
}
This loop is a classic idiom to enumerate values between 10 (the excluded upper bound) and 0 the included lower bound, useful to iterate over the elements of an array from the last to the first.
The initial value 10 is the total number of iterations (for example the length of the array), and one plus the first value used inside the loop. The 0 is the last value of x inside the loop, hence the comment x goes to 0.
Note that the value of x after the loop completes is -1.
Note also that this loop will operate the same way if x has an unsigned type such as size_t, which is a strong advantage over the naive alternative for (i = length-1; i >= 0; i--).
For this reason, I am actually a fan of this surprising syntax: while (x --> 0). I find this idiom eye-catching and elegant, just like for (;;) vs: while (1) (which looks confusingly similar to while (l)). It also works in other languages whose syntax is inspired by C: C++, Objective-C, java, javascript, C# to name a few.

That's what you mean.
while((x--) > 0)
We heard in childhood,
Stop don't, Let Go (روکو مت، جانے دو)
Where a Comma makes confusion
Stop, don't let go. (روکو، مت جانے دو)
Same Happens in Programming now, a SPACE makes confusion. :D

The operator you use is called "decrement-and-then-test". It is defined in the C99 standard, which is the latest version of the C programming language standard. The C99 standard added a number of new operators, including the "decrement-and-then-test" operator, to the C language. Many C++ compilers have adopted these new operators as extensions to the C++ language.
Here is how the code without using the "decrement-and-then-test" operator:
#include <stdio.h>
int main()
{
int x = 10;
while (x > 0)
{
printf("%d ", x);
x--;
}
}
In this version of the code, the while loop uses the > operator to test whether x is greater than 0. The x-- statement is used to decrement x by 1 at the end of each iteration of the loop.

Related

Move number away from n in C++

I am looking for a simple way to increment/decrement a number away from n, without using if statements, or creating a function. Here is an example:
Increment x from 9 to 10, n is 6
Decrement x from 3 to 2, n is 6
An obvious way to do this is with if statements, but that seems like too much code in my opinion. Here is a function that I could imagine using:
x += 1 * GetSign(6, 9) //GetSign(A, B) returns 1 or -1 depending on what would
Be necessary to move farther away from 6. The made up function above would look something like:
int GetSign(A, B)
{
if( A < B) return -1;
else return 1;
}
You can use the ternary operator:
int A = 6;
int B = 9;
x += (A < B) ? (-1) : (1);

Unexpected result regarding comparing two pointer-related integer values in C++

I have a BST of three elements {1, 2, 3}. Its structure looks like
2
/ \
1 3
Now I try to calculate the height for each node using BSTHeight() defined below and have some problem with calculating the height of '2', which value is supposed to be 1 as the heights of '1' and '3' are defined as 0. My problem is that with direct use of heights from '2's two children (see part 2 highlighted below), its height is ALWAYS 0. However, its value is correct if I use two temporary integer variables (see part 1 highlighted below). I couldn't see any difference between the two approaches in terms of functionality. Can anyone help explain why?
void BSTHeight(bst_node *p_node)
{
if (!p_node)
return;
if (!p_node->p_lchild && !p_node->p_rchild) {
p_node->height = 0;
} else if (p_node->p_lchild && p_node->p_rchild) {
BSTHeight(p_node->p_lchild);
BSTHeight(p_node->p_rchild);
#if 0 // part 1
int lchild_height = p_node->p_lchild->height;
int rchild_height = p_node->p_rchild->height;
p_node->height = 1 + ((lchild_height > rchild_height) ? lchild_height : rchild_height);
#else // part 2
p_node->height = 1 + ((p_node->p_lchild->height) > (p_node->p_rchild->height)) ? (p_node->p_lchild->height) : (p_node->p_rchild->height);
#endif
} else if (!p_node->p_lchild) {
BSTHeight(p_node->p_rchild);
p_node->height = 1 + p_node->p_rchild->height;
} else {
BSTHeight(p_node->p_lchild);
p_node->height = 1 + p_node->p_lchild->height;
}
}
Problem lies in operator precedence. Addition binds stronger than ternary operator, hence you must surround ternary operator (?:) with brackets.
Below is the corrected version. Note that all brackets you used were superflous and I've removed them. I've added the only needed pair instead:
1 + (p_node->p_lchild->height > p_node->p_rchild->height ?
p_node->p_lchild->height : p_node->p_rchild->height);
Even better would be to use std::max (from <algorithm>) instead:
1 + std::max(p_node->p_lchild->height, p_node->p_rchild->height)

How does the modulus operator work?

Let's say that I need to format the output of an array to display a fixed number of elements per line. How do I go about doing that using modulus operation?
Using C++, the code below works for displaying 6 elements per line but I have no idea how and why it works?
for ( count = 0 ; count < size ; count++)
{
cout << somearray[count];
if( count % 6 == 5) cout << endl;
}
What if I want to display 5 elements per line? How do i find the exact expression needed?
in C++ expression a % b returns remainder of division of a by b (if they are positive. For negative numbers sign of result is implementation defined). For example:
5 % 2 = 1
13 % 5 = 3
With this knowledge we can try to understand your code. Condition count % 6 == 5 means that newline will be written when remainder of division count by 6 is five. How often does that happen? Exactly 6 lines apart (excercise : write numbers 1..30 and underline the ones that satisfy this condition), starting at 6-th line (count = 5).
To get desired behaviour from your code, you should change condition to count % 5 == 4, what will give you newline every 5 lines, starting at 5-th line (count = 4).
Basically modulus Operator gives you remainder
simple Example in maths what's left over/remainder of 11 divided by 3? answer is 2
for same thing C++ has modulus operator ('%')
Basic code for explanation
#include <iostream>
using namespace std;
int main()
{
int num = 11;
cout << "remainder is " << (num % 3) << endl;
return 0;
}
Which will display
remainder is 2
It gives you the remainder of a division.
int c=11, d=5;
cout << (c/d) * d + c % d; // gives you the value of c
This JSFiddle project could help you to understand how modulus work:
http://jsfiddle.net/elazar170/7hhnagrj
The modulus function works something like this:
function modulus(x,y){
var m = Math.floor(x / y);
var r = m * y;
return x - r;
}
You can think of the modulus operator as giving you a remainder. count % 6 divides 6 out of count as many times as it can and gives you a remainder from 0 to 5 (These are all the possible remainders because you already divided out 6 as many times as you can). The elements of the array are all printed in the for loop, but every time the remainder is 5 (every 6th element), it outputs a newline character. This gives you 6 elements per line. For 5 elements per line, use
if (count % 5 == 4)

C++ reading a sequence of integers

gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.

Return statement that works but doesn't make much sense

I have the following function:
int mult(int y, int z)
{
if (z == 0)
return 0;
else if (z % 2 == 1)
return mult(2 * y, z / 2) + y;
else
return mult(2 * y, z / 2);
}
What I need to do is prove its correctness by induction. Now the trouble I'm having is that even though I know it works since I ran it I can't follow each individual step.
What is confusing me is that y only shows up as an argument and in no place does it show up in a return except in the recursive part, and yet the function actually returns y as the answer.
How does this happen? I need to be able to follow everything that happens so that I can do the iterations of it for the proof.
Since this is obviously a homework question, I recommend you do what the assinment was likely meant fot you to do. Trace through the code.
1) give a starting value for y and z.
2) either on paper or in a debugger, trace what happens when you call the function.
3) repeat step 2 with your current y/z values until program completion.
#include <iostream>
using namespace std;
int mult(int y, int z)
{
if(z==0) {
cout<<"z is null! - y:"<<y<<" z: "<<z<<endl;
return 0;
}
else if (z%2==1)
{
cout<<"z is odd! - y:"<<y<<" z: "<<z<<endl;
// make z even
return mult(2*y,z/2)+y;
}
else
{
cout<<"z is even! - y:"<<y<<" z: "<<z<<endl;
return mult(2*y,z/2);
}
}
int main() {
cout<<"result: "<<mult(3,13)<<endl;
}
Output:
z is odd! - y:3 z: 13
z is even! - y:6 z: 6
z is odd! - y:12 z: 3
z is odd! - y:24 z: 1
z is null! - y:48 z: 0
result: 39
How it works for 3 and 13:
There's a switch for even and odd numbers (see comment in code).
When z is null, the recursion "starts to return to the initial call". If the number z is odd it adds y to the returned value of the recursive call, if it's even it justs returns the value from the recursive call.
odd: return 0 + 24
odd: return 24 + 12
even: return 36
odd: return 36 + 3
step-by-step analisis
final result: 100
mult(10, 10)
{
makes 100
mult(20, 5)
{
makes 100
mult(40, 2) + 20
{
makes 80
mult(80, 1)
{
makes 80
mult(160, 0) + 80
{
return 0;
}
}
}
}
}
Note: If this is homework, tag it as such.
So, we basically got three recursive cases. To make it all clearer, I'd rewrite the C-code into some functional pseudo-code. Replace mult with an intuitive operator sign and figure out descriptive explanations of low-level expressions like (z%2==1).
You'll come up with something like
a ** b =
| b is 0 -> 0
| b is even -> 2a ** (b/2)
| b is odd -> 2a ** (b/2) + a
Do you get the point now?
One approach would be to translate each line into "English". My translation would be something like this:
if z is zero, return zero
if z is odd, return mult(y*2, z/2) + y
if z is even, return mult(y*2, z/2)
The general pattern is to recursively call mult with the first parameter doubling, and the second parameter halving.
Note that here you're calling mult with z/2, but its arguments are integers, so if your function continues to recurse, the 2nd parameter will halve each time until it gets down to 1, and then finally 1/2 which rounds down to 0 - at which point recursion will stop because z==0.
With those clues, you should be able to understand how this algorithm works.
Demonstrations by induction are based on proving that the result is valid for the first value, and that if the principle is correct for a generic value N, it is provable that it holds for N+1.
To simplify, you can start by proving that it works for z in { 0, 1, 2 } which should be trivial with a manual test. Then to demonstrate the induction step, you start with a generic z=N, and prove that if mult( y, N ) is a valid result, then mult( y, N+1 ) is also a valid result in terms of the previous one. Since there are different branches for even and odd numbers, you will have to prove the induction step for both even and odd N numbers.
ya = ya
a = an even number
b = the next odd number (in other words a + 1)
So, if you want the equation above in terms of only even numbers (an 'a') when given an odd number (a 'b') you can do the following:
yb = y(a+1) = y*a + y
Now confuse everyone by writing 'a' as 2*(z/2).
y*a becomes (2*y)*(z/2)
y*b becomes ((2*y)*(z/2))+y
Since 'z' appears in the formula for both even and odd numbers, we want to think that the code is telling us that (2*y)*(z/2) = (2*y)*(z/2) + y which is obviously MADNESS!
The reason is that we have snuck in the fact that z/2 is an integer and so z can never be odd. The compiler will not let us assign z/2 to an integer when z is odd. If we try to make 'z' odd, the integer we will really be using is (z-1)/2 instead of z/2.
To get around this, we have to test to see if z/2 is odd and pick our formula based on that (eg. either ya or yb in terms of 'a').
In mult(y,z) both 'y' and 'z' are both integers. Using the symbols above mult(2*y,b/2) becomes mult(2*y,a/2) because b/2 will be truncated to a/2 by the compiler.
Since we are always going to get an 'a' as a parameter to 'mult', even when we send a 'b', we have to make sure we are only using formulas that require 'a'. So, instead of yb we use ya+1 as described above.
b/2 = a/2 + 1/2 but 1/2 cannot be represented as part of an int.
Not really an answer, but more of a suggestion.
You may want to reduce the recursion call from 2 to one:
int mult(int y, int z)
{
int result = 0;
if (z == 0)
return result;
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
return result;
}
This could be simplified once more by observing the rule "one exit point only":
int mult(int y, int z)
{
int result = 0;
if (z != 0)
{
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
}
return result;
}
Although many compilers will perform this simplification automatically, debugging is usually easier when the code is simplified. The debugger will match the code when single-stepping.
Sometimes simplifying will add clarity. Also, adding comments will help you figure out what you are doing as well as the next person who reads the code.