C++ Calling a vector inside a function through a function pointer - c++

In a program I'm working on, I've declared a vector in main. I have two functions that use the vector: an int function, and a standard void 'print' function. I'm attempting to use a function pointer (pointing to the int function) in the void function, but I get the error that the vector has not been declared, even though it's in main. I've tried declaring the vector outside of main, and the function worked fine, but I'm hesitant on keeping it outside of main. I was wondering if there was some way to use the vector in the void function when it was declared in main. Here's some example code for what I'm asking:
// Example program
#include <iostream>
#include <vector>
using namespace std;
int returnSquare(vector<int>& numbers);
void print(int (*squarePtr)(vector<int>&));
int (*squarePtr)(vector<int>&);
int main()
{
vector<int> v(1);
squarePtr = &returnSquare;
for(int i = 0; i < v.size(); i++)
{
v.at(i) = i * 25;
cout << v.at(i) << " ";
}
print(squarePtr);
return 0;
}
int returnSquare(vector<int>& numbers)
{
int product = 0;
for(int i = 0; i < numbers.size(); i++)
{
product = numbers.at(i) * numbers.at(i);
}
return product;
}
void print(int (*squarePtr)(vector<int>&))
{
int answer = (*squarePtr)(v);
cout << answer << endl;
}

In your function print you have just one parameter. To call your squaring function you need to pass the vector to square to it, something like:
void print(int (*squarePtr)(vector<int>&), vector<int> &v)
{
int answer = (*squarePtr)(v);
cout << answer << endl;
}
Without that the variable v is not visible inside the function. The call should look like:
print(squarePtr, v);
Less important. You use the squarePtr name in your global definitions twice. This does not bring clarity to your code. You better write:
void print(int (*workerFuncPtr)(vector<int>&));
int (*squarePtr)(vector<int>&);

void print (int (*squarePtr)(vector<int>&))
This parameter only accepts a pointer to your square function, that's it. It doesn't hold a pointer or a reference to your v variable. Your print function has no idea what v is, unless you pass v as an argument, or make v a global variable (which is what you did moving it out of main).
Do this:
// Modify your print definition to accept a reference to your vector `v`
void print(int (*squarePtr)(vector<int>&), vector<int>& v);
// Add `v` as the second argument to your print call
print(squarePtr, v);
// Modify the definition of your print function to accept a reference to your vector `v`
void print(int (*squarePtr)(vector<int>&), vector<int>& v)
{
...
}

Related

How can i increase value of x in function?

C++ Program: - I know that in the function definition, x is not passed so it would get error message but i want to increase in function, so what can i do?
#include <iostream>
using namespace std;
fun(int& p)
{
cout << p;
x++;
}
int main()
{
int x = 15;
int c = 1;
fun(c);
cout << x;
return 0;
}
The value of variable x is undefined for fun() and you should go through a book for basics.
The only method if you just want to manipulate the same variables, is using reference variables as parameters and then you can directly modify its original values.
Refined version of your program for accessing and manipulating the data with functions:
#include <iostream>
void fun(int &, int &);
int main(void) {
int x = 15;
int c = 1;
fun(c, x); // c is printed "1" and x increments with 1
std::cout << x << std::endl; // new value of x prints
return 0;
}
void fun(int & p, int & x) {
std::cout << p << std::endl;
x++; // increments original x
}
Note: Alternatively, you can declare your required variable in global scope by putting them outside of all the functions and underneath the header declaration, so that they'll be visible to the entire program but remember that you must need to use reference for changing the variable values for the whole program.
You can either set x as a global variable or you can also pass it to your function.
fun(int &p, int &x) and then call it from main.

C++ a non-void function as an argument to a function

