简体   繁体   中英

How to define an array of functions in C

I have a struct that contains a declaration like this one:

void (*functions[256])(void) //Array of 256 functions without arguments and return value

And in another function I want to define it, but there are 256 functions! I could do something like this:

struct.functions[0] = function0;
struct.functions[1] = function1;
struct.functions[2] = function2;

And so on, but this is too tiring, my question is there some way to do something like this?

struct.functions = { function0, function1, function2, function3, ..., };

EDIT : Syntax error corrected as said by Chris Lutz.

I have a struct that contains a declaration like this one:

No you don't. That's a syntax error. You're looking for:

void (*functions[256])();

Which is an array of function pointers. Note, however, that void func() isn't a "function that takes no arguments and returns nothing." It is a function that takes unspecified numbers or types of arguments and returns nothing. If you want "no arguments" you need this:

void (*functions[256])(void);

In C++, void func() does mean "takes no arguments," which causes some confusion (especially since the functionality C specifies for void func() is of dubious value.)

Either way, you should typedef your function pointer. It'll make the code infinitely easier to understand, and you'll only have one chance (at the typedef ) to get the syntax wrong:

typedef void (*func_type)(void);
// ...
func_type functions[256];

Anyway, you can't assign to an array, but you can initialize an array and copy the data:

static func_type functions[256] = { /* initializer */ };
memcpy(mystruct.functions, functions, sizeof(functions));

I had the same problem, this is my small program to test the solution. It looks pretty straightforward so I thought I'd share it for future visitors.

#include <stdio.h>

int add(int a, int b) {
    return a+b;
}

int minus(int a, int b) {
    return a-b;
}

int multiply(int a, int b) {
    return a*b;
}

typedef int (*f)(int, int);                 //declare typdef

f func[3] = {&add, &minus, &multiply};      //make array func of type f,
                                            //the pointer to a function
int main() {
    int i;
    for (i = 0; i < 3; ++i) printf("%d\n", func[i](5, 4));
    return 0;
}

You can do it dynamically... Here is a small example of a dynamic function array allocated with malloc...

#include <stdio.h>
#include <stdlib.h>

typedef void (*FOO_FUNC)(int x);

void a(int x)
{
    printf("Function a: %d\n", x);
}

void b(int x)
{
    printf("Function b: %d\n", x);
}

int main(int argc, char **argv)
{
    FOO_FUNC *pFoo = (FOO_FUNC *)malloc(sizeof(FOO_FUNC) * 2);
    pFoo[0] = &a;
    pFoo[1] = &b;

    pFoo[0](10);
    pFoo[1](20);

    return 0;
}

From the top of my head and untested.

// create array of pointers to functions
void (*functions[256])(void) = {&function0, &function1, &function2, ..., };

// copy pointers to struct
int i;
for (i = 0; i < 256; i++) struct.functions[i] = functions[i];

EDIT : Corrected syntax error as said by Chris Lutz.

You could do that while declaring your struct instance:

function_structur fs = { struct_field1,
                         struct_field2,
                         {function0, function1, ..., function255},
                         struct_field3,
                         ... };

You cannot use this shortcut for initialize arrays after the array has been declared: if you need to do that, you'll have to do it dynamically (using a loop, a memcpy or something else).

If you want to post -initialize an array using form like {func1, func2, ...} , this can be accomplished in the following way (using GCC):

UPD (thanks to Chris Lutz for remarks)

Define a macro like this:

#define FUNCTION_VECTOR_COPY(destVec, sourceVec) memcpy(destVec, sourceVec, sizeof(sourceVec))

And pass source vector using Compound Literals , as follow:

#include <string.h>
...
void (*functions[256])();
...
FUNCTION_VECTOR_COPY (functions, ((void(*[])()) {func1, func2, func3}));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM