Reputation: 9
i have a little question. i'm studying C with devc++ (as start) and i have seen as argument function you can pass a function, this is ok but why? for example u can write as argument:
void myfunc(void(*func)(int)){}
but if u simple call function with his name and argument it is not better?
like example:
void myfunction (){name of func to call(myargs); }
there's a difference? it seems the same thing but with more simple and short code
edit:
i want only know
void map (int (*fun) (int),int x[ ], int l) {
for(i = 0; i < l; i++)
x[i] = fun(x[i]);
}
why u use this instead of:
void map (int x[ ], int l) {
for(i = 0; i < l; i++)
x[i] = nameoffunction(yourargument);
}
Upvotes: 0
Views: 139
Reputation: 123558
i want only knowwhy u use this instead of:void map (int (*fun) (int),int x[ ], int l) { for(i = 0; i < l; i++) x[i] = fun(x[i]); }
void map (int x[ ], int l) { for(i = 0; i < l; i++) x[i] = nameoffunction(yourargument); }
Let's answer the question with a question - what if you want to perform more than one type of mapping? What if you want to map both x2 and √x?
You could certainly do something like
void map( int x[], int l, int type )
{
for ( int i = 0; i < l; i++ )
{
if ( type == MAP_SQUARED )
x[i] = int_square( x );
else if ( type == MAP_ROOT )
x[i] = int_root( x );
...
}
}
which works, but is hard to read and cumbersome to maintain - every time you want to perform a new mapping, you have to add a new case to the map
function.
Compare that to
void map( int x[], int l, int (*fun)(int) )
{
for ( int i = 0; i < l; i++ )
x[i] = fun( x[i] );
}
...
map( x, l, int_square );
map( y, l, int_root );
You don't have to hack the map
function to get different mappings - you only have to pass the function that operates on the individual elements. If you want to perform a new mapping, all you have to do is write a new function - you don't have to edit the map
function at all.
The C standard library uses this form of delegation in several places, including the qsort
function (allowing you to sort arrays of any type in any order) and the signal
function (allowing you to change how a program reacts to interrupts dynamically).
Upvotes: 0
Reputation: 31409
A very good example is the classic sorting function qsort
. It's a library function, which means that you only have access to it's prototype. In order to make qsort
general, you have to write your own compare function. A typical implementation looks like this for regular integers:
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
And then, if you have an array arr
of integers you can sort it with qsort(arr, sizeof(arr), cmpfunc)
You might ask why this is not built in the qsort
function? After all, it would be easy to make it work for both floats and integers. Yes, but imagine if you have an array of structs that look like this:
struct {
char *firstname;
char *lastname;
int age;
} persons[10];
How would you sort this? Well, that's not obvious. You might want all three. In that case, write three different compare functions.
Upvotes: 1
Reputation: 224437
You can use a function pointer as a parameter if you want your function to do different things depending on what the user wants.
Here's a simple example:
#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int subtract(int x, int y)
{
return x - y;
}
int multiply(int x, int y)
{
return x * y;
}
int divide(int x, int y)
{
return x / y;
}
int operation(int x, int y, int (*func)(int, int))
{
printf(" x=%d, y=%d\n", x, y);
return func(x,y);
}
int main()
{
int x = 8, y = 4;
printf("x+y=%d\n", operation(x,y,add));
printf("x-y=%d\n", operation(x,y,subtract));
printf("x*y=%d\n", operation(x,y,multiply));
printf("x/y=%d\n", operation(x,y,divide));
return 0;
}
Upvotes: 1