Passing new value to a pointer via a recursive function in c++ - c++

How I can change the value of p to 1 passing it as an argument to a recursive function.
This is my code:
class Solution
{
void g(int n,int k,int *p){
if(k==0) return;
if(k%n==0) g(n,k-1,1);
cout<<p<< endl;
g(n,k-1,p+1);
}
public:
int josephus(int n, int k)
{ int p=1;
g(n,k,&p);
return p;
}
};
I get this errors:
prog.cpp: In member function void Solution::g(int, int, int*):
prog.cpp:14:21: error: invalid conversion from int to int* [-fpermissive]
if(k%n==0) g(n,k-1,1);
^
prog.cpp:12:9: note: initializing argument 3 of void Solution::g(int, int, int*)
void g(int n,int k,int *p){

The error says you cannot pass an int as a parameter to a function when it expects an int *.
There is also a logical bug in your code:
g(n,k-1,p+1);
This recursive call increments the pointer value, which makes it point past the passed in object, since the function was called like this:
{ int p=1;
g(n,k,&p);
Since your function takes an int *, you need to dereference the pointer to manipulate the referenced object. So, you probably intend to increment *p and then make the recursive call:
++*p;
g(n,k-1,p);
To address the compilation error, you probably intended to assign 1 to the int object and make the recursive call.
if(k%n==0) {
*p = 1;
g(n,k-1,p);
}

Related

Calling a void function to another void function BEFORE calling to the main function

Please bear with me as I am brand new to coding.
I am trying to figure out how to call a void function to another void function. Here is what I came up with:
#include <iostream>
using namespace std;
void test(int x,int n, double &test1);
void ref(int a,int b, double &ref1);
int main()
{
int x,n;
double test1;
cout<<"Enter x and n: ";
cin>>x>>n;
test(x,n,test1);
cout<<"Your value is "<<test1;
return 0;
}
void test(int x,int n, double &test1)
{
int a, b,ref1;
ref(a,b,ref1);
test1=x+n + ref1;
}
void ref(int a,int b, double &ref1)
{
ref1=a+b;
}
But I am getting an error:
main.cpp: In function 'void test(int, int, double&)':
main.cpp:32:17: error: cannot bind non-const lvalue reference of type 'double&' to an rvalue of type 'double'
32 | ref(a,b,ref1);
| ^~~~
main.cpp:14:31: note: initializing argument 3 of 'void ref(int, int, double&)'
14 | void ref(int a,int b, double &ref1);
| ~~~~~~~~^~~~
I am trying to use the void ref function inside the void test function and print out under the main function. Can I do this?
Your ref() function takes a non-const reference to a double in its 3rd parameter. However, your test() function is initializing that parameter with an int variable. So, the compiler has to perform an implicit conversion from int to a temporary double, but then fails because a non-const reference can't bind to a temporary object, hence the compiler error.
You need to change test() to pass a double variable to ref() (just like main() is doing when calling test()), eg:
void test(int x,int n, double &test1)
{
int a, b;
double ref1; // <-- here
ref(a,b,ref1);
test1=x+n + ref1;
}
Also note that test() is not initializing its a or b variables with any values, but is still passing them to ref(), which will then sum their values together and assign the result to ref1. That summation will have undefined behavior, and the resulting value of ref1 will be indeterminate. You need to fix that, too.

Modifying Arguments passed by reference in the function call in a recursive function

Here is a simple code that takes counter as a reference passed argument and then prints it :
#include <iostream>
using namespace std;
void Fun(int &counter, int n)
{
if(n==0)
return;
Fun(counter+1,n--);
}
int main() {
int counter = 0;
int n = 5;
Fun(counter,n);
cout<<counter<<endl;
return 0;
}
I'm getting this error.
prog.cpp: In function ‘void Fun(int&, int)’:
prog.cpp:7:16: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
Fun(counter+1,n);
^
prog.cpp:3:6: note: initializing argument 1 of ‘void Fun(int&, int)’
void Fun(int &counter, int n)
^
Can somebody please help, why this error?
In Fun(counter+1,n--); you are not passing counter to the function. You create a temporary from counter+1 that you pass to the function. To extend the life of a temporary taken by reference, it needs to be const, so void Fun(const int &counter, int n) would be compileable.
Counter will however be 0 when the function ends since you never change counter and the function will never return since you do not decrease the n you pass to the function. You call the function with n and then decrease n.
An alternative:
void Fun(int &counter, int n)
{
if(n==0)
return;
Fun(counter += 1, n - 1); // or Fun(++counter, --n);
}
Both counter += 1 and ++counter return a reference to counter which is why this works.
counter++ and n-- will however not work, because the post-increment operators return temporaries too, like in:
int old = n;
n = n - 1;
return old;

can't pass by reference a pointer returned from a function

why I need intermediate variable to pass my return pointer by reference instead of just using the function that returns that pointer ?
This doesn't compile
int main ()
{
testfunc(getpointer());
return 0;
}
error: C2664: 'void testfunc(int *&)': cannot convert argument 1 from 'int *' to 'int *&'
and this compiles
int main ()
{
int *i = getpointer();
testfunc(i);
return 0;
}
my two functions
void testfunc(int *& i) // I have to use this interface
{
cout << i[0] <<endl;
}
int* getpointer()
{
int * arr1 = new int[1];
arr1[0]=10;
return arr1;
}
The C++ language prohibits binding a non-const reference to a temporary. In this case, the simple fix is to make testfunc take a const reference to an int*.

Assignment function to function

Please explain me why the code below doesn't work
#include <stdio.h>
int foo() { return 1; }
int bar() { return 2; }
void ass()
{
foo=bar;
}
int main()
{
ass()
}
The following error
test.cpp: In function ‘void ass()’:
test.cpp:8:8: error: assignment of function ‘int foo()’
test.cpp:8:8: error: cannot convert ‘int()’ to ‘int()’ in assignment
caused.
You must use a function pointer. You cannot assign to the function itself.
int(*baz)() = &foo;
baz();
try this:
typedef int (*int_funcptr_void)(void);
then, you can simply:
int foo() { return 1; }
int bar() { return 2; }
int_funcptr_void func;
void ass()
{
func = (int_funcptr_void)foo;
}
int main()
{
ass(); //you also forgot a semicolon here, but nice naming
//then, we can call it:
printf("%d\n", func());
}
and get this:
hydrogen:tmp phyrrus9$ ./a.out
1
Hope that helps.
You can not assign function to function, as you can not assign int to int. Think naturally, you assign an int variable to another int variable, which means you are assigning rvalue of the second variable to the lvalue(address) of the first one. Same rule for function, you can assign a function object to another function object. The difference is, function is code, not data, but it has an address ( the starting point). So assigning function to one another generally means assigning the address of the function to a variable which can hold an address, i.e. a function pointer.
void f(){}
typedef void(*pF)(); //typedef for easy use
pf foo; //create a function pointer object
foo = &f; //assign it the address of the function

C++ Pointer to Pointer

I want to have a pointer to a constant, and pass its address to a function that will increment it.
int f1(const int **ptr) {
int n = **ptr; //use pointer
(*ptr)++; //increment pointer
return n;
}
void foo(const int *data) {
const int *p = data;
const int n = f1(&p); //error: invalid conversion from ‘const int**’ to ‘int**’
//error: initializing argument 1 of ‘int LevelLoader::readWord(byte**)’
}
How do I declare the pointers?
Try
int f1(const int *& ptr) {
int n = *ptr;
++ptr;
return n;
}
void foo(const int *data) {
const int *p = data;
const int n = f1(p);
}
instead.
The error message indicates that LevelLoader::readWord doesn't take a const byte**.
This:
const int *data;
is a pointer to a constant integer. That means that you are not allowed to change the data pointed to by data. You can read and copy the data, but you can't do:
(*data) = 5;
That's illegal in C++ because it was declared const int *.
If you take the address of a const int *, you get a const int **, which is a pointer to a pointer to a constant integer. So you still cannot change the integer. Any attempt to do so will cause the compiler to complain.
If you want to be able to change the integer, then foo and f1 should not take const int * values. They should take int * values.
I don't want to modify the constant. I want to modify the pointer to it (p in foo())
So, you're given a pointer. And you want to increment the pointer. So just do so:
void foo(const int *data) {
const int *p = data;
data++;
}
You have incremented the pointer. This will not affect the caller to foo, as the pointer itself is copied by value.
Check again, this code is correct. It shouldn't generate the errors you claim.
EDIT: You fixed the void problem so answer amended accordingly.