When you have a function (pointer) as an argument to another function in c++ does the function (that is in the argument) have to be a void function?
eg. Can you have a function like
void run(int (*method)(int, double, vector), int dimension)
here the function method returns an int not a void. I am also having difficulty with the vector. Should it be a &vector?
When I then call it in my main I have it as:
run(jacobi_method(Vnew, V, vec), dimension);
but it does not want to work.
Thanks
run(jacobi_method(Vnew, V, vec), dimension);
should be
run(jacobi_method, dimension);
When you have a function (pointer) as an argument to another function in c++ does the function (that is in the argument) have to be a void function?
No, it can be any type of function; as long as the code using it calls it correctly.
Should it be a &vector?
You mean, should it be a reference? Only you can decide. Is the function supposed to modify it? Then it should be a reference. If not, it's probably more efficient to pass by const reference rather than value.
run(jacobi_method(Vnew, V, vec), dimension);
That's trying to pass the result of calling the function, not a pointer to the function. You want
run(jacobi_method, dimension);
eg. Can you have a function like
void run(int (*method)(int, double, vector), int dimension)
Yes, that is ok, just remember that vector is a template, so it should be
void run(int (*method)(int, double, vector<some_type>), int dimension)
As for your calling,
run(jacobi_method(Vnew, V, vec), dimension);
You can't pass the arguments to the function pointer. You should call it as
run(jacobi_method, dimension);
Here is a complete working code:
#include <vector>
#include <iostream>
using namespace std;
int jacobi_method(int a, double b, vector<int> c)
{
cout << "jacobi_method: " << a << " " << b << endl;
for(int i=0; i<c.size(); i++)
cout << c[i] << endl;
return 8;
}
void run(int (*method)(int, double, vector<int>), int dimension)
{
int result;
vector<int> a;
a.push_back(1337);
a.push_back(1338);
result = method(dimension,2.1,a);
cout << "Result = " << result << endl;
}
int main()
{
run(jacobi_method, 2);
return 0;
}
Yes, it is possible to pass a non void return function as parameter.
A full sample:
#include <iostream>
using namespace std;
int sum(int a, int b) {
return a + b;
}
int substract(int a, int b) {
return a - b;
}
void run(int (*f)(int a, int b), int a, int b) {
int res = f(a, b);
cout << "Result: " << res << endl;
}
int main()
{
run(sum, 10, 5);
run(substract, 10, 5);
return 0;
}
Such definition is legal
void run(int (*method)(int, double, vector), int dimension)
But,
run(jacobi_method(Vnew, V, vec), dimension);
is equivalent to
int r = jacobi_method(Vnew, V, vec);
run(r, dimension);
so you should call:
run(jacobi_method, dimension);
About the vector question, passed by reference (Vector & vec or const Vector & vec for read only) is recommended, because passed by value (Vector vec) actually make a copy, which will lead to low efficient in most conditions.
So just pass vector by value only when you tend to make a copy. The same rule can apply to any other parameter passing, such as other containers and user defined objects
Yes you can have a function that accepts a pointer to another function with a specific signature:
void run(int (*method)(int, double, std::vector<int>), int dimension)
{
std::vector<int> vec;
// put some values in the vector here
int result = method(1, 2.5, vec); // this will call the function
}
And the invocation:
int my_method(int x, double d, std::vector<int> v)
{
int result;
// function code here
return result;
}
run(my_method, dimension);
But, if you want to pass a function with specific parameters to 'run' and also have the ability to change these original parameters inside 'run', then you need to pass in a functor that wraps the method and its arguments, so your 'run' will get the result based on the original parameters, and/or whatever changes 'run' made itself.
Let me know if this is what you really want.
The other posters have pointed out the mistake in your syntax, I'll answer the other question that you have: How do you specify the parameters for the function in question.
If you want to specify them at the moment that you construct the function pointer (as in your original post), your function's type should actually be int (*method)(). You don't expect anyone to be able to change the function parametrs through the pointer, and this is why your pointer is actually to a function accepting no parameters.
If you want to re-use some function that you already have, and assign some parameters, and pass the function as a pointer, with the parameters that you assigned, what you need is std::bind. Some documentation on it: http://en.cppreference.com/w/cpp/utility/functional/bind
In essence, what this allows you to do, is to take one function pointer, pass some parameters to it, and get a new function pointer, which will call your original function, but with the parameters that you specified.

Is this the correct method to pass an array to a function?

