wisepeople
wisepeople

Reputation: 9

why pass as argument of a function a function?

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

Answers (3)

John Bode
John Bode

Reputation: 123558

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);
}

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

klutt
klutt

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

dbush
dbush

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

Related Questions