max defined in #define not working properly - c++

I wrote the program as follows :
#include<cstdio>
#define max(a,b) a>b?a:b
using namespace std;
int main()
{
int sum=0,i,k;
for(i=0;i<5;i++)
{
sum=sum+max(i,3);
}
printf("%d\n",sum);
return 0;
}
I got the output : 4
But when I stored max(i,3) in a variable k and then added to sum, I got the correct output:
#include<cstdio>
#define max(a,b) a>b?a:b
using namespace std;
int main()
{
int sum=0,i,k;
for(i=0;i<5;i++)
{
k=max(i,3);
sum=sum+k;
}
printf("%d\n",sum);
return 0;
}
Output : 16
Can somebody please explain why is it happening?

hash-define macros are a string expansion, not a "language" thing.
sum=sum+max(i,3);
expands to:
sum=sum+i>3?i:3;
And if you are writing that with no () round it you deserve to get the wrong answer. Try this:
#define max(a,b) (a>b?a:b)
but there are still many situations where it will fail. As others point out an even better macro is:
#define max(a,b) ((a)>(b)?(a):(b))
but it will still fail in too many situations, such as arguments with side effects getting evaluated twice. You are much much better off avoiding macros where possible and doing something like this:
template <typename T> T max(T a, T b) { return a>b?a:b; }
or, infact, using std::max and std::min which have already been written for you!

This line:
sum=sum+max(i,3);
expands to:
sum = sum + i > 3 ? i : 3;
Which, when set up with parens to make it clearer is:
sum = (sum + i) > 3 ? i : 3;
So on the 5-passes through the loop, the expressions are:
sum = (0 + 0) > 3 ? 0 : 3; // Result, sum = 3
sum = (3 + 1) > 3 ? 1 : 3; // Result: sum = 3
sum = (3 + 2) > 3 ? 2 : 3; // Result: sum = 3
sum = (3 + 3) > 3 ? 3 : 3; // Result: sum = 3
sum = (3 + 4) > 3 ? 4 : 3; // Result: sum = 4
And that's where your answer comes from.
The conventional way to solve this is to change the #define to:
#define max(a,b) (((a)>(b))?(a):(b))
But even this has some pitfalls.

I think you are having operator precedence issues, you have to remember that define will lead to a textual replacement in your source code. You should change your define to
#define max(a,b) ((a) > (b) ? (a) : (b))

The output of the prepocessor (view it with the -E flag) will be:
sum = sum+i>3?i:3;
which is the same as
sum = (sum+i)>3?i:3;
which is not what you meant because + has a higher precedence than >. You should use:
#define max(a,b) (a>b?a:b)
instead.

Replacing your macro in the line sum=sum+max(i,3); gives the following form :
sum=sum+i>3?i:3 ;
which is asking that if sum + i is greater than 3 than assign sum's value accordingly. Hence, you have 4 because each time a new assignment happens inside the loop. Use the template method suggested by Andrew.
(The loop evaluates the condition (sum + i) > 3 ? i : 3 every time. There is no cumulative addition here.)

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);

C/C++ Macro for finding maximum of two numbers without using ternary operator

I came across a interview question which reads as follows:
"Write a simple C/C++ Macro to find maximum of two numbers without using std library or ternary operator".
I need your help in solving this. I know this is trivial but I couldn't find it. So, posting it here.
#include<iostream>
#define max(x,y) /*LOGIC HERE*/
using namespace std;
void main()
{
int a = 98453;
int b = 66394;
cout<<max(a,b);
}
Use Boolean operations to get 0 or 1 and then just add them up:
#define max(x,y) (((int)((x)<(y)) * (y)) + ((int)((y)<=(x)) * (x)))
#include <iostream>
#define max(x, y) [a = x, b = y](){ if (a<b) return b; else return a; }()
int main() {
using namespace std;
int a = 10;
int b = 20;
cout << max(10, 20);
cout << max(a, b);
};
a solution just for fun : >
compiled with c++14
would blow up if x, y has different types
#define max(x,y) (x+y + abs(x-y))/2 gives you what you are looking for. This works because abs(x-y) = max(x,y) - min(x,y). So, you can rewrite the expression as follows
(x + y) + abs(x-y) = max(x,y) + min(x,y) + max(x,y) - min(x,y)
= 2*max(x,y)
As pointed out in the comments, using abs might violate the conditions what you have asked for.
#define max(x, y) x - ((x-y) & ((x-y) >> 31))
This assumes x and y are 32 bit.
This works by the fact that the most-significant bit of a negative integer is 1.
Thus if x-y is negative (y is greater than x) then x - (x - y) = y.
If x-y is positive then x is greater than y, the most significant bit is zero and thus x - 0 = x.
The 31 represents the total # of bits of the variable - 1. (thus the most significant bit).
I imagine this is what they're looking for since it doesn't use comparisons.
Aww, so many nice solutions. I have another one exploiting that booleans convert to zero and one:
#define CONDITION(c, t, f) (c * t + (1 - c) * f)
#define MAX(a, b) CONDITION(a > b, a, b)
Nearby, I'm deliberately ALL_UPPERCASING this evil macro machinery. I'd say this is the actual point you should have raised in an interview.
Another crazy C++11-only approach, and cheating slightly with an extra struct declaration (could use a std::array if libraries were allowed) - for whatever it's worth (not much!)...
struct Max { int n_[2]; };
#define max(x,y) (Max{(x),(y)}.n_[(x) < (y)])

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)