This is the working program to pass an array in a function, but I am not able to understand that in the print function only the base address of the array is passed but still I am able to access the array with subscript a[i]. I know the correct method will be *(a+i) but why does it work with the subscript too?
#include <iostream>
#include <conio.h>
void print(int *a);
using namespace std;
int main()
{
int arr[3]={1,2,3};
print(arr);
getch();
return 0;
}
void print(int *a)
{
for(int i=0;i<3;i++)
{
cout<<a[i];//how we are able to access array with subscipt a[i]
}
}
Since you are passing a pointer (pointing to a specific memory address) you can treat it as usual even inside the function. Pointers and arrays are very closely related and the use is just fine.
a[0] and *a are the same thing, so are a[1] and *(a+1) etc.
"A pointer is equivalent to the address of the first element that it points to" - from http://www.cplusplus.com/doc/tutorial/pointers/
The array can be passed like that, but the other way is to put name of the array followed by empty []:
#include <iostream>
#include <conio.h>
void print(int *a);
using namespace std;
int main()
{
int arr[3]={1,2,3};
print(arr);
getch();
return 0;
}
void print(int a[])
{
for(int i=0;i<3;i++)
{
cout<<a[i];//how we are able to access array with subscipt a[i]
}
}
both methods pass the address of the first number in array, so both methods work.
//how we are able to access array with subscipt a[i]
a[i] is the same thing as *(a + i).
As it is now, your print will only work for arrays of the exact size 3, so:
If the array happens to have more than 3 elements, some elements will not be printed.
If it happens to have less than 3, you'll access whatever is in memory behind the array, which is undefined behavior (translation: very bad!).
The size of the array gets "forgotten" when you pass the array to a function, so either explicitly pass the size to make the function reusable for arrays of all sizes (reusability is the point of having functions after all!)...
void print(int const* a, size_t a_size) {
for (size_t i = 0; i < a_size; ++i) // size_t is the appropriate type here, not int.
std::cout << a[i] << std::endl; // Use std::endl to be able to discern where teh current number ends and the next starts!
}
// ...
int arr[3] = {1, 2, 3};
const size_t arr_size = sizeof(arr) / sizeof(arr[0]);
print(arr, arr_size);
...or do it in the C++ way and use std::vector...
void print(const std::vector<int>& a) {
for (const auto& s : a) // The new C++11 "for each" syntax.
std::cout << s << std::endl;
}
// ...
std::vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
print(a);
...or even make it generic...
template <typename T>
void print(const std::vector<T>& a) {
for (const auto& s : a)
std::cout << s << std::endl;
}

Functions in different files not working properly

I made a program that calls this function. I know this because "Int Strength has been called" appears in the output box. However, it will not change the values that I tell it to do.
I want it to get integer values from main(), then use them and return the new values.
I am using a header file that only contains "int strength(int a, int s, int i)"
int strength(int a, int s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
a = a + i;
s = s - i;
return a;
return s;
}
Multiple errors. Firstly, if you want the arguments to be modified (more precisely, the modification being effective out of the scope of the function), you have to pass the values by reference:
int strength(int &a, int &s, int &i)
Second, you seem to be concerned about return a; return s; returning two values. It doesn't - the very first return encountered exits the function immediately.
The values only change within the function. Variables are passed by value not reference.
Use references as the parameters.
int strength(int& a, int& s, int& i)
You're passing by value. You need to pass a pointer to the memory allocated in the caller that contains the data you wish to modify.
void strength(int *a, int *s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
*a += i;
*s -= i;
}
Then call it thusly:
a = 1;
s = 2;
i = 3;
strength(&a, &s, i);

How to use a class object in C++ as a function parameter

