I had pleasure of working with function pointers lately. I got to know how they work. Classical example of function pointers is :
int add() {
return (100+10);
}
int sub() {
return (100-10);
}
void print(int x, int y, int (*func)()) {
printf("value is : %d", (x+y+(*func)()));
}
int main() {
int x=100, y=200;
print(x,y,add);
print(x,y,sub);
}
Somebody asked me the other day that how is it better than calling(inside main):
print(add(x,y));
print(sub(x,y));
and I struggled to explain that. Is it only about the stack or there is something else lying underneath?
I don't really understand why the code you show would be a classical example of function pointers. Functions pointers' utility is much more obvious from code like this:
void transform(int *dst, const int *src, size_t len, int (*f)(int))
{
for (size_t i = 0; i < len; ++i)
dst[i] = f(src[i]);
}
Basically, if you accept a pointer to function as a parameter, it allows you to apply a client-provided operation on data of your choice.
The classic use case (which generalizes) is qsort (https://linux.die.net/man/3/qsort). The sort algorithm is general purpose but the implementation does not know how to compare items because they can be of any type. So you pass in a function that it can call in order to compare two elements.
Function pointers are pretty much useless overhead if you hard coded call the one or the other, like your example. Their power comes from being able to dynamically pick and use them, or pass them to other functions:
You can put function pointers in an array, and loop over them; or you can call a selected one based on a user-input or input file content, or other circumstances. In both cases, they will allow to write code that has a single dynamic call, instead of potential long switch or if statement chains.
The second - and even more useful - concept is to pass them to some other function (also sometimes called 'callbacks'); a classic example is to call qsort with your data table and a custom comparison function in form of a function pointer. qsort will then use your comparison function inside the standardized sort algorithm; there is no other way to implement this.
"pointer to function" is an object. So it can be copied,stored,assigned like any other object.
Where as references to functions (normal functions) are not objects.
I think the classic example is.... User interfaces events handling by using callback functions, which has become an obvious pattern for any UI software.
Related
I have looked at the following threads, but they do not seem to help resolve the issue:
Function pointer to member function - this thread does not help because the access is made within main and not another class
one class should invoke method of another class using a function pointer - I could not follow the accepted answer as it is not clear to me how to use <functional> header.
I have a Useful Function class, UF, in which I declare and define all common utility functions for my program. One of these functions is
int UF::compar_dbl_asc(const void *a, const void *b)//comparator for sorting
{ //array of double in ascending order
int aa = *((int *)a), bb = *((int *)b);
if (base_arr_dbl[aa] < base_arr_dbl[bb])
return -1;
if (base_arr_dbl[aa] == base_arr_dbl[bb])
return 0;
if (base_arr_dbl[aa] > base_arr_dbl[bb])
return 1;
}
This is a comparator function that I intend to use within qsort() for sorting doubles in ascending order.
Within UF class definition, I also have double* base_arr_dbl; as a declaration. This is the array of values (doubles) that qsort will use.
Now, in a different class of mine named SEP, I have a function, fn1 wherein I would like to have base_arr_dbl point to a local (to fn1) double array and I would like to invoke qsort using the comparator function in UF. To be very specific although this is possibly not needed, I do not sort the actual values' array, but will sort an array of indices sortedindices[], such that sortedindices[0] will hold the index of the smallest entry in base_arr_dbl[] array. That is, the sorted order is base_arr_dbl[sortedindices[0]], base_arr_dbl[sortedindices[1]], etc.
So, I do this:
void SEP::fn1(UF *uf) {
double ratio[100];
//populate ratio's entries
//Now, sort ratio's entries.
uf->set_base_arr_dbl(ratio); //This function is defined as
//void UF::set_base_arr_dbl(double *ptr) { base_arr_dbl = ptr; }
qsort(sortedindices, 100, sizeof(double), uf->compar_dbl_asc);
}
However, the line qsort(sortedindices, 100, sizeof(double), uf->compar_dbl_asc); throws the following compile time error:
error C3867: 'USEFUL_FUNCTIONS::compar_dbl_asc': non-standard syntax; use '&' to create a pointer to member
I tried having &uf->compar_dbl_asc but that gives the error:
error C2276: '&': illegal operation on bound member function expression
Any way to help resolve this is appreciated.
As the compiler clearly tells in the error messages, neither uf->compar_dbl_asc nor &(uf->compar_dbl_asc) is appropriate for use as an argument to qsort.
You can use compar_dbl_asc as an argument to qsort using one of the following approaches.
Make compar_dbl_asc a static member function of the class.
Better yet, create a namespace for your app and define compar_dbl_asc in the namespace. UF could be that namespace unless it must be a class for some other reasons.
Another choice would be forego use of qsort in favor of std::sort. The latter gives you more options. You can use a functor or a lambda function when you use std::sort, which will allow you to use UF::compar_dbl_asc.
std::sort(sortedindices, sortedindices+100,
[=uf](int a, int b) { return uf->compar_dbl_asc(a, b); });
One thing to note is that if you choose the last approach, the signature of UF::compar_dbl_asc can be changed to a more user friendly variation.
bool UF::compar_dbl_asc(int a, int b)
return (base_arr_dbl[a] < base_arr_dbl[b]);
}
I have a function which internally uses some helper functions to keep its body organized and clean. They're very simple (but not always short) (they're more than just 2), and could be easily inlined inside the function's body, but I don't want to do so myself because, as I said, I want to keep that function's body organized.
All those functions need to be passed some arguments by reference and modify them, and I can write them in two ways (just a silly example):
With normal functions:
void helperf1(int &count, int &count2) {
count += 1;
count2 += 2;
}
int helperf2 (int &count, int &count2) {
return (count++) * (count2--);
}
//actual, important function
void myfunc(...) {
int count = count2 = 0;
while (...) {
helperf1(count, count2);
printf("%d\n", helperf2(count, count2));
}
}
Or with lambda functions that capture those arguments I explicitly pass in the example above:
void myfunc(...) {
int count = count2 = 0;
auto helperf1 = [&count, &count2] () -> void {
count += 1;
count2 += 2;
};
auto helperf2 = [&count, &count2] () -> int {
return (count++) * (count2--);
};
while (...) {
helperf1();
printf("%d\n", helperf2());
}
}
However, I am not sure on what method I should use. With the first, one, there is the "overhead" of passing the arguments (I think), while with the second those arguments could be (are them?) already included in there so that that "overhead" is removed. But they're still lambda functions which should (I think, again) not be as fast as normal functions.
So what should I do? Use the first method? Use the second one? Or sacrifice readability and just inline them in the main function's body?
Your first and foremost concern should be readability (and maintainability)!
Which of regular or lambda functions is more readable strongly depends on the given problem (and a bit on the taste of the reader/maintainer).
Don't be concerned about performance until you find that performance actually is an issue! If performance is an issue, start by benchmarking, not by guessing which implementation you think is faster (in many situations compilers are pretty good at optimizing).
Performance wise, there is no real issue here. Nothing to decide, choose whatever.
But, Lambda expressions won't do you any good for the purpose you want them.
They won't make the code any cleaner.
As a matter of fact I believe they will make the code a bit harder to read compared to a nice calculator object having these helper functions as member functions properly named with clean semantics and interface.
Using Lambda is more readable but they are actually there for more serious reasons , Lambda expressions are also known as "anonymous functions", and are very useful in certain programming paradigms, particularly functional programming, which lambda calculus ( http://en.wikipedia.org/wiki/Lambda_calculus )
Here you can find the goals of using lambdas :
https://dzone.com/articles/why-we-need-lambda-expressions
If you won't need the two helper functions somewhere else in your code, then use your lambda method , but if you will call one of them again somewhere in your project avoid writing them each time as lambdas , you can make a header file called "helpers.(h/hpp)" & a source file called "helper.(c/cpp)" then append all the helper functions there then you gain the readability of both the helper file and the caller file
You can avoid this unskilled habit and challange yourself by writing complex code that you have you read it more than once each time you want to edit it , that increases your programming skills and if you are working in a team , it won't be a problem , use comments , that will let them show more respect to your programming skills (if your complex code is doing the expected behaviour and giving the expected output)
And don't be concerned about performance until you find yourself writing a performance critical algorithm , if not , the difference will be in few milliseconds and the user won't notice it , so you will be loosing you time in an optimization that compiler can do by itself most of the time if you ask him to optimize your code .
here is code of example:
const vector<int>* (*seq_array[])(int) = {
fibon_seq, lucas_seq, pell_seq,
triang_seq, square_seq, pent_seq
};
i step by step to figure out the declare:
*seq_array[] is is an array of pointer
(*seq_array[])(int) is an function with int parameter
3.so the const vector<int>* (*seq_array[])(int) is a pointer function that return const vector<int> type with a int parameter.
If my understanding is correct,then i can't find any return statement in this function.
If not, anyone can pointing out my mistakes and give some direction about complex declarators.thanks.
seq_array is i) an array ii) of function pointers iii) that take an int and return const vector<int>*. One of the simplest way of learning what's going on is to follow the so-called spiral rule. IMHO, it's one of the best mnemonics out there, even if from 1994.
You have an array of function pointers, so the stuff inside the = { ... } bit is a list of functions matching the expected signature; that's why there's no return statement: it's an array with values, not a function definition.
Trying to compare voids for a sorting algorithm. I have this so far but it kinda defeats the purpose IMO if you cast them to ints. Is there a way to compare voids? My professor ran out of time and how were stuck scowering the web. Any help is appreciated. Thanks
int fcmp(const void *one, const void *two)
{
if (*(int*)one > *(int*)two) return 1;
if (*(int*)one < *(int*)two) return -1;
return 0;
}
Assuming that the idea is to use fcmp in the context of qsort, your code is perfectly valid.
Since qsort does not care for the returned value to be 1 or -1 and would take any positive or negative number, this version is even shorter, but would work with qsort just as well:
int fcmp (const void * one, const void * two)
{
return ( *(int*)one - *(int*)two );
}
The reason qsort uses void* is to let you use the same algorithm with different data types.
You are not comparing "voids" in this code. The code is casting the void pointers into int pointers, and then dereferencing the result, which means you're comparing the ints to which the pointers point to. Ideally, the function would have been written like this:
int fcmp(const int *one, const int *two)
{
if (*one > *two) return 1;
if (*one < *two) return -1;
return 0;
}
But it isn't written like that since fcmp() in this case needs to have a specific signature. Otherwise it couldn't be used in a generic way. As a callback to another function, for example.
This looks to be a standard comparison function used in several of the standard library functions like qsort() in which you call the function with some kind of array of data items along with the comparison function that indicates whether two elements are equal to each or or not and if not what is their collating order.
So what the void pointer points to is kind of up to the programmer. That is the purpose of using the void pointers in the comparison function interface because the function, such as qsort(), which is calling the comparison function just wants to know what order two array elements are to go in. It does not know what the array elements are or how to do the comparison, it just knows the starting address of the array and the size of each element and how many elements are there.
Another function from the standard library is the bsearch() function.
So to use this you might have code like the following:
see qsort() man page.
typedef struct {
int iValue;
char sName[10];
} DataValue;
// compare two elements of the array and indicate which one is higher
// or lower in collating sequence or if they are equal.
int dataComp (void *one, void *two)
{
return ((DataValue *)one)->iValue - ((DataValue *)two)->iValue;
}
int main (int argc, char *argv[])
{
DataValue myData[25];
//.. put some data stuff in the array.
// call qsort with the array. specify number of elements and size of each one
qsort (myData, sizeof(myData)/sizeof(myData[0]), sizeof(myData[0]), dataComp);
}
In C++ I want to add two 50-digit numbers. I use an array to keep each. It means that I want to add two arrays. My problem is that I want to do this in a function named AddNum()
and pass the result to another function named WriteNum for printing and I don't know how to pass an array returned by one function to another function.
hope that my question was clear enough
thanx all
Don't use arrays. Look up the C++ std::vector class in your text book or help system and use that instead. It will make life much easier for you.
Don't return an array from the addition function - instead make it return void and pass the array for storing the result by reference or pointer. Then you will pass that array to the function for printing.
First of all, if you will be adding a lot of numbers, saving them in arrays is troublesome and takes both cpu power and memory. If you can, use GMP (optimized and fast library).
If you must use arrays, then use c++'s vectors instead of c's arrays which will minimize the chance for error and make it simpler.
To send a vector to a function, you do it normally as with int's, string's etc, namely
vector<int> number1;
vector<int> number2;
addnum(number1, number2);
where addnum is defined as :
void addnum(vector<int> a, vector<int> b)
This will copy the first and the second vector array that you have into variables a and b. It is recommended that you send a reference to the addnum in order skip to copy the vectors all the time. This can be done by changing the addnum definition to :
void addnum(vector<int>& a, vector>int>& b)
and then performing normal operation on a and b as usual.
To have addnum return a vector you need to change the definition of addnum to
vector<int> addnum(vector<int>& a, vector>int>& b)
and of course have the return statement with the vector you want to return.
If you choose to send the values by references, that means that the number1 and number2 vectors declared in you main class will also change if you change them in the addnum function. That basically means that, if you save the result in variable a in the addnum function, you will have that same value in the number1 vector, meaning you don't need the function to return a new vector but can instead reuse the existing ones.
Just to clarify the answer of sharptooth: if you want to return a new array, you have to allocate it in the function and someone else will have to free it. It can be done but you will always have to remember to free the result after calling the function. As Neil Butterworth points out: std::vector helps you solve this.
if i get it right, and if this is what you wanna do, your functions should have signatures like that:
int* addNumbers(int* array1, int* array2)
{
....
}
and
void writeNumbers(int *array3)
{
....
}
and you can call it like:
//declare and init array1 and array2
//...
writeNumbers(addNumbers(array1, array2));
i hope i understood your question correctly.