这个问题是关于如何在我设计程序的层面上解决我的问题。为了完成一个学校项目,我正在构建一个shell,其中包含几个内置函数。其中一个函数的目的(cmd_type)是检查提供的参数是否在这些函数列表中。以下是它的部分实现:
它们这样使用:
然后他们会愉快地把(int argc, char *argv[])作为参数。但是cmd_path()需要访问该列表以及这些参数,所以我必须将其定义为全局变量或定义一个指向全局变量的指针...在研究过程中,我发现了这个答案,说类似的方法确实很不好:https://stackoverflow.com/a/41425477/5537652 所以我的问题是:这是解决这个问题的好方法吗?还是我应该使用if/else语句/是否有更好的方法?你会建议使用函数名称数组的全局指针吗?
int cmd_type(int argc, char *argv[]) {
if (argc == 2) {
for (int i = 0; i < BUILTIN_FUNC_COUNT; i++) {
if (strcmp(cmds_name[i], argv[1]) == 0) {
printf("%s is a shell builtin\n", argv[1]);
return 0; // found it
}
}
// still need to search path, call stat(path/cmd)
errmsg("not implemented! type", 1);
} else {
err_msg("type", 1);
}
}
为每个我支持的函数定义手动if语句似乎是一个糟糕的选择,因为列表可能会随着时间而扩展,并且我需要存储函数名称的列表。因此,最初,我计划定义一个函数名数组和它们指针的数组,如下所示:
char cmds_name[BUILTIN_FUNC_COUNT-1][16];
char (*cmds_ptr)(int,*char[])[BUILTIN_FUNC_COUNT-1];
// make list of built-in funcs
strcpy(cmds_name[0], "exit");
strcpy(cmds_name[1], "cd");
// make list of func pointers
cmds_ptr[0] = &cmd_exit;
cmds_ptr[1] = &cmd_cd;
它们这样使用:
// try builtin cmds
for (int i = 0; i < BUILTIN_FUNC_COUNT; i++) {
if (strcmp(cmds_name[i], argv[0]) == 0) {
last_cmd_err = (*cmds_ptr[i])(argc, argv);
continue; // we found it, so next loop
}
}
然后他们会愉快地把(int argc, char *argv[])作为参数。但是cmd_path()需要访问该列表以及这些参数,所以我必须将其定义为全局变量或定义一个指向全局变量的指针...在研究过程中,我发现了这个答案,说类似的方法确实很不好:https://stackoverflow.com/a/41425477/5537652 所以我的问题是:这是解决这个问题的好方法吗?还是我应该使用if/else语句/是否有更好的方法?你会建议使用函数名称数组的全局指针吗?
int builtin_cmd(int argc,char **argv,void *extra)
原型定义函数。额外的指针指向函数需要的任何额外信息。最好能够设计一种类型——可能是某种结构体指针——而不是模棱两可的void *
,但那是最通用的类型。不需要额外信息的函数可以传递空指针,或者可以忽略它们所传递的指针。 - Jonathan Lefflerchar (*cmds_ptr)(int,*char[])[BUILTIN_FUNC_COUNT-1];
和这个for (int i = 0; i < BUILTIN_FUNC_COUNT; i++) { if (strcmp(cmds_name[i], ...
不是很对应。 - alk