C 语言是一种静态类型语言。它不具备其他语言所具备的运行时反射功能。它也不提供从运行时提供的类型构建任意函数调用的方法。您需要有一些方法来了解函数签名is_odd
是什么,它接受多少个参数以及这些参数的类型是什么。它甚至不知道它何时到达 ... 参数列表的末尾;你需要一个明确的终结者。
enum function_signature {
returns_bool_accepts_int,
returns_bool_accepts_float,
returns_bool_accepts_int_int,
};
typedef bool (*function_returning_bool_accepting_int)(int);
typedef int (*function_generates_int)();
void for_all(function_signature signature, ...)
{
va_list ap;
va_start(ap, signature);
switch (function_signature)
{
case returns_bool_accepts_int:
{
function_returning_bool_accepting_int fn = va_arg(ap, function_returning_bool_accepting_int);
function_generates_int generator;
do {
generator = va_arg(ap, function_generates_int);
if (generator) fn(generator());
} while (generator);
}
break;
... etc ...
}
}
您的问题是 QuickCheck 旨在利用 JavaScript 的高动态可编程性,这是 C 语言所缺少的。
更新如果您允许任意函数签名,那么您需要一种使其再次成为静态的方法,例如,通过让调用者提供适当的适配器。
typedef void (*function_pointer)();
typedef bool (*function_applicator)(function_pointer, function_pointer);
void for_all(function_applicator apply, ...)
{
va_list ap;
va_start(ap, apply);
function_pointer target = va_arg(ap, function_pointer);
function_pointer generator;
do {
generator = va_arg(ap, function_pointer);
if (generator) apply(target, generator);
} while (generator);
}
// sample caller
typedef bool (*function_returning_bool_accepting_int)(int);
typedef int (*function_returning_int)();
bool apply_one_int(function_pointer target_, function_pointer generator_)
{
function_returning_bool_accepting_int target = (function_returning_bool_accepting_int)target_;
function_returning_int generator = (function_returning_int)generator_;
return target(generator());
}
for_all(apply_one_int, is_odd, generated_values1, generated_values2, (function_pointer)0);
}