question on c++ recursion and local variables - c++

suppose I have this recursion:
void doSomething(double j)
{
double x;
double y;
x = j -1;
y = j -2 ;
doSomething(x+y);
x = j + 31;
y = j + 12 ;
}
I know that this recursion executes infinitely, but just ignore that
My question is with regards to variables x and y's scope in the recursion tree...will x and y's scope be valid only for the function in that specific stage in the recursion tree? or when I call doSomething() again, when the child doSomething() in the recursion tree redeclares x and y, will it reset the parents' x and y variables as well or is it creating an entirely new x and y variables that is valid for that stage in the recursion tree only?

will x and y's scope be valid only for the function in that specific stage in the recursion tree?
Yes.
when I call doSomething() again, and the child doSomething() in the recursion tree, redeclares x and y, will it reset the parents' x and y variables as well
No.
is it creating an entirely new x and y variables that is valid for that stage in the recursion tree only?
Yes.
Edit 1:
This example should be helpful.
#include <iostream>
void foo( int temp )
{
int num = temp;
if( temp == 0)
return;
foo(temp-1) ;
std::cout << &num << "\t" << num << "\n" ;
}
int main()
{
foo(5) ;
return 0;
}
Output:
0xbfa4e2d0 1
0xbfa4e300 2
0xbfa4e330 3
0xbfa4e360 4
0xbfa4e390 5
Notice the address of num being different and each call has it's own value of num.
Ideone

Every call gets its own copy of the variables. Assigning to the copy in one function call has no effect on the versions in any other function call. That's why the recursion has to communicate between "stages" by passing arguments and returning a value.

yes, x and y are stack variables, and thus are independent between each call. A fresh, stack-based x and y will be created for each call to doSomething.
If you wanted them to be the same variable in each call, you should declare them static

Every time a function is invoked, there are new local variables x and y created, that are unrelated to any other invocation of the function. This is what makes local variables different from global variables.

You are passing x + y by value into the function doSomething(). This means that on the function stack doSomething() will have access to one local variable j with its value set from the function below it on the stack to whatever x + y evaluates to (i.e the function that called them). Since this variable is completely separate from that in the parent function, modifying its value will have no affect on variables below it on the stack.
If, however, you want j to be the exact same variable as in the parent function then you can do something like:
void doSomething( double& j )
{
double x = j - 1;
double y = j - 2;
double willChange = x + y;
doSomething( willChange );
x = j + 31;
y = j + 12 ;
}
Notice the & after the double, this tells the compiler that the function accepts the value of a double by its address, which is called appropriately enough passing by address. Here in the child of every doSomething() j is an alias for the variable willChange in the function below it on the stack.
If you want to modify x and y specifically then maybe do something like
void doSomething( double& x, double& y )
{
double j = x + y
double x = j - 1;
double y = j - 2;
doSomething( x, y );
x = j + 31;
y = j + 12 ;
}

Related

In C++, can you define a variable in terms of other variables that have already been defined? [duplicate]

