可变参数函数 - C 有点问题



我想实现一个参数数量可变的函数。此函数允许我使用可选参数列表调用另一个函数。该函数的目的是根据某些条件调用任何函数(取决于调用的函数,如果前两个参数相等,我们调用该函数(。我的问题是,可以调用的函数没有相同数量的参数,因此,我不知道每次我有不同的函数时如何传递参数

例如,如果我有这个:

void func(int value_to_compare, int compared_value, int arg_number, char *arg_types, char *function_name, ...)

我可以这样称呼它:

char arg1;
int arg2, arg3;
int condition1;
func(condition1, 1, 1, "c", func1, arg1);
func(condition1, 0, 2, "ci", func2, arg1, arg2);
func(arg2, 0 , 3, "cii", func3, arg1, arg2, arg3);

调用的函数如下所示:

func1(char);
func2(char, int);
func3(char, int, int);

我尝试解释更多,例如:

struct element_list {
char *element_type;
char *element_name;
}
在我的例子中,结构有大量元素,条件必须作为参数传递给函数,条件值取决于上下文,

所以我必须能够在任何上下文中调用'func',我只是给出条件和值,然后一个函数将被调用与相应的参数, 所以它会像

func(element_list.element_type, "CHAR", func1, "s", element_list.element_name);

除此之外,我还有大量的函数和大量的条件,所以我需要一些尽可能通用的东西。

无论你在做什么,现在你都在围绕类型系统工作。在 C 中没有类型安全的方法可以执行您想要的操作。

牢记这一点:

一种可能的解决方案是使所有函数具有相同的类型:typedef void my_func_type(void*)并让每个函数自行"解密"参数。

另一个解决方案是重新考虑您的设计 - 这是我真诚推荐给您的解决方案。但首先你需要多说一点你想在这里实现的目标......一个好的起点是展示您打算如何使用此类功能。很有可能你最终根本不需要这个......


续,#1

据我了解,你会想写这样的func,以至于这段代码

char arg1;
int arg2, arg3;
int condition1;
func(condition1, 1, 1, "c", func1, arg1);
func(condition1, 0, 2, "ci", func2, arg1, arg2);
func(arg2, 0 , 3, "cii", func3, arg1, arg2, arg3);

行为如下:

if (condition1 == 1) func1(arg1);
if (condition1 == 0) func2(arg1, arg2);
if (arg2 == 0)       func3(arg1, arg2, arg3);

坦率 地 说。。。最好的方法是这样写。:-)

既然你问这个问题,你可能想要更复杂的东西。情况是这样的:您希望在代码的控制流上构建一些抽象。这就是函数式编程风格派上用场的地方......事实上,在C++中,事情会很简单(嗯,不是真的微不足道,但可以以类型安全和可移植的方式完成,使用一些模板神奇的奇怪功能,名称中带有bind(。

我们谈论的是 C 而不是 C++,没有模板,没有函子......所以事情可能比这更复杂。但首先要做的是 - 是什么阻止您使用带有 if 的简单解决方案?回答这个问题是一个好的开始。

你有两个选择。 首选方法是通过具有输入类型和为该类型输入定义的各种值的struct传递输入。 然后,您只需将struct传递给函数(通过引用/指针(。

第二个选项是格式化参数,以便您可以使用 va_startva_argva_end 来读取它们。 要使用它,您需要知道下一个 arg 的类型,因此您需要将其作为输入传递。 您还需要提前知道何时到达最后一个参数,因此同样,您需要将其作为输入传递。 这与printf的工作方式相同,以及为什么您需要将格式字符串传递给printf

好的,这是我的做法

void func(int value_type, void *value_to_compare, void *compared_value, char *arg_types, void (*function_name)(), ...)

我根据类型在value_type上切换,在value_to_compare上进行转换,compared_value,将这些值存储在两个不同的联合中,然后比较它们,如果值相等,我调用函数function_name。关于要调用的函数,我根据arg_types进行强制转换,然后我做了一些非常愚蠢的事情,这是一个开关,例如:

switch(strlen(arg_types)) {
case 0:
function_name();
break;
case 1:
function_name(args[0]);
break;
case 2:
function_name(args[0], args[1]);
break;
...
}

其中参数是

void* args[MAX_NUMBER_ARGS];

我采用数组参数的每个元素,并根据arg_types进行强制转换,但我找不到更好的解决方案......

相关内容

  • 没有找到相关文章

最新更新