I really do not have any clue about how to solve this task, can someone please help?
Consider the following function definition:
void f(int i, int &j) {
j = i+1;
i = j*2;
j += i;
}
In the following code:
int x = 4, y = 7;
f(x, y);
What are the final values of x and y?
For starters you could just run the code... but otherwise we can try and predict the output.
For starters the function f has two parameters, i and j. The & Infront of the j means that the value of the function input is passed by reference (the value of the variable will be edited).
So now let's evaluate the function with inputs 4, 7. We get:
j = 4+1 = 5
i = 10
j += i, j = 15
Because the variable y was passed by reference, its value will become 15. The variable x was passed by value, so it doesn't get affected and thus stays as 4.
Simply just run the code.Anyway the output will be
x=4(because it is passed as pass by value ->any change will not affect the outside the function f)
y=15(because it is passed as pass by reference->any change will affect the outside the function f)
Related
i have a little problem with this small piece of code;
If i use the ++ operation (x++) it works fine, but if i write "x + 1" it breaks and causes an infinite loop of zeros.
The code:
int x = 0;
while (x <= 20)
{
std::cout << x << std::endl;
x + 1;
}
Any help would be appreciated!
If you want to set a value of a variable you must* use an =.
This : x + 1 is NOT the same as x = x + 1 or x += 1 or x++.
When you add that x plus to your code you are never changing the value of x.
x + 1 simply returns a temporary value of the result. Where as the other three listed about will change the value of x instead of creating a temporary value.
You need to know the differences between different statements related to increment as below.
x++ means x = x + 1; which means copy the value of x into temporary
register, increment the value by 1 and write that register value back
into x.
x + 1 means, copy the value of x into temporary register, increment
the value by 1. You are not assigning the value back to x. So x value
won't be changed.
So in your while loop, x value is not being changed which is reason for infinite loop.
Okay so I was writing some code earlier. This was the line specifically:
EnterNode( FindNode( terrain_X, terrain_Y, travel_dir ), travel_dir );
I noticed after testing my program something weird was happening. The value being received by the outer function was not the value I was reading when I inspected the stack.
I made an example program:
https://ideone.com/wNjJrE
#include <iostream>
int modifyRef(int& A)
{
A = 0;
std::cout << "\nint& A = 0";
return A;
}
void TakeValues(int X, int Y)
{
std::cout << "\nX = " << X;
std::cout << "\nY = " << Y;
}
int main()
{
int Q = 9;
TakeValues(modifyRef(Q), Q);
std::cout << std::endl;
system("pause");
return 0;
}
This is the output I receive:
int& A = 0
X = 0
Y = 9
I would expect Y to also be 0. How is the order of operations defined for parameter binding to function calls?
(My apologies if I am not using the correct terminology.)
The evaluation order of function arguments is unspecified. When you write:
TakeValues(modifyRef(Q), Q);
you are relying upon the fact that modifyRef(Q) to be evaluated before Q. But the evaluation order of function arguments is unspecified - it is not necessarily the case that modifyRef(Q) will be sequenced before Q nor vice versa.
In this case, Q (the second argument) gets evaluated first. So we read 9, and initialize the parameter Y with it. Then we evaluate modifyRef(Q), which zeros out Q and returns it, which leads to initializing X with 0.
Try changing the signature of your functions:
int ModifyRef( int& A );
void TakeValues( int X, int Y );
to the following...
int& ModifyRef( int& A );
void TakeValues( int& X, int& Y );
and see what your output will be in main when you call this line of code:
int q = 9;
TakeValues( ModifyRef(q), q );
then reverse the order of the parameters as such
TakeValues( q, ModifyRef(q) );
and compare the results.
When I did this on my machine Win 7 64bit with VS2015 Community on an Intel Core2 Quad Extreme the results I was given for both situations when using references were the same and the output I am getting is:
I changed the value of A in ModifyRef() from 0 to 7 for testing purposes.
int& A = 7
X = 7
Y = 7
for both situations where either the inner function is the first parameter and the stand alone variable is the second or the inner function is the second parameter with the stand alone variable as the first.
Since I am receiving the same results it appears to me that do to how the compiler creates and handles the stack pointer the ModifyRef() appears to be evaluated first and once that function is finished since q is now being referenced instead of being a stack copy it is being overwritten by whatever value it is being set to within the ModifyRef function.
I also modified your ModifyRef() function slightly so that I can see what its passed in parameter is instead of having a number hard coded into its print out statement.
int& ModifyRef( int& A ) {
A = 7; // Changed Value From 0 To 7 For Testing Purposes
std::cout << "n\int& A = " << A;
return A;
}
However this effect may only apply when using only references.
When I revert back to your original function signatures and I call it in this order:
q = 9;
TakeValues( ModifyRef( q ), q );
As is your original code was presented the output I am getting is:
int& A = 7
X = 7
Y = 9
However when I reverse the parameters to:
q = 9;
TakeValues( q, ModifyRef( q ) );
My output is:
int& A = 7
X = 7
Y = 7
So what I am seeing in these two situations is slightly different.
In the first order of parameters, Y or the second parameter is being set to 9 as q is initialized to 9 and Y within TakeValues() is printing out a stack copy with a value of 9. Then X is being valuated by ModifyRef() where q has a value of 9 but then it is being modified since it is a reference so when TakeValues() sets X from q, q was already changed from 9 to 7 so X is now being set to 7.
In the second order of parameters it appears that ModifyRef() is being called first and changes q from 9 to 7 so TakeValues() is setting Y to 7 and since this function is using a reference q was also changed from 9 to 7, so when the first parameter is taking q to set X q was already changed from 9 to 7.
I do not know if this is compiler dependent but at least on my machine it appears that the call stack for the parameters is happening from farthest right to left. This also makes sense when you think about it due to when functions have default values.
Example:
class foo {
void bar( int a, int b, int c = 3 ) {
std::cout << a << ", " << b << ", " << c << std::endl;
}
};
All default values in a function declaration must be to the far right for you can not have:
class foo {
void bar( int a = 1, int b, int c ) { ... } // Compile Error
};
I hope this helps to clarify what is going on within your code when you begin to call a function within a function as a parameter either if you are using passing by value(stack copy) or by reference.
I have called the function like this,
decimal2binary(1, 4);
By mistake i have re defined the variable m in the definition section of the following function
void decimal2binary(int m, int n) {
int arr[n];
cout<<"m:"<<m<<endl;
for(int i=0;i<n;i++)
{
if(m==0)
{
arr[i]=0;
}
else
{
arr[i]=m%2;
int m=m/2;
cout<<"m:"<<m<<endl;
}
}
when i ran the code i got the output like this,
m:1
m:1184170
m:592085
m:296042
m:148021
why this duplicate variable m producing the strange value, something like 1184170..592085. please tell me the reason.
You defined another variable with the name m in the else block, which shadows the function argument m, its scope begins right after int m, and it's uninitialized in the expression m/2.
in statement int m=m/2; here m on right side contains new m having garbage value. if you replace line int m=m/2; with line int m;//=m/2; you will see that value is actually a garbage value of m that is 2368340 for 1st case you are dividing this value by 2 to get 1184170(m/2) into m(m)
You define another variable with same name m inside else block and you performing operation
int m =m/2;
so compiler this will treat local m not outsider m;
and its give value unpredictable because you not intialize it;
Variable int m inside else block is not initialised. It contains some garbage value. You are dividing the garbage value by 2. Now when we say, it's uninitialised, it means, it can contain any value within the range of int.
I think, what you would like to do instead is::
// Inside else block
int temp = m ; // Store the older m value here
int m = temp/2 ;
Or the easy way::
int temp = m/2 ;
I have this program
//h is our N
static int g=0;
int fun(int h){
if(h<=0){
g++;
return g;
}
return g+fun(h-1)+fun(h-4);
}
Is it possible to speed it up using dynamic programming?
I figured out that this function runs in O(2^n)
I am supposed to reduce the running time by dynamic programming, but do not understand the concept.
Just asking for a nudge in the right direction.
While I can't give an answer to your actual question, I am intrigued by something altogether different, namely the statement
return g+fun(h-1)+fun(n-4);
Obviously, your function has the side effect of changing the global static variable g. I am not 100% sure whether the return statement's expression actually evaluates in a clearly defined fashion, or whether the result might be undefined.
It might be a nice exercise to think about the order in which those function calls are executed, and how this affects g and thereby the function's result.
If we define that summation order in g+fun(h-1)+fun(n-4) is from left to rigth, than this is good defined problem. With that I get values for fun(n), n=1,...,15:
3, 6, 10, 15, 33, 74, 154, 295, 575, 1143, 2269, 4414, 8508, 16396, 31634
Return value of fun(n) is evaluated as sequence of summations with not-descending elements. Each summand is for one larger then previous (return g++;) or same as previous (return g+fun()+fun()). Execution sequence of return statements depend only of fun() input parameter. So, with g set to initial value != 0 we get same summands as with g=0, but every summand is larger for same initial value.
With that, fun(n) with initial g > 0 will return value that is g * number of executed return statements larger than with initial g = 0.
Define A(n) as number of executed return statements while executing fun(n), and G(n) number of executed return statement in if clause (same as number of g++ statement executions). For A and G holds:
A(n) = A(n-1) + A(n-4) + 1
G(n) = G(n-1) + G(n-4)
A(n) = 1 and G(n) = 1, for n <= 0
From these observations it can be seen that for n > 0 holds:
fun(n) = fun(n-1) + G(n-1) * A(n-4) + fun(n-4)
Simple python implementation:
def x( h ):
Rg = { -3:1, -2:1, -1:1, 0:1 }
Ra = { -3:1, -2:1, -1:1, 0:1 }
F = { -3:1, -2:1, -1:1, 0:1 }
for i in xrange( 1, h+1 ):
F[i] = F[i-1] + Rg[i-1]*Ra[i-4] + F[i-4]
print i, F[i]
Rg[i] = Rg[i-1] + Rg[i-4]
Ra[i] = Ra[i-1] + Ra[i-4] + 1
#stakx: for expression g+fun(h-1)+fun(h-4) we can't have evaluation order guaranty, especially not in C.
Yes , It's possible to use DP to speed it up and avoid using CPU stack, but I agree with stakx about the side effect of changing the global static variable g.
It's better to provide a mathematical expression because the recursive function above could give a different result depending on the order & count of calls.
OK. We start from fun (a serialized version where order of evaluation is forced).
int fun(int h){
if(h<=0){
g++;
return g;
}
int tmp1 = g;
int tmp2 = fun(h-1);
int tmp3 = fun(h-4);
return tmp1+tmp2+tmp3;
}
Let's focus on g and forget the current result of the function
Now it is easy to change the function to pass in g as a parameter and to return the new value of g as a result.
int gun(int h, int g0){
if(h<=0){
return g0+1;
}
int tmp1 = g0;
int tmp2 = gun(h-1, g0);
int tmp3 = gun(h-4, tmp2);
return tmp3;
}
What can be simplified into:
int gun(int h, int g0){
if(h<=0){
return g0+1;
}
return gun(h-4, gun(h-1, g0));
}
Now back to fun:
int fun2(int h, int g0){
if(h<=0){
return g0+1;
}
return g0+fun2(h-1, g0)+fun2(h-4, gun(h-1,g0));
}
fun2 does exactly the same thing as the initial fun, but now as we removed the side effect and the function only depends from it's parameter, we can memoize results (store already computed results in an array), which should speed-up the computing.
We can still simplify gun a bit. The g0 parameter is not really necessary, let's set it to 0.
int gun2(int h){
if(h<=0){
return 1;
}
return gun2(h-4) + gun2(h-1);
}
We may even define a fun3 with g0 parameter fixed to 0, henceforth a bit simpler, but it still has to call fun2. I do not see yet how to simplify further but it's probably possible.
int fun3(int h){
if(h<=0){
return 1;
}
return fun3(h-1)+fun2(h-4, gun2(h-1));
}
Can anyone please explain how this works
#define maxMacro(a,b) ( (a) > (b) ) ? (a) : (b)
inline int maxInline(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int i = 1; j = 2, k = 0;
k = maxMacro(i,j++); // now i = 1, j = 4 and k = 3, Why ?? Where is it incremented ?
//reset values
i = 1; j = 2, k = 0;
k = maxInline(i,j++); // now i = 1, j = 3, and k = 2, Why ??
return 0;
}
So, I want to know where exactly is the value of j incremented, while checking
condition or while returning or while calling ?
a. using macro
b. using inline method
UPDATE :
Thanks to all, now I understand this. But just out of curiosity, why would anyone do j++ while calling method, why not increment j after calling method, this way it would be less confusing. I saw this piece of code somewhere so asking it !!
The issue is the preprocessor does just straight text substitution for macros.
maxMacro(i, j++)
becomes
( (i) > (j++) ) ? (i) : (j++)
As you can see, it does two increments when j is greater.
This is exactly why you should prefer inline functions over macros.
k = maxMacro(i,j++);
expands to:
k = ( (i) > (j++) ) ? (i) : (j++)
Because of the sequence point of ?: the behaviour of this is well defined. When i is less than the initial value of j, j is incremented twice and k receives the once incremented value of j.
(If i were greater than the initial value of j, then j would be incremented only once when evaluating (i) > (j++), k would be assigned that value of (i) and the second increment would not be performed.)
In:
k = maxInline(i,j++);
maxInline is called with the values i and j before increment (1 and 2), j is incremented before the function call, and k is assigned the return value of maxInline (2).
Macro results in textual expansion. It happens before the compiler is even considering expressions and operators, and immediately after it had split the input text into individual tokens. Thus, the following line:
k = maxMacro(i,j++);
is exactly equivalent to the following line after macro expansion:
k = ( (i) > (j++) ) ? (i) : (j++);
Obviously, there are two increments here.
On the other hand, inline functions are just functions, and work exactly like non-inline ones for the purpose of the call. And in function calls, expressions in the argument list are evaluated first, and then their values are bound to respective parameter names inside the function body. Thus, the evaluation only happens once.
This is why macro is evil!
A macro is literal text subsitution by the proprocessor before your compiler gets to it so k = maxMacro(i,j++); becomes ( (i) > (j++) ) ? (i) : (j++);. I hope you see the problem here.
In the (inline) function call, the value of a and b is passed by value into the function where the initial value of i and j is passed in, after which j increment.
Calling a macro is not the same as calling a function.
The preprocessor replaces the reference to maxMacro(i,j++)
with literal text that looks like this.
(i) > (j++) ? (i) : (j++)
A post increment operator uses the current value of its target,
and then increments its target. So if i = 1 and j = 2, the following
happens:
(i) > (j++) // 1 is compared to 2, and j is incremented to 3
? (i) : (j++) 2 is greater than 1, so the "b" value is passed
along. j++ is invoked again, so the previous value 3 is returned
from the expression, but as a side effect, j is incremented to 4.
On the other hand, the inline function works just like a non
inline function as far as how the parameter variables are treated.
j++ is referenced once when it is put on the
stack as part of the function call. The function call operates
with a b value of 2 and returns its result(2) while j is incremented
to 3 as a side effect.
Note: your question indicates k=3 after the call to maxInline. I got
k=2 after that call - the result I'd expect.
I hope this clarifies things . . .
K
Check out the CERT C Coding standard:
PRE00-C. Prefer inline or static functions to function-like macros
This is a great resource, lots of information about various little gotchas that one should avoid to make their code clean, stable, and secure :)
Weird. So far nobody has mentioned that the inline function option is type-safe, where the macro isn't!