将参数传递给函数指针

时间:2015-12-10 15:17:36

标签: c function-pointers

我无法弄清楚如何在以下场景中传递参数:

#include<stdio.h>

void quit(const char*);

int main(void){
    const char *exit = "GoodBye";
    void (*fptr)(const char*) = quit;
    (*fptr)(exit);

    return 0;
}

void quit(const char *s){
    printf("\n\t%s\n",s);
}

这就是我的程序应该如何工作的方式,但是当我制作文本菜单时,我无法弄清楚如何做到这一点:

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

int update(void);
int upgrade(void);
int quit(void);
void show(const char *question, const char **options, int (**actions)(void), int length);

int main(void){
    const char *question = "Choose Menu\n";
    const char *options[3] = {"Update", "Upgrade", "Quit"};
    int (*actions[3])(void) = {update,upgrade,quit};

    show(question,options,actions,3);
    return 0;
}

int update(void){
    printf("\n\tUpdating...\n");
    return 1;
}

int upgrade(void){
    printf("\n\tUpgrade...\n");
    return 1;
}

int quit(void){
    printf("\n\tQuit...\n");
    return 0;
}

void show(const char *question, const char **options, int (**actions)(void), int length){
    int choose = 0, repeat = 1;
    int (*act)(void);

    do{
        printf("\n\t %s \n",question);
        for(int i=0;i<length;i++){
            printf("%d. %s\n",(i+1),options[i]);
        }

        printf("\nPlease choose an Option:  ");
        if((scanf("%d",&choose)) != 1){
            printf("Error\n");
        }
        act = actions[choose-1];
        repeat = act();

        if(act==0){
            repeat = 0;
        }
    }while(repeat == 1);
}

在这里,我需要像第一个示例中那样将退出函数(int quit(void);更改为int quit(char *s){};),并使用const char *exit = "GoodBye"; ==&gt;&gt;等参数调用它。 (*fptr)(exit);

我知道此时我的程序仅以void作为参数,但我这样做只是为了说明问题。

我对此很困惑。

编辑:

这个int (*actions[3])(void)我认为是一个函数指针数组,所有3个函数指针都将void作为参数,但我需要知道我是否可以使用一个指针来获取参数,或者我必须重新编码整个计划。

2 个答案:

答案 0 :(得分:3)

由于您有一个函数指针数组,因此所有函数都必须属于同一类型。所以至少每个函数都应该使用const char *(并非所有函数都需要使用它),并且应该更改数组类型以匹配。

如果你想要更灵活的东西,你可以让函数接受一个void *,这样每个函数都可以传递一个不同的参数,然后它被转换为适当的类型。这就是pthreads如何将参数传递给启动新线程的函数。你将失去一些编译时类型检查,所以如果你走这条路线就要小心。

编辑:

后者的一个例子:

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

int update(void *);
int upgrade(void *);
int quit(void *);

int main(void){
    const char *question = "Choose Menu\n";
    const char *options[3] = {"Update", "Upgrade", "Quit"};
    int (*actions[3])(void *) = {update,upgrade,quit};

    show(question,options,actions,3);
    return 0;
}

int update(void *unused){
    printf("\n\tUpdating...\n");
    return 1;
}

int upgrade(void *unused){
    printf("\n\tUpgrade...\n");
    return 1;
}

int quit(void *message){
    printf("\n\tQuit...%s\n", (char *)message);
    return 0;
}

void show(const char *question, const char **options, int (**actions)(void *), int length){
    ...
    if (act == quit) {
        repeat = act("GoodBye");
    } else {
        repeat = act(NULL);
    }
    ...
}

答案 1 :(得分:2)

由于您正在使用一个函数指针数组,因此您不知道哪些参数占用哪些参数。但是,您可以通过使函数采用“未指定数量的参数”来避免重新编码。即从函数指针和函数指针的原型以及void函数中删除quit()作为参数。

int quit(const char*);
void show(const char *question, const char **options, int (**actions)(), int length);

int main(void){
    const char *question = "Choose Menu\n";
    const char *options[3] = {"Update", "Upgrade", "Quit"};
    int (*actions[3])() = {update,upgrade,quit};
    ...
}

int quit(const char *msg){
    printf("\n\tQuit...%s\n", msg);
    return 0;
}

void show(const char *question, const char **options, int (**actions)(), int length){
    ....
    int (*act)();
   ....
}

这是有效的,因为C允许没有显式参数的函数采用“未指定数量的参数”。否则,您需要使所有功能都具有相似的签名。