【问题标题】:Pointer to function with some, but not all arguments fixed指向函数的指针,但不是所有参数都固定
【发布时间】:2018-02-16 13:36:50
【问题描述】:

我想使用数值接收书中的布伦特方法来最小化一个函数。最小化例程的签名基本上如下所示:

float brent(float (*f)(float), float *xmin, "other parameters not relevant to question")

你可以猜到brent 返回f 的最小值并将其参数存储在xmin 中。 但是,我要最小化的函数的确切形式取决于附加参数。说

float minimize_me(float x, float a, float b)

一旦我决定了ab 的值,我想相对于x 将其最小化。

我可以简单地为所有调用的函数添加额外的参数,一直到brent,从而将其签名更改为

float brent(float (*f)(float,float,float),float a ,float b , float *xmin, ...)

因此每次都在brent 内调用(*f)(x,a,b)。然而,这对我来说似乎不是很优雅,因为我现在不仅要传递指向 minimize_me 的指针,还要传递整个函数链中的两个附加参数。

我怀疑可能有更优雅的解决方案,例如创建一个指向函数版本的指针,其中 ab 作为固定值。

即使它是一个非常晦涩难懂的解决方案,也请不要对我隐瞒,因为我觉得它可以提高我对语言的整体理解。

【问题讨论】:

  • 也许您正在寻找这个? stackoverflow.com/questions/7308449/…
  • 你可以考虑用你的参数创建一个结构体并将它的指针传递给函数
  • @Nefrin 类似typedef struct { float a; float b; float (*f)(double,double,double) } f_ab;?我做对了吗?我还不太习惯c。
  • 是的@cmmnn,然后您可以使用f_ab myAB 创建一个实例并设置其值并将其指针传递给function(&myAB)function(void* param),然后将其转换回f_ab 类型。此方法允许将具有任意内容的结构传递给具有单个参数的函数
  • 好的,我会在答案中巩固这一点

标签: c function-pointers


【解决方案1】:

实现这一点的一种可行方法是使用结构来存储所有值并将指向该值的指针传递给函数。

struct parameters{
    int valueA;
    int valueB;
};

int function(void* params){
    parameters* data = (parameters*) params;
    return data->valueA + data->valueB; // just an example
}

int main(){
    parameters myData;
    myData.valueA = 4;
    myData.valueB = 2;
    function(&myData);
    return 0;
}

【讨论】:

  • 不错的答案 +1...我想问你一件小事..强制转换?只是问问。
  • void* params 不是类型安全的。最好使用参数类型struct parameters * params
  • 是的,强制转换。否则编译器不知道结构有多大以及它包含什么值。 (虽然你可以自己做指针算术)
  • 另外,小挑剔:(parameters*) 不会编译,因为只有类型 struct parameters 存在。甚至不需要强制转换,因为void* 可以隐式转换为任何其他对象指针类型。编译器不需要知道指向结构的大小。
  • 我发现使用指向结构的指针的想法在很多方面都非常有用,但遗憾的是没有得到充分利用。不错的答案!
【解决方案2】:

你需要的是currying,比如:

给定一个由三个变量f(x,y,z)和两个值ab,构造一个变量的函数g,使得g(z)=f(a,b,z)

唉,C语言可不能让你柯里化。这种结构仅适用于函数式语言,而 C 不是。这并不意味着你真的做不到,但语言中没有给定的结构。所以需要自己重构机制。有关示例,请参见 Currying/binding with ISO C99Is there a way to do currying in C?

【讨论】:

  • Jean nice answer(+1) 但你介意单行解释柯里化...很多人都懒得从答案中打开链接。 (或者很多可能不是一个常见的话题)。
  • 我不得不在 C 中做这样的事情,但从来不知道有这么好的发展和形式化的想法存在,甚至被命名。
  • @ryyker 很好,CS 是...一门科学。因此,该领域存在很多定理等。
  • @Jean-BaptisteYunès - 哈哈,是的,我想是的。作为一个没有在该领域接受过正式教育的人,我担心我错过了一些非常酷的东西。然而,这个事实也意味着当我在这里遇到这些很酷的东西时,我非常感激。 :)
【解决方案3】:

GCC 的本地函数扩展使用起来非常有趣(使用 -std=gnu11):

float brent(float (*f)(float), float *xmin);

float minimize_me(float x, float a, float b);

int main() {
   ...
   float min_me_local(float x) { return minimize_me(x, 1, 2); }
   brent(min_me_local, xmin);
   ...
}

我希望它是标准的,但事实并非如此。因此,在针对可移植性时,更喜欢@Nefrin 的回答。

【讨论】:

    猜你喜欢
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多