简体   繁体   English

将参数传递给函数指针

[英]Passing an argument to function pointer

I just can't figure out how to pass an Argument like in the following scenario: 我只是不知道如何在以下情况下传递参数:

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

This is how my program should work and it does, but when I make a text menu i just can't figure out how to do it: 这是我的程序应该如何工作并起作用的方法,但是当我创建文本菜单时,我只是想不出如何做:

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

Here I need to change the quit function ( int quit(void); to int quit(char *s){}; ) like in the First example and call it with an argument like const char *exit = "GoodBye"; 在这里,我需要像第一个示例一样将quit函数( int quit(void);更改为int quit(char *s){}; ),并使用const char *exit = "GoodBye";这样的参数进行调用const char *exit = "GoodBye"; ==>> (*fptr)(exit); == >> (*fptr)(exit);

I know that at this point my program takes only void as argument, but I done it only to illustrate the problem. 我知道在这一点上我的程序仅将void作为参数,但是我这样做只是为了说明问题。

I'm very confused about this. 我对此很困惑。

EDIT: 编辑:

this int (*actions[3])(void) I think is an Array of Function pointers and all 3 function pointers takes void as argument, but I need to know if i can use one pointer to take an argument or i have to re-code the whole program. 这个int (*actions[3])(void)我认为是一个函数指针数组,所有3个函数指针都将void作为参数,但是我需要知道我是否可以使用一个指针作为参数,否则我必须重新-编码整个程序。

Since you have an array of function pointers, all the functions need to be of the same type. 由于您具有函数指针数组,因此所有函数都必须具有相同的类型。 So at the very least each function should take a const char * (not all functions need to use it) and the array type should be changed to match. 因此,至少每个函数都应采用const char * (并非所有函数都需要使用const char * ),并且应更改数组类型以使其匹配。

If you want something more flexible, you can have the functions accept a single void * so each function can be passed a different parameter which it then casts to the appropriate type. 如果您想要更灵活的东西,可以让函数接受单个void *以便可以为每个函数传递一个不同的参数,然后将其转换为适当的类型。 This is how pthreads passes parameters to functions which start a new thread. 这就是pthreads将参数传递给启动新线程的函数的方式。 You will lose some compile-time type checking with this, so be careful if you go this route. 您将因此失去一些编译时类型检查,因此如果您选择这种方法,请务必小心。

EDIT: 编辑:

An example of the latter: 后者的示例:

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

Since you are using a an array of function pointers, you don't know which ones to take which arguments. 由于您使用的是函数指针数组,因此您不知道该使用哪个参数。 But have You can avoid re-coding it by making the functions to take "unspecified number of arguments". 但是,您可以通过使函数采用“未指定数量的参数”来避免对其进行重新编码。 ie Remove the void from as the parameter from function definitions and prototypes from of the function pointers and from the quit() function. 即从函数指针和quit()函数中,从函数定义和原型中删除void from作为参数。

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

This works because C allows a function with no explicit parameters to take "unspecified number of arguments". 之所以可行,是因为C允许没有显式参数的函数采用“未指定数量的参数”。 Otherwise, you need to make all functions have similar signatures. 否则,您需要使所有功能具有相似的签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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