I am not sure how to have a function that receives a class object as a parameter. Any help? Here is an example below.
#include<iostream>
void function(class object); //prototype
void function(class tempObject)
{
//do something with object
//use or change member variables
}
Basically I am just confused on how to create a function that will receive a class object as its parameters, and then to use those parameters inside the function such as tempObject.variable.
Sorry if this is kind of confusing, I am relatively new to C++.
class is a keyword that is used only* to introduce class definitions. When you declare new class instances either as local objects or as function parameters you use only the name of the class (which must be in scope) and not the keyword class itself.
e.g.
class ANewType
{
// ... details
};
This defines a new type called ANewType which is a class type.
You can then use this in function declarations:
void function(ANewType object);
You can then pass objects of type ANewType into the function. The object will be copied into the function parameter so, much like basic types, any attempt to modify the parameter will modify only the parameter in the function and won't affect the object that was originally passed in.
If you want to modify the object outside the function as indicated by the comments in your function body you would need to take the object by reference (or pointer). E.g.
void function(ANewType& object); // object passed by reference
This syntax means that any use of object in the function body refers to the actual object which was passed into the function and not a copy. All modifications will modify this object and be visible once the function has completed.
[* The class keyword is also used in template definitions, but that's a different subject.]
If you want to pass class instances (objects), you either use
void function(const MyClass& object){
// do something with object
}
or
void process(MyClass& object_to_be_changed){
// change member variables
}
On the other hand if you want to "pass" the class itself
template<class AnyClass>
void function_taking_class(){
// use static functions of AnyClass
AnyClass::count_instances();
// or create an object of AnyClass and use it
AnyClass object;
object.member = value;
}
// call it as
function_taking_class<MyClass>();
// or
function_taking_class<MyStruct>();
with
class MyClass{
int member;
//...
};
MyClass object1;
At its simplest:
#include <iostream>
using namespace std;
class A {
public:
A( int x ) : n( x ){}
void print() { cout << n << endl; }
private:
int n;
};
void func( A p ) {
p.print();
}
int main () {
A a;
func ( a );
}
Of course, you should probably be using references to pass the object, but I suspect you haven't got to them yet.
I was asking the same too. Another solution is you could overload your method:
void remove_id(EmployeeClass);
void remove_id(ProductClass);
void remove_id(DepartmentClass);
in the call the argument will fit accordingly the object you pass. but then you will have to repeat yourself
void remove_id(EmployeeClass _obj) {
int saveId = _obj->id;
...
};
void remove_id(ProductClass _obj) {
int saveId = _obj->id;
...
};
void remove_id(DepartmentClass _obj) {
int saveId = _obj->id;
...
};
holy errors The reason for the code below is to show how to not void main every function and not to type return; for functions...... instead push everything into the sediment for which is the print function prototype... if you need to use useful functions ... you will have to below.....
(p.s. this below is for people overwhelmed by these object and T templates which allow different variable declaration types(such as float and char) to use the same passed by value in a user defined function)
char arr[ ] = "This is a test";
string str(arr);
// You can also assign directly to a string.
str = "This is another string";
can anyone tell me why c++ made arrays into pass by value one at a time and the only way to eliminate spaces and punctuation is the use of string tokens. I couldn't get around the problem when i was trying to delete spaces for a palindrome...
#include <iostream>
#include <iomanip>
using namespace std;
int getgrades(float[]);
int getaverage(float[], float);
int calculateletters(float[], float, float, float[]);
int printResults(float[], float, float, float[]);
int main()
{
int i;
float maxSize=3, size;
float lettergrades[5], numericgrades[100], average;
size=getgrades(numericgrades);
average = getaverage(numericgrades, size);
printResults(numericgrades, size, average, lettergrades);
return 0;
}
int getgrades(float a[])
{
int i, max=3;
for (i = 0; i <max; i++)
{
//ask use for input
cout << "\nPlease Enter grade " << i+1 << " : ";
cin >> a[i];
//makes sure that user enters a vlue between 0 and 100
if(a[i] < 0 || a[i] >100)
{
cout << "Wrong input. Please
enter a value between 0 and 100 only." << endl;
cout << "\nPlease Reenter grade " << i+1 << " : ";
cin >> a[i];
return i;
}
}
}
int getaverage(float a[], float n)
{
int i;
float sum = 0;
if (n == 0)
return 0;
for (i = 0; i < n; i++)
sum += a[i];
return sum / n;
}
int printResults(float a[], float n, float average, float letters[])
{
int i;
cout << "Index Number | input |
array values address in memory " << endl;
for (i = 0; i < 3; i++)
{
cout <<" "<< i<<" \t\t"<<setprecision(3)<<
a[i]<<"\t\t" << &a[i] << endl;
}
cout<<"The average of your grades is: "<<setprecision(3)<<average<<endl;
}