0

Is it possible to replace all of these "if, else if ..." with an array of function pointers in this example of code ?

  if (strncmp(buff, "ls\n", 3) == 0)
    my_ls();
  else if (strncmp(buff, "cd\n", 3) == 0)
    my_cd();
  else if (strncmp(buff, "user\n", 5) == 0)
    my_user();
  else if (strncmp(buff, "pwd\n", 4) == 0)
    my_pwd();
  else if (strncmp(buff, "quit\n", 5) == 0)
    my_quit();

I'm trying to get something like this :

void (*tab[5]) (void);

  tab[0] = &my_ls;
  tab[1] = &my_cd;
  tab[2] = &my_user;
  tab[3] = &my_pwd;
  tab[4] = &my_quit;
3
  • possible duplicate of How can I use an array of function pointers? Commented Mar 24, 2015 at 16:19
  • You don't need the reference before function name. Commented Mar 24, 2015 at 16:19
  • @cerkiewny Not a duplicate, since this question is really an associative array problem in disguise. Commented Mar 24, 2015 at 16:41

3 Answers 3

1

I created a code to illustrate what you wanted to do, because I it's pretty entertaining.

#include <stdio.h>
#include <string.h>

// your functions
void my_ls()  { puts("fun:my_ls")  ;}
void my_cd()  { puts("fun:my_cd")  ;}
void my_user(){ puts("fun:my_user");}
void my_pwd() { puts("fun:my_pwd") ;}
void my_quit(){ puts("fun:my_quit");}


int main(int argc, char const *argv[])
{
    char* buff="ls\n"; // the string you have to compare

    void (*tab[5]) (void)={my_ls,my_cd,my_user,my_pwd,my_quit};
    char *names[5]={"ls\n","cd\n","user\n","pwd\n","quit\n"};

    int i;
    for (i=0; i<5; i++)
    {
        if(strncmp(buff,names[i],strlen(names[i]) )==0){
            tab[i]();
            return 0;
        }
    }
    return 0;
}

There are other ways to write it. Actually my_function is the same as &my_function since a function name alone is converted to the adress of the function. Also tab[i]() is equivalent to (*tab[i])()... Those are weird behaviours but I think it's specified by C standard

Sign up to request clarification or add additional context in comments.

Comments

1

There's no problem with an array of function pointers, but you'd need to convert the sequence of boolean strncmp() results to a single index.

If the list is long, the hash table idea might be a winner. For compact, simple code and easy maintenance, I've used an array of structs:

typedef struct cmdtable_t
{
    void (*fptr)();
    unsigned char length
    char name[11];
} cmdtable_t, *pcmdtable_t;

cmd_table_t commands = {
    { my_ls,   2, "ls"},
    { my_cd,   2, "cd" },
    { my_user, 4, "user" },
    ...etc.
};

That could also be what a hash table entry looks like, could be sorted in advance to allow a binary search, or simply sequentially searched for a KISS version until you find out whether this needs optimizing at all.

Comments

0

I think you want a dictionary or hashtable:

  • Use buff as string key
  • Use function pointer as values

1 Comment

hash table or dictionary will be slower then known offset function call. But it will be much faster the individual strncmp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.