Fibonacci Function Question

I was calculating the Fibonacci sequence, and stumbled across this code, which I saw a lot:
int Fibonacci (int x)
{
if (x<=1) {
return 1;
}
return Fibonacci (x-1)+Fibonacci (x-2);
}
What I don't understand is how it works, especially the return part at the end: Does it call the Fibonacci function again? Could someone step me through this function?
Yes, the function calls itself. For example,
Fibonacci(4)
= Fibonacci(3) + Fibonacci(2)
= (Fibonacci(2) + Fibonacci(1)) + (Fibonacci(1) + Fibonacci(0))
= ((Fibonacci(1) + Fibonacci(0)) + 1) + (1 + 1)
= ((1 + 1) + 1) + 2
= (2 + 1) + 2
= 3 + 2
= 5
Note that the Fibonacci function is called 9 times here. In general, the naïve recursive fibonacci function has exponential running time, which is usually a Bad Thing.
This is a classical example of a recursive function, a function that calls itself.
If you read it carefully, you'll see that it will call itself, or, recurse, over and over again, until it reaches the so called base case, when x <= 1 at which point it will start to "back track" and sum up the computed values.
The following code clearly prints out the trace of the algorithm:
public class Test {
static String indent = "";
public static int fibonacci(int x) {
indent += " ";
System.out.println(indent + "invoked with " + x);
if (x <= 1) {
System.out.println(indent + "x = " + x + ", base case reached.");
indent = indent.substring(4);
return 1;
}
System.out.println(indent + "Recursing on " + (x-1) + " and " + (x-2));
int retVal = fibonacci(x-1) + fibonacci(x-2);
System.out.println(indent + "returning " + retVal);
indent = indent.substring(4);
return retVal;
}
public static void main(String... args) {
System.out.println("Fibonacci of 3: " + fibonacci(3));
}
}
The output is the following:
invoked with 3
Recursing on 2 and 1
invoked with 2
Recursing on 1 and 0
invoked with 1
x = 1, base case reached.
invoked with 0
x = 0, base case reached.
returning 2
invoked with 1
x = 1, base case reached.
returning 3
Fibonacci of 3: 3
A tree depiction of the trace would look something like
fib 4
fib 3 + fib 2
fib 2 + fib 1 fib 1 + fib 0
fib 1 + fib 0 1 1 1
1 1
The important parts to think about when writing recursive functions are:
1. Take care of the base case
What would have happened if we had forgotten if (x<=1) return 1; in the example above?
2. Make sure the recursive calls somehow decrease towards the base case
What would have happened if we accidentally modified the algorithm to return fibonacci(x)+fibonacci(x-1);
return Fibonacci (x-1)+Fibonacci (x-2);
This is terribly inefficient. I suggest the following linear alternative:
unsigned fibonacci(unsigned n, unsigned a, unsigned b, unsigned c)
{
return (n == 2) ? c : fibonacci(n - 1, b, c, b + c);
}
unsigned fibonacci(unsigned n)
{
return (n < 2) ? n : fibonacci(n, 0, 1, 1);
}
The fibonacci sequence can be expressed more succinctly in functional languages.
fibonacci = 0 : 1 : zipWith (+) fibonacci (tail fibonacci)
> take 12 fibonacci
[0,1,1,2,3,5,8,13,21,34,55,89]
This is classic function recursion. http://en.wikipedia.org/wiki/Recursive_function should get you started. Essentially if x less than or equal to 1 it returns 1. Otherwise it it decreases x running Fibonacci at each step.
As your question is marked C++, I feel compelled to point out that this function can also be achieved at compile-time as a template, should you have a compile-time variable to use it with.
template<int N> struct Fibonacci {
const static int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
};
template<> struct Fibonacci<1> {
const static int value = 1;
}
template<> struct Fibonacci<0> {
const static int value = 1;
}
Been a while since I wrote such, so it could be a little out, but that should be it.
Yes, the Fibonacci function is called again, this is called recursion.
Just like you can call another function, you can call the same function again. Since function context is stacked, you can call the same function without disturbing the currently executed function.
Note that recursion is hard since you might call the same function again infinitely and fill the call stack. This errors is called a "Stack Overflow" (here it is !)
In C and most other languages, a function is allowed to call itself just like any other function. This is called recursion.
If it looks strange because it's different from the loop that you would write, you're right. This is not a very good application of recursion, because finding the n th Fibonacci number requires twice the time as finding the n-1th, leading to running time exponential in n.
Iterating over the Fibonacci sequence, remembering the previous Fibonacci number before moving on to the next improves the runtime to linear in n, the way it should be.
Recursion itself isn't terrible. In fact, the loop I just described (and any loop) can be implemented as a recursive function:
int Fibonacci (int x, int a = 1, int p = 0) {
if ( x == 0 ) return a;
return Fibonacci( x-1, a+p, a );
} // recursive, but with ideal computational properties
Or if you want to be more quick but use more memory use this.
int *fib,n;
void fibonaci(int n) //find firs n number fibonaci
{
fib= new int[n+1];
fib[1] = fib[2] = 1;
for(int i = 3;i<=n-2;i++)
fib[i] = fib[i-1] + fib[i-2];
}
and for n = 10 for exemple you will have :
fib[1] fib[2] fib[3] fib[4] fib[5] fib[6] fib[7] fib[8] fib[9] fib[10]
1 1 2 3 5 8 13 21 34 55``

What is the "-->" operator in 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.