Persisting variables outside scope of a function - c++

This is part of a debugging assignment that I've been stuck on for days. I'm not as much looking for an answer as much as I'm looking for where to look to find the answer.
I have a function that takes an int as a parameter, and the test uses that function to calculate the sum of the range (0,n]. My problem is that I am new to C++ and have exhausted my knowledge of where to look to solve this. Any help would be greatly appreciated.
Also, it goes without saying that I cannot modify the test file.
Header.h
bool getNum(int n);
Header.cpp:
bool getNum(int n)
{
n = n + 1;
if (n < 10)
{
return true;
}
else
{
return false;
}
}
Test.cpp
int n = 0;
int sum = 0;
while (getNum(n) && n)
{
sum += n;
}
CHECK(sum == 45);
My problem is that I have no way of getting n to be true to pass the logical &&, so the test never visits the inside of the while loop.

You can change the value of an argument to a function, by taking that argument as a reference:
bool getNum(int &n) // note the reference parameter
{
// changes to n are visible to the caller of this function
}
You have to change the declaration of getNum to match as well, of course.
Note that there is no change to the calling code.
Here's a demo of a working example.

Related

C++, different function output when called multiple times

I have the following code:
int countLatticePoints(const double radius, const int dimension) {
static std::vector<int> point {};
static int R = static_cast<int>(std::floor(radius));
static int latticePointCount = 0;
for(int i = -R; i <= R; i++) {
point.push_back(i);
if(point.size() == dimension) {
if(PointIsWithinSphere(point,R)) latticePointCount++;
} else {
countLatticePoints(R, dimension);
}
point.pop_back();
}
return latticePointCount;
}
When I make the call countLatticePoints(2.05, 3) I get the result 13 which is correct. Now I change the parameters and then call countLatticePoints(25.5, 1) I get 51 which is also correct.
Now when I call countLatticePoints(2.05, 3) and countLatticePoints(25.5, 1) right after each other in the main program I get 13 and then 18 (instead of 51), I really don't understand what i'm doing wrong ? When I call each one individually without the other I get the correct result but when I call the functions together one after the other my results change.
You're misusing static.
The second time you call the function, you push additional values into point.
Edit: I hadn't spotted the recursion. that makes things more complex, but static is still the wrong answer.
I'd create a 'state' object, and split the function into two. One that recurses, and takes a reference to the 'state' object, and a second one which initialises the state object and calls the first.
struct RecurState
{
std::vector<int> point;
int latticePointCount
RecurState() : latticePointCount(0)
{
}
}
Outer function:
int countLatticePoints(const double radius, const int dimension)
{
RecurState state;
return countLatticeRecurse(radius, dimension, state)
}
Recursive function
int countLatticeRecurse(const double radius, const int dimension, RecurseState &state)
{
...
}
Local, static variables only get initialized once, on the first function call.

Referring to this function in C++

Is there any general way to refer to the current function being executed? Something that would let me do this for example,
([] (int n) -> int {
if (n <= 1) {
return 1;
}
return n * thisFunc(n - 1);
})()
Mainly, I'm thinking of anonymous functions calling themselves without the use of auxiliary named functions. So avoiding this.
You can use a function pointer, or function object in C++11, but there is no built-in way to refer to a function. For example:
std::function<int (int)> myFun = [] (int i)
{
if i <= 1
{
return 1;
}
return i * myFun(i-1);
}
I would argue that calling a lambda recursively is not how they were meant to be used. Lambdas are essentially meant to provide inline functionality and thus are meant to be fairly simple.
Not to mention that the example you give can very easily be replaced with a loop thus resulting in much more efficient implementation:
int result = 1;
while (i > 1)
{
result = result * i;
i--;
}

Max-heap implementation

Following code for max-heap implementation
#include<iostream>
#include<math.h>
using namespace std;
#define maxn 1000
int x[maxn];
int parent(int i){
return int(i/2);
}
int left(int i){
return 2*i;
}
int right(int i){
return 2*i+1;
}
void max_heap(int x[],int i,int size){
int largest;
int l=left(i);
int r=right(i);
if (l<=size && x[l]>x[i]){
largest=l;
}
else
{
largest=i;
}
if (r<=size && x[r]>x[largest]){
largest=r;
}
if (largest!=i) { int s=x[i];x[i]=x[largest];x[largest]=s;}
max_heap(x,largest,size);
}
int main(){
x[1]=16;
x[2]=4;
x[3]=10;
x[4]=14;
x[5]=7;
x[6]=9;
x[7]=3;
x[8]=2;
x[9]=8;
x[10]=1;
int size=10;
max_heap(x,2,size);
for (int i=1;i<=10;i++)
cout<<x[i]<<" ";
return 0;
}
When I run it, it writes such kind of warning:
1>c:\users\datuashvili\documents\visual studio 2010\projects\heap_property\heap_property\heap_property.cpp(36): warning C4717: 'max_heap' : recursive on all control paths, function will cause runtime stack overflow
Please tell me what is wrong?
The message tells you exactly what's wrong. You haven't implemented any checks to stop the recursion. One smart compiler.
max_heap function doesn't have base case, i.e., a return statement. You are just recursively calling the function but never saying when to break another successive call to the max_heap.
Also, in your example you are just calling the function with out satisfying any condition. Usually recursion is done or not done when a case is satisfied.
please tell me what is wrong?
Another problem that I see is that the size of your array x is 10. But the indices that you are using to set values are 1-10.
Put
max_heap(x,largest,size);
inside last check, like this:
if (largest!=i)
{
int s=x[i];
x[i]=x[largest];
x[largest]=s;
max_heap(x,largest,size);
}
and you're done!
There are many other problems with your code, but to answer your specific question, above change would do!

