简体   繁体   中英

C - How to setup an associative array of function pointers?

Here's what I'm trying to do:

myValueType function1(myParam){}

myValueType function2(myParam){}

myArray[CONSTANT_STATE1] = &function1;
myArray[CONSTANT_STATE2] = &function2;

myValue = (*myArray[CONSTANT_STATE1])(myParam);

When I compile, it throws an error that I've redeclared function1.

What's the best way to do this?

As per this SO answer from user Vijay Mathew :

Section 6.6 of The C Programming Language presents a simple dictionary (hashtable) data structure. I don't think a useful dictionary implementation could get any simpler than this. For your convenience, I reproduce the code here.

struct nlist { /* table entry: */
    struct nlist *next; /* next entry in chain */
    char *name; /* defined name */
    char *defn; /* replacement text */
};

#define HASHSIZE 101
static struct nlist *hashtab[HASHSIZE]; /* pointer table */

/* hash: form hash value for string s */
unsigned hash(char *s)
{
    unsigned hashval;
    for (hashval = 0; *s != ’\0’; s++)
      hashval = *s + 31 * hashval;
    return hashval % HASHSIZE;
}

/* lookup: look for s in hashtab */
struct nlist *lookup(char *s)
{
    struct nlist *np;
    for (np = hashtab[hash(s)]; np != NULL; np = np->next)
        if (strcmp(s, np->name) == 0)
          return np; /* found */
    return NULL; /* not found */
}

char *strdup(char *);
/* install: put (name, defn) in hashtab */
struct nlist *install(char *name, char *defn)
{
    struct nlist *np;
    unsigned hashval;
    if ((np = lookup(name)) == NULL) { /* not found */
        np = (struct nlist *) malloc(sizeof(*np));
        if (np == NULL || (np->name = strdup(name)) == NULL)
          return NULL;
        hashval = hash(name);
        np->next = hashtab[hashval];
        hashtab[hashval] = np;
    } else /* already there */
        free((void *) np->defn); /*free previous defn */
    if ((np->defn = strdup(defn)) == NULL)
       return NULL;
    return np;
}

char *strdup(char *s) /* make a duplicate of s */
{
    char *p;
    p = (char *) malloc(strlen(s)+1); /* +1 for ’\0’ */
    if (p != NULL)
       strcpy(p, s);
    return p;
}

Note that if the hashes of two strings collide, it may lead to an O(n) lookup time. You can reduce the likely hood of collisions by increasing the value of HASHSIZE . For a complete discussion of the data structure, please consult the book.

The code you've shown is almost right. The problem is in your function declarations:

myValueType function1(myParam){}

myValueType function2(myParam){}

These are old-style K&R non-prototyped declarations - the name of the parameter is myParam , and the type has not been specified. Perhaps you meant this?

myValueType function1(myParamType myParam){}

myValueType function2(myParamType myParam){}

Expanding your code out to a minimal compilable example:

typedef int myValueType, myParamType;
enum { CONSTANT_STATE1, CONSTANT_STATE2 };

myValueType function1(myParamType myParam){}

myValueType function2(myParamType myParam){}

void f(myParamType myParam)
{
    myValueType myValue;
    myValueType (*myArray[2])(myParamType);

    myArray[CONSTANT_STATE1] = &function1;
    myArray[CONSTANT_STATE2] = &function2;

    myValue = (*myArray[CONSTANT_STATE1])(myParam);
}

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