Macros in C++ breaks with postfix increments - c++

I need a working MAX macros (without(!) declaring main function) which assign 'r' the maximum of numbers 'a' and 'b'. This code breaks in compilation. How can it be fixed?
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 10;
int y = 20;
int r;
MAX(x, y, r);
Thanks for watching!
UPD: Some revision to clear the full task:
#import <iostream>
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 1;
int y = 1;
int r = 1;
int main()
{
MAX(x++, y, r);
std::cout << r;
return 0;
}
The result of this code is 1, and need to be 2. So I need another logic in my macros to consider all postfix increments

You can't use this macro outside of a function, because it's an arbitrary expression, that's why you're getting an error.
Just move the invocation of the macro into function scope and it will work:
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 10;
int y = 20;
int r;
int main()
{
MAX(x, y, r);
}
Using macros in this case is, however, unnecessary (unless this is just an exercise to learn macro usage); making max a function (or, better yet, using std::max) would be a better and less error-prone way.

It doesn't work because you can't put arbitrary expressions at file-scope. I have a couple of suggestions:
Don't use global variables unless you really, really have to. They'll just cause you pain.
Don't use macros unless you really, really have to. They'll just cause you pain.
Here's what I'd do:
int main()
{
int x = 10;
int y = 20;
int r = std::max(x, y);
//pass x, y and r as arguments to functions rather than using globals
}

Related

In a recursive function, how can I jump to a different function call on the stack?

To make my question more clear, I'll give an example. Say I want to implement a recursive function that sums up the range of numbers from [1-10] and [15-20], skipping (10-15). I would want to add up [15-20] and skip the function calls on stack of (10-15), and continue with [1-10]. How can I do this?
int summation(int x, int y) {
if(x == y) return x;
// Catch here and return sum of 15-20 back to calls of 1-10
if(x == 10)
catch(int n)
return n;
int sum = x + summation(x+1,y);
// Skip function calls 10-15
if(x==15) throw sum;
return sum;
}
summation(1,20) // >> 160 or [1-10] = 55, [15,20] = 105
I know how to solve the above example with a different approach, but this example gives an idea of what I'm trying to do.
In order to set the try/catch in the right stack frame, you need to know the edge of the skip interval before you recurse deeper. Given that, it will be better to just never make the useless function calls instead of using an exception to unwind them. For example:
int summation(int const x, int const y)
{
if(x == y) return x;
int const next = (x==10)? 15: (x+1); // skip from 10 to 15 directly
return x + summation(next, y);
}
Avoiding exceptions also gives you the possibility to write the function tail-recursively:
int summation(int const x, int const y, int partial_sum = 0)
{
partial_sum += x;
if(x == y) return partial_sum;
int const next = (x==10)? 15: (x+1); // skip from 10 to 15 directly
return summation(next, y, partial_sum);
}
Keep the function simple.
int summation(int x, int y) {
if(x == y) return x;
return x + summation(x+1,y);
}
and use
summation(1, 10) + summation(15, 20);
on the client side.
You can make the client side a little bit simpler by adding another function that takes care of the numbers to skip.
int summation_with_skip(int x1, int x2, int x3, int x4) {
return summation(x1, x2) + summation(x3, x4);
}
and use
summation_with_skip(1, 10, 15, 20);
If you must have the logic to skip items in the function, you can use
int summation_with_skip(int x1, int x2, int x3, int x4)
{
if ( x1 > x4 )
{
return 0;
}
int s = summation(x1+1, x2, x3, x4)
if ( (x1 > x2) && (x1 < x3) )
{
return s;
}
else
{
return x1 + s;
}
}
I like the idea of passing all arguments to the function.
well, this would be a solution without throw&catch
still an odd solution for the given problem
int summation(int x, int y)
{
if(x > y) return 0;
if ((x >= 10) && (x <= 15))
{
return summation(x+1, y);
}
else
{
return x + summation(x+1, y);
}
}

Using the same parameter in different functions

So I was curious about something. I have two functions, both work the way I want them to, and they are as follows:
//this function returns the absolute value of a number
int abs(int y) {
if (y < 0) {
return -1 * y;
}
return y;
}
//gives a random number, multiplied by x, in the range 1-y
int randomNum(int x, int y) {
srand((int)time(0));
return abs(x * rand() % y) + 1;
}
They both work, so their functionality is not the problem. But if you'll notice, they both use a parameter called "int y."
My question is, despite the fact that these two functions work, is this bad practice that might screw me over in more complex programs? Or does it not matter because the variables are local to their respective functions?
I mean, it's obviously no big deal if I change one of the "int y" parameters to something else, I'm just curious, is all.
I think it is okay for simple programs.
However, you should name a variable using the same care with which you
name a first-born child.
Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
For instance, nobody prefers to read the declaration int foo(int x, int y, int z, int xx, int bb, int cc .....)
Whenever there is a variable inside braces { }, it is local to the scope. Once out of the braces it simply dies.
Now the code that you are asking,
// y is declared in abs and is alive only in the abs
int abs(int y) {
if (y < 0) {
return -1 * y;
}
return y;
}
// the previous y dies here and is inaccessible.
// a new instance of y is created in randomNum and it's valid till the brace ends
int randomNum(int x, int y) {
srand((int)time(0));
return abs(x * rand() % y) + 1;
}
Now a little thing to try out as pointed out by Jawad Le Wywadi
int main()
{
int a = 0;
++a;
{
int a = 1;
a = 42;
cout << a;
}
cout << a;
}
Try it yourself and let us know what do you realize in the comments.

