tags:

views:

88

answers:

4

Hey!

i need to write a function that receives an array of pointers to functions. i wrote the following code, however i'm having trouble in testing it at the moment.

is this the correct way to define a pointers to function array?

typedef (*Function)(double);
void func(Function* arr);

and if i want to declare the size of the array with [20] do i write:

void func(Function arr[20]);

?

thanks for your help

A: 

What does the function return? You're the return type in the function pointer typedef, like you should have something like

typedef double (*Function)(double);
arsenm
ah right forgot that.. lets say it does return double as you wrote, is my array declarations correct?
Mike
A: 

it looks almost correct i think you forgot the return type when declaring Function:

typedef int (*Function)(double)

instead

the second declaration is invalid too i think because it is invalid to specify array size for function parameters

void func (Function*)

will do just fine

flownt
however this is valid:void func(Function arr[]);?
Mike
@Mike: that is valid, and is a synonym for `void func(Function *arr);`. It might mean "pass an array" to the programmer, but to the compiler it means "pass a pointer". You can't pass arrays as function parameters in C. You can pass pointers to them (or, more commonly, to their first elements, since that's what array names "decay" to), or structs containing them.
Steve Jessop
You can also say `void func(Function arr[20])` but the compiler treats that as equivalent to `void func(Function arr[])` or `void func(Function *arr)` for most practical purposes.
Jonathan Leffler
+3  A: 

If you correct the typedef to include a return type typedef void (*Function)(double);, that array declaration will work fine. You'd call it by calling (arr[index])(3.14) for the array case.

BTW: http://www.newty.de/fpt/fpt.html is a handy reference for function pointers.

jkerian
A: 

First, my usual method for figuring out complex types. Start with the identifier, and then add on the rest one step at a time:

    f          -- f
    f[N]       -- is an N-element array
   *f[N]       -- of pointers
  (*f[N])()    -- to functions
T (*f[N])()    -- returning T

For an array of pointers to functions taking a double parameter and returning a double value, that would be

double (*f[N])(double);

However, remember that expressions of array type "decay" from type "N-element array of T" to "pointer to T" in most contexts. When you pass an array expression as an argument to a function, what the function actually receives is a pointer. So, instead of receiving an object of type "N-element array of pointer to function returning double", your function will receive an object of type "pointer to pointer to function returning double", or

double (**f)(double)

So your function definition would look something like

void func(double (**f)(double))
{
  int i;
  ...
  for (i = 0; f[i] != NULL; i++)
  {
    double x = (*f[i])((double) i);
  }
}

And the caller would look something like

double a(double x) {...}
double b(double x) {...}
double c(double x) {...}

void foo(void)
{
  double (*list[])(double) = {a, b, c, NULL};
  func(list);
}

If you want to use typedefs instead, you could use something like this:

typedef double Dblfunc(double);   // typedef for function type 
typedef Dblfunc *Dblfuncptr;      // typedef for function pointer type

void func(Dblfuncptr *f)
{
  int i;
  for (i = 0; f[i] != NULL; i++)
  {
    double x = (*f[i])((double) i);
    ...
  }
}
...
void foo(void)
{
  Dblfuncptr list[] = {a, b, c, NULL}; // EDIT: fixed type
  func(list);
}

Using the typedefs makes the array and function parameter look more like regular types. Personally, I prefer using the "raw" types, since it shows explicitly that I'm dealing with pointers to functions, and it shows what the return and parameter types are.

John Bode