用n个参数运行函数

时间:2013-02-15 07:20:37

标签: c function undefined

我需要在处女ANSI C(1989)中解决一个问题。

我有一些指针(void * func)用于(int n)双参数,并且数组double values[]带有n个数字。所以我想用n param运行我的函数,它位于value中。

例如,我有功能:

double hypotenuse(double x, double y, double z);

所以

void *func = (void *)hypotenuse; double values[3] = {5, 4, 3}; int n = 3;

我想做这样的事情:

func(n, values);

问题是我无法改变功能的原型, 所以我需要以某种方式这样做(也许是一些宏?)。

2 个答案:

答案 0 :(得分:4)

主要问题是你必须根据参数的数量(即取决于n变量)对指针进行不同的投射。

一种方法是使用包含switch语句的包装函数作为参数号:

double wrapper(void *func, double args[], int n)
{
    switch (n)
    {
    case 0:
        return ((double (*)(void)) func)();
    case 1:
        return ((double (*)(double)) func)(args[0]);
    case 2:
        return ((double (*)(double, double)) func)(args[0], args[1]);
    case 3:
        return ((double (*)(double, double, double)) func)(args[0], args[1], args[2]);
    default:
        printf("Error: wrapper called with %d arguments\n", n)
        break;
    }

    return 0.0;
}

答案 1 :(得分:2)

昨晚写的很晚 - 但是当我尝试发布时,我的互联网连接失败了。我看到约阿希姆写的答案基本相同。


在限制范围内,这将有效:

#include <assert.h>

extern double function_invoker(void *func, int n, double *values);

double function_invoker(void *func, int n, double *values)
{
    switch (n)
    {
    case 0:
        return (*(double (*)(void))func)();
    case 1:
        return (*(double (*)(double))func)(values[0]);
    case 2:
        return (*(double (*)(double, double))func)(values[0], values[1]);
    case 3:
        return (*(double (*)(double, double, double))func)(values[0], values[1], values[2]);
    default:
        assert("Need more entries in the switch in function_invoker()" == 0);
        return(0.0);
    }
}

明显的限制是您要在switch中输入多少条目。我已经看到松散类似的代码超过100个参数;我不确定为什么认为这是必要的。

该代码在Mac OS X 10.8.2的GCC 4.6.0下编译时没有警告:

$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -c x.c
$

但如果你选择double (*)()代替void *,你会得到:

$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -c x.c
x.c:3:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
x.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
$