Variables out of scope in main when called by reference by a function in C++

I have made the following code, whose output should generate a point uniformly at random on the unit circle centered at the origin:
#include "unif.h"
#include <iostream>
#include <cmath>
using namespace std;
void point_on_circle(double& x, double& y)
{
double r;
do
{
double x = unif(-1.,1.);
double y = unif(-1.,1.);
double r = x*x + y*y;
}
while (r >=1.0);
x = x / sqrt(r);
y = y / sqrt(r);
}
int main()
{
cout << "Pair of points on the circle found is " << x << " and " << y << endl;
cout << "Let's verify: x^2+y^2=" << x*x+y*y << endl;
return 0;
}
The header "unif.h" is just a file that contains a function void unif(double x, double y), that produces uniformly random numbers in the interval (x,y), and it works perfectly (already tested).
The problem is that when I build the program then it gives me (of course) the error in the main:
"error: 'x' was not declared in this scope"
which is clear since of course x is defined outside the main and never defined in main(). I cannot figure out how to tell the compiler that the values of x and y found by the function point_on_circle should be "carried" inside the main. How could I fix this code?
Thanks in advance
In your main method you did not declare a variable called x nor y. Moreover, you also have scoping issues in your point_on_circle(double& x, double& y) function with the variable r.
Please review C++ scoping.
Because you defined x in the do-while loop, so you cannot use it outside the loop, since those definitions hide the parameters x and y. Define it before the loop:
void point_on_circle(double& x, double& y)
{
double r;
do
{
x = unif(-1.,1.);
y = unif(-1.,1.);
r = x*x + y*y;
}while (r >=1.0);
x = x / sqrt(r);
y = y / sqrt(r);
}
You have a few issues.
1) you need to declare x and y inside main.
2) you never, ever actually call point_on_circle. At all.
3) finally, as others noted, you mask parameters x and y in your do loop.
With all of that said, it looks like you're attempting to find a random point on the unit circle. with that in mind, I would remove the do loop entirely and just do this:
void point_on_circle(double& x, double& y)
{
double r;
x = unif(-1.,1.);
y = unif(-1.,1.);
r = x*x + y*y;
x = x / sqrt(r);
y = y / sqrt(r);
}
It gives the exact same result while avoiding a (potential) endless loop, and certainly avoids useless extra processing.

Returning the actual value of maximum of absolutes of variables

I want to find the maximum of the absolute of two variables, and return the actual value of that variable, rather than the absolute value of that variable.
For example:
int x = 3;
int y = -5;
int z = max(abs(x), abs(y))
Will just set z to 5, whereas I want it to return -5. Is there a C++ function to perform this?
If you're using C++11, with the STL you could use a vector of int, max_element and a lambda Compare
std::vector<int> values = {3, -5};
int largest_abs = *std::max_element(values.begin(), values.end(), [](const int& a, const int& b)
{
return abs(a) < abs(b);
});
This returns the iterator between the start and end of values, whose absolute value is the largest. (this is found through the comparator) The * is then used to convert the iterator (returned by std::max_element) to an int
It's not a commonly used function, but writing your own function is trivial.
int max_abs(int x, int y)
{
if (x == INT_MIN || y == INT_MIN)
return INT_MIN;
return (abs(x) > abs(y)) ? x : y;
}
int z = (max(abs(x), abs(y)) == abs(x)) ? x : y;
This is like an if-condition. Its equivalent to
int z = x;
if(max(abs(x), abs(y)) != abs(z))
z = y;
But much shorter.
There is no function in the STL to fit into your needs directly, so you need to make your own and this one could be one version.
A more handy one can be int z = (abs(y) < abs(x)) ? x : y thought.

Implementing the Tak function using tail recursion

Is it possible to implement the Tak function:
tail recursively in C/C++ in a way so that gcc/g++ can perform tail-recursion optimization?
I'm not sure if the nested recursive function calls will confuse the compiler.
Tail recursion optimization in C++ requires that there only be 1 recursive call (which basically allows it to be converted to a loop) and that recursive call is the last operation in the function:
Example:
unsigned int f( unsigned int a )
{
if ( a == 0 )
{
return a;
}
return f( a - 1 ); // tail recursion
}
Since the Tak function requires 4 recursive calls per "iteration":
int tak(int x, int y, int z)
{
if (x >= y)
{
return z;
}
else
{
return tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y)); // this is why it cannot happen
}
}
As you can see, the last call is recursive, but it has 3 recursive calls inside it. This prevents tail-recursion optimization (and there is no logical method for converting this into a non-recursive-loop - which is required to obtain tail-recursion optimization).
Another way it can be implemented is:
int tak(int x, int y, int z)
{
while (x > y)
{
int oldx = x, oldy = y;
x = tak(x - 1, y, z);
y = tak(y - 1, z, oldx);
if (x <= y)
break;
z = tak(z - 1, oldx, oldy);
}
return z;
}
Which again shows that even in a loop form, it is still recursive, preventing tail-recursion optimization.
Going straight from your math definition, we can just write the function as:
int tak(int x, int y, int z){
if(x>y)
return tak(tak(1-x,y,z), tak(y-1,z,x), tak(z-1,x,y));
else
return z;
}
However you can't do it with tail-recrusion as it cannot be converted into a loop. Since there is more than one recrusion call.