1

我是这个社区的新手,我想问一个问题。我不是程序员/开发人员,但我使用编程来加速我的科学计算。过去我使用了很多 python,但现在因为我的新工作,我需要使用 C 编程语言。我是新手,这有点困难,但我很挣扎:D。我的主要问题是,如何完成从 python 到 C 的这种代码:

def foo(x,a):
    def en(x):
        return a*x
    return en

我用它来获得动态最终方程,我可以为很多不同的例子编写我的求解器。基本上我想在 C 中做同样的事情。因为 ansi C 不支持嵌套函数,所以我不能用 typdefs 得到它,或者只是不知道该怎么做。我已经搜索了很多答案,但我没有找到它。

提前致谢。PS对不起我的英语不好,如果是:D

编辑:我忘记在我尝试做同样事情的地方添加我的示例代码:D 但我收到错误,因为 ansi C 不支持嵌套函数

double fun(double x, double a){
return a*x-5;
}
double n(double x);
typedef double (*function)(double);
function wrapper(double x, double a){
    function ptr;
    double functionReturn(double x){
        return fun(a,x);
    }
    ptr = functionReturn;
    return ptr;
}
4

1 回答 1

0

如前所述,您不能在 C 中动态生成函数。因此,您的方法需要完全不同,您如何调整它取决于您要完成的细节。我将展示两种可能替换函数返回函数行为的方法。

方法 1:如果您一次只需要使用 1 个返回函数。

通常,如果您正在动态计算函数,则从给定函数返回的函数将彼此非常相似。您可以使用静态数据存储来获得此效果,假设您一次只需要一个有效的返回函数。

static double fun_a;

double fun( double x )
{
   return fun_a*x - 5;
}

void wrapper( double a )
{
   fun_a = a;
}

在您的示例中,您有一个 2 参数函数 'fun',并且您想要一个函数返回由修复一个参数给出的乐趣切片给出的函数。当您调用 'wrapper(a)' 时,'fun' 本质上会发生变化,因此调用 'fun(x)' 与调用 'fun(x,a)' 相同(将第二个参数 'a' 与静态变量 '乐趣_a')。

基本上,“包装器”不是返回一个函数,而是将现有函数更改为它应该返回的(实际上并不返回任何东西)。所以你得到了同样的效果,你一次只能使用一个回报。

如果您花点时间考虑一下要计算函数的情况,您可能会发现定义一个使用全局变量的函数并通过修改这些全局变量来获得所需的函数几乎总是相当简单的。

请注意,全局变量可以从程序的其他部分访问,请注意如何命名它们以避免它们被其他地方弄乱。如果我有一个函数 'fun' 并且我定义了一些全局的东西来配合它,我通常将它命名为 'fun_[something]',这样就很容易避免这样的问题。

最后,如果您对一次需要使用多少个函数有任何小的固定限制,您可以通过执行以下操作来实现您的目标:

static double fun1_a;

double fun1( double x )
{
   return a*x - 5;
}

void wrapper1( double a )
{
   fun1_a = a;
}



static double fun2_a;

double fun2( double x )
{
   return a*x - 5;
}

void wrapper2( double a )
{
   fun2_a = a;
}

.
.
.

方法 2:使用 typedef

您提供的示例非常简单,我猜是因为您的情况太复杂,无法在实际情况下提出这个问题。第二种方法需要更复杂的示例才能有意义。

假设您有一个函数 E(x,m),它计算 x 和 m 共有多少个素因数。这是一个可能非常昂贵的函数,因此您可能想要计算一个函数 F_k(m) 来计算 k 和 m 共有多少个素因子,因为这将是一个快得多的函数。请注意,E 采用变量 x,而 k 对于 F_k 是固定的,因此这些函数具有不同的作用。

这只是一个任意示例,用于演示在比简单地获取更高元数函数的切片更复杂的情况下执行此类操作的技术。

您可以执行以下操作:

typedef long long unsigned llu;
typedef llu* F_type;

int fun( F_type L, llu m )
{
   int i, j=0;
   for(i=0; L[i]; ++i)
      if( m % L[i] == 0 ) ++j;
   return j;
}

F_type wrapper( llu k )
{
   // code that returns an array listing the primes dividing k, followed by 0
}

因此,您可以简单地调用 wrapper(k),将结果设置为 L,然后调用 fun(L,m),而不是调用某个为给定 k 返回 F_k 的函数。然后 L 充当函数 F_k 的角色,本质上是将 fun 转换为 F_k。

这种方法的优点是任何数量的此类类型都可以在给定时刻在程序中处于活动状态。

您的问题的真正答案是,您只需要重组您的方法以使用可以在执行期间构建的数据类型。我希望这两个示例可以帮助说明在 C 中执行此操作的一些方法。

于 2016-03-25T08:32:17.177 回答