about return type from a function

Here I have written some code to get the square of a number from a function, but the return statement is not working as desired by me, it is giving me the same number which I have entered, I want to know the reason behind this, please if any one can explain this to me...
#include<iostream>
#include<conio.h>
using namespace std;
int square(int &i);
int main()
{
cout<<"enter the number whose square you want to find";
int a;
cin>>a;
square(a);
cout<<"the square of the number is"<<a;
_getch();
return 0;
}
int square(int &i)
{
return i*i;
}
You're ignoring the returned value. You should store it as:
int value = square(a);
cout<<"the square of the number is "<< value;
Also, as the type is just integral type, passing by reference doesn't give you much advantage. I would suggest to use pass by value for its readability sake:
int square(int i)
{
return i*i;
}
--
Or in case if you're experimeting with reference, and trying to learn it, then in that case I would say that you've to store the result of product in the argument itself, as:
int square(int &i)
{
i = i * i; //this updates i here, and at the call site as well
return i;
}
Or simply do this:
int square(int &i)
{
return i = i*i; //multiply, update, and return - all in one statement!
}
You do not obtain the result.
Your line should be:
a = square(a);
to fetch the result from the function.
The other possibility would be to write in the function
int square(int &i)
{
i = i * i;
return i;
}
The latter will alter the variable you passed to the function which justifies passing a reference.
To make it clear you want to alter the variable do something like:
void square(int &i)
{
i = i * i;
}
You see there is no return involved but it will alter the variables value.
You have a choice:
Modify the parameter you pass in, or
Return a value and assign it to something in the calling scope.
What you are doing in square is the second option. You seem to want the first.
If what you really want is to modify the passed-in value, then what you need is this:
void square(int &i)
{
i = i*i;
}
Either do it this way:
a = Square (a) ; // in main()
...
int Square (int i) // Pass by value -- doesn't change a in main
{
return i * i ;
}
or do it this way:
Square (a) ; // in main()
...
void Square (int& i) // Pass by reference -- changes a in main
{
i = i * i ; // No need for a return value
}
Make sure you understand the difference before you program anything else!
Judging by your comments on the answers, you've misunderstood what passing by reference does OR you've misunderstood return.
I'm assuming you're thinking that the variable i will be updated in your program. However, this is not the case. If you did something like...
i = i*i;
then yes, you would be correct. However, you did not assign any value to i, you simply multiplied it by itself and returned the result. Also, if you truly wanted to make this work based on a reference, there would be no need to return anything, as the variable would be updated via the reference.

Returning recursive ternary freaks out

assume this following function:
int binaryTree::findHeight(node *n) {
if (n == NULL) {
return 0;
} else {
return 1 + max(findHeight(n->left), findHeight(n->right));
}
}
Pretty standard recursive treeHeight function for a given binary search tree binaryTree. Now, I was helping a friend (he's taking an algorithms course), and I ran into some weird issue with this function that I couldn't 100% explain to him.
With max being defined as max(a,b) ((a)>(b)?(a):(b)) (which happens to be the max definition in windef.h), the recursive function freaks out (it runs something like n^n times where n is the tree height). This obviously makes checking the height of a tree with 3000 elements take very, very long.
However, if max is defined via templating, like std does it, everything is okay. So using std::max fixed his problem. I just want to know why.
Also, why does the countLeaves function work fine, using the same programmatic recursion?
int binaryTree::countLeaves(node *n) {
if (n == NULL) {
return 0;
} else if (n->left == NULL && n->right == NULL) {
return 1;
} else {
return countLeaves(n->left) + countLeaves(n->right);
}
}
Is it because in returning the ternary function, the values a => countLeaves(n->left) and b => countLeaves(n->right) were recursively double called simply because they were the resultants?
Thank you!
The question was answered below
I just wanted to link some literature on the subject for future reference:
http://www.boostpro.com/tmpbook/preprocessor.html
http://msdn.microsoft.com/en-us/library/z3f89ch8.aspx
The main difference between the two implementations being:
#define max(i, j) (((i) > (j)) ? (i) : (j))
vs
template<class T> T max (T i, T j) { return ((i > j) ? i : j) }
Thank you all!
Macros are expanded by the preprocessor, before the compiler gets to see the code. This means that, for example, macro parameters might be evaluated more than once.
With your macro, you're going to end up with something akin to:
int binaryTree::findHeight(node *n) {
if (n == NULL) {
return 0;
} else {
return 1 + (findHeight(n->left) > findHeight(n->right)) ? // call once...
findHeight(n->left) : findHeight(n->right); // and ouch
}
}
As you can see, it's going to evaluate both functions, then one more an additional time. This is why macros can be evil.
You can disable the macro by defining NOMINMAX prior to including the Windows headers. Then use the function in <algorithm> instead.
If he must use the macro, he'll have to store the calculations in a variable:
int binaryTree::findHeight(node *n) {
if (n == NULL) {
return 0;
} else {
const int leftHeight = findHeight(n->left);
const int rightHeight = findHeight(n->right);
return 1 + max(leftHeight, rightHeight);
}
}
With a function, each call will be evaluated prior to calling the function. That is, it's somewhat like the previous code block. It evaluates the function's arguments, gets the results, then passes those into the std::max function. There are no repeated evaluations.
That max macro evaluates the arguments twice - and since your argument is a recursive function call, that's probably the source of the perf problem.
It's because of the definition of max. You're making 3 calls to findHeight() instead of 2.
a better option would be to declare a function with following signature:
int max(int, int)
This will prevent the recursive expansion of macro.