我无法弄清楚如何在以下场景中传递参数:
#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作为参数,但我需要知道我是否可以使用一个指针来获取参数,或者我必须重新编码整个计划。
答案 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允许没有显式参数的函数采用“未指定数量的参数”。否则,您需要使所有功能都具有相似的签名。