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.
Related
Hi I want to know how can I assign an output as an input to another function. Below there is an example.
I want to fully explain my assignment:
I have a string with operands and numbers.
I splited it into 3 numbers being "num1" "num2" and "ans" with a function.
Now I need another function to sum "num1" and "num2" and another function to check if the real answer and the user answer are equal.
For this I need to input num1 and num2 into another function and I couldn't manage how to do that.
int step1()
{
int x = 12;
int new_x = 2*12;
return new_x;
}
int step2()
{
sqr_x = new_x * new_x
return sqr_x;
}
If you pass an argument you can do this. You could also declare the new_x variable at the top of your program, but to keep it the way you did this kinda, call the function
int step1() {
int x = 12;
int new_x = 2*x;
return new_x;
}
int step2() {
int sqr_x = step1()*step1()
return sqr_x;
}
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.
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
}
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.
I'm having a very odd problem with my program and am hoping you can help. I have a really basic pair of functions. One calls the other and requires a return int.
For reasons completely unknown reasons the first function fails to print out match even though the conditions are true if the return value to a variable is assigned to a variable ie:
Function 1:
int function1(int posX, int posY){
int x=1;
int y=1;
if (posX == X && posY == Y){
printf("Match");
return 1;
}
}
Function 2:
int i = function1(1, 1);
Does work:
function1(1,1);
So to clarify, I'm saying that its working if I get the message "Match".
(posX == X && posY == Y)
C/C++ is case-sensitive. What do "X" and "Y" stand for?
Maybe try changing them to lowercase?
Also, always try to return a value even if there is NOT a match (the function function1 is supposed to be returning an int value, right?)
Code : (corrected)
int function1(int posX, int posY){
int x=1;
int y=1;
if ((posX == x) && (posY == y)){
printf("Match");
return 1;
}
return 0;
}