2015-03-24 3 views
0

Возможно ли заменить все эти «if, else if ...» на массив указателей функций в этом примере кода?Array of function pointer

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

Я пытаюсь получить что-то вроде этого:

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

    tab[0] = &my_ls; 
    tab[1] = &my_cd; 
    tab[2] = &my_user; 
    tab[3] = &my_pwd; 
    tab[4] = &my_quit; 
+0

Возможный дубликат [Как я могу использовать массив указателей функций?] (Http://stackoverflow.com/questions/252748/how-can-i-use-an-array-of-function-pointers) – cerkiewny

+0

Вам не нужна ссылка перед именем функции. – cerkiewny

+0

@cerkiewny Не дубликат, так как этот вопрос действительно является проблемой ассоциативного массива. –

ответ

1

Я создал код, чтобы проиллюстрировать, что вы хотели сделать, потому что я очень занимателен.

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

Есть и другие способы его написания. Фактически my_function совпадает с &my_function, поскольку только имя функции преобразуется в адрес функции. Также tab[i]() эквивалентно (*tab[i])() ... Это странное поведение, но я думаю, что это определено стандартом C

0

Я думаю, что вы хотите, словарь или hashtable:

  • Используйте buff как строка ключа
  • Используйте функцию указателя как значения
+0

Хэш-таблица или словарь будут медленнее, чем известный вызов функции смещения. Но это будет намного быстрее отдельного strncmp. – cerkiewny

1

Там нет никаких проблем с массивом указателей на функции, но вы должны преобразовать последовательность булевых strncmp() приводит к одному индексу.

Если список длинный, идея хэш-таблицы может быть победителем. Для компактного, простого кода и простота в обслуживании, я использовал массив структур:

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

Это также может быть то, что запись хэш-таблица выглядит, может быть отсортирован заранее, чтобы двоичный поиск, или просто последовательно искали версию KISS, пока не выясните, требуется ли вообще оптимизация.