This question already has answers here:
C++ initialize variable based on condition [closed]
(4 answers)
How to let a variable be dependent on other variables inside a class?
(6 answers)
How to initialize a static variable with another static variable?
(1 answer)
Closed 2 years ago.
For example, can I define a variable "z" in terms of variables I already defined called "x" and "y" (yes I know these are horrible naming conventions but it's an example). Like this:
int x = 0;
int y = 0;
int z = x * y;
Can you do something like that and just go on with your program or will you get error messages?
You may be interested in lambdas:
int x = 0;
int y = 0;
auto z = [&x, &y](){ return x * y; };
This code does exactly what you are requesting: calling the z() function would always give you the result that is the multiplication of the x and y variables:
int v = z();
assert(v == x * y);
Even if x or y change you would always get their multiplication:
int x = 0;
int y = 0;
auto z = [&x, &y](){ return x * y; };
assert(z() == 0);
x = 1;
y = 2;
assert(z() == 2);
can I define a variable "z" in terms of variables I already defined called "x" and "y"
int z = x * y;
Totally possible to define z that way. Most if not all languages should allow that basic definition. Except, perhaps you have to be careful with overflow issue. If later in your program you may assign x and y to very large value, then z could overflow. It may be better to do:
long long z = x * y;
Yes, you can.
Also,
int x = 1, y = x;
int z=x*y;
y = x; is possible.

the scope and priority of variable in c++

Could anybody explains to me why the result is 2, which x is using and why.
auto x = 0;
int f(int i){
auto x = 1;
{
static auto x = 0;
x += i;
}
return x;
}
int main() {
cout << f(1) + f(2) <<endl;// result 2
return 0;
}
The inner x shadows the outer one, but the mutations only apply to the inner most scope
int f(int i){
auto x = 1; // consider this "x1"
{
static auto x = 0; // this is "x2"
x += i; // mutates "x2" but not "x1"
}
return x; // return "x1" which is still 1
}
Therefore
f(1) + f(2) // 1 + 1 == 2
This is all about variable shadowing.
The innermost x in function f is shadowing the automatic x in that function. So that function is equivalent to
int f(int){
auto x = 1;
return x;
}
Note furthermore that the x in my abridged version shadows the one at global scope.
The function f is further abbreviated to
int f(int){
return 1;
}
and now the program output should be obvious.
In fact this function
int f(int i){
auto x = 1;
{
static auto x = 0;
x += i;
}
return x;
}
can be rewritten like
int f(int i){
auto x = 1;
return x;
}
because the static variable x declared in this block scope
{
static auto x = 0;
x += i;
}
is not used outside the block and does not influence on the returned value of the function. The only side effect of this code block is potential overflowing of the static signed integer variable x that has undefined behavior.
So the both function calls f(1) and f(2) returns 1 and as a result the expression f(1) + f(2) yields 2.
In the program there are declared three variables x. The first one in the global name space
auto x = 0;
The second one in the outer-most block of the function f that hides the declaration of the variable x in the global name space.
auto x = 1;
And the third one is declared in an inner block of the function f
{
static auto x = 0;
x += i;
}
that is not visible outside this inner block.

Returning 0 after functions are called without "return(0);"

I'm having a small issue in trying to figure out why a zero is printed out at the end of my while loop.
#include <iostream>
using namespace std;
int x;
int CountDown(int x);
int CountUp(int x);
int main()
{
int toCountUp = CountUp(x);
cout << x << endl;
}
int CountUp(int x)
{
x = 0;
while(x <= 10)
{
cout << x << endl;
x++;
}
}
My best response would be that it is in the condition of the while loop. Or a return status from the function/main being fulfilled, but I don't have a return on there, and I know a function doesn't require a return statement but in this while loop I want there to be a integer returned, do I need to make the function void so there will be no return? But what about the parameter x that I need for the while loop?
code output:
0
1
2
3
4
5
6
7
8
9
10
0 < ---- this is the number I do not want.
Thinking about it, it has to be a value returned at the end of the function, any ideas?
This outputs the values 0 through 10:
int toCountUp = CountUp(x);
Then, this outputs 0:
cout << x << endl;
The method does not change the value that is passed to it, it uses its own local copy of that variable.
—It's mainly because you are printing cout << x << endl; twice. Once in the int CountUp(int x) function itself, but again in the main function.
—It could've printed any given value of x at this point, but since you're setting x=0 outside of the While{} loop in the int CountUp(int x) function, it's printing 0 at the end after the function call is executed.
*int CountUp(int x)
{
x = 0;
while(x <= 10)
{
cout << x << endl;
x++;
}
}*
—Is there a reason why you are setting x=0 within the function? since you're passing x as a parameter in the function call, and adding 1 to it in the While{} loop until it's x<= 10? Asking because you're not returning x back to the main() function.
—In case you wanted to use the end value of x to countdown using CountDown(x), you may like to reset x=0 in the main() function after calling the block—
*int CountUp(int x)
{
x = 0;
while(x <= 10)
{
cout << x << endl;
x++;
}
}*
At last 0 is printed in main() function because x is declared global.
If you want latest x after loop got over to be printed in main() then you should reference variable and don't declare it globally.
int CountUp(int &); /* function prototype*/
Since passed variable(actual argument) and reference variable having the same memory So modification will affects in calling function.
int CountUp(int &x) { /* catch with reference variable so that modification affects in calling function also */
x = 0;
while(x <= 10)
{
cout << x << endl;
x++;
}
}
First read Shadowing variables and What's the difference between passing by reference vs. passing by value?
The int x parameter of CountUp shadows the global variable int x so inside CountUp, the only x is the parameter.
int CountUp(int x)
int x defines x as passed by value, so it is a copy of the x used to call CountUp in main. This different x is counted up to 10 and then discarded.
the global int x has static storage duration and is default initialized to zero for you. Do not try this trick with a variable with Automatic duration because unless it has a constructor that does something useful, the contents are uninitialized and their value is undefined.
Sideshow issue:
A function that has a non-void return type MUST return a value on ALL paths. If it does not, you have Undefined Behaviour and the compiler can generate hopelessly invalid code that can get you even if the bad path is not taken. Don't smurf with Undefined Behaviour, as it might crash the program or do something hilariously wrong, but it might also look like it works until it suddenly doesn't at a really bad time.
Solutions:
void CountUp(int & x)
{
x = 0;
while(x <= 10)
{
cout << x << endl;
x++;
}
}
Passes x by reference allowing global x and the local x to be one and the same and returns nothing.
Usage would be
CountUp(x);
Not so useful in the asker's case because it doesn't leave a toCountUp.
int CountUp(int x)
{
x = 0;
while(x <= 10)
{
cout << x << endl;
x++;
}
return x;
}
Makes a copy if the provided x, operates on the copy, and then returns x. Usage would be
int toCountUp = CountUp(x);
And will set toCountUp to 10 higher than the global x.

[C++]Basic Array code that redefines y value. It's working but cannot explain why

I saw some codes on the web and trying to figure out how this works. I tried to leave comments on each lines but I cannot understand why y[0] changes to 5555. I'm guessing y[0] might change to numbers[0], but why?
x value is still 1. Well.. is this because y[0] = 1; has no int data type?
#include
using namespace std;
void m(int, int []);
/*this code explains a variable m that m consists of two parts, int and int array*/
int main()
{
int x = 1; /* x value is declared to 1*/
int y[10]; /*Array y[10] is declared but value is not given*/
y[0] = 1; /*Array y's first value is declared to 1 but data type is not given*/
m(x, y); /*This invokes m with x and y*/
cout << "x is " << x << endl;
cout << "y[0] is " << y[0] << endl;
return 0;
}
void m(int number, int numbers[]) /*variable names in m are given, number and numbers.*/
{
number = 1001; /*number has int 1001 value*/
numbers[0] = 5555; /*This overrides y to numbers[], so y[0] =1 changes to numbers[0] = 5555.*/
}
/*This program displays
* x is 1
* y[0] is 5005
* y[0] value has changed but x has not.
* */
I'm guessing y[0] might change to numbers[0], but why? x value is still 1.
Don't guess please. Your code works as commonly expected.
number = 1001; doesn't influence x in any way.
number is a local copy (as passed by value).
numbers decays to a pointer to the 1st element of the original array, thus it is changed outside the functions scope.
Well.. is this because y[0] = 1; has no int data type?
No, as explained above. y[0] actually is of type int.
int numbers[] is almost equivalent to int* numbers in this situation. You are not passing the vector as an immutable object but as a reference. So both numbers ( the local variable from the function ) and y ( the local variable from main ) will be pointing to the same memory address.

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.