【问题标题】:Nested callback function in CC中的嵌套回调函数
【发布时间】:2020-11-22 23:23:43
【问题描述】:

我已经编写了一些使用回调调用嵌套函数的代码。 但我没有得到预期的输出。

请查看代码:

#include <stdio.h>
#include <stdlib.h>

typedef int (*f_ptr)(int a, int b);
typedef int (*pair_ptr)(f_ptr);

pair_ptr cons(int a, int b)
{

    int pair(f_ptr f)
    {
        return (f)(a, b);
    }
    return pair;
}

int car(pair_ptr fun)
{
    int f(int a, int b)
    {
        return a;
    }
    return fun(f);
}

int main()
{
    int a = 3;
    int b = 4;
    // It should print value of 'a'
    printf("%d", car(cons(a, b)));     // Error : It is printing '0'
    return 0;
}

我也尝试过使用函数指针,但我也得到了与上面相同的输出。

【问题讨论】:

  • pair 尝试使用已不存在的 ab。他们没有被抓到,是吗?
  • C 没有 闭包 的概念,也没有使用它们的工具。您需要以其他方式“修复”ab
  • 请不要将有关 C 的问题标记为 C++。它们不是同一种语言。 (在 C++ 中,这将使用 lambda 或仿函数轻松处理,这两种解决方案都不是在 C 中有效的解决方案。)
  • 一般来说,C语言不允许嵌套函数(虽然gcc确实有这样的扩展)`强烈建议消除函数的“嵌套”

标签: c callback nested-function funcall


【解决方案1】:

试试这个(也许将与闭包相关的函数和变量移动到他们自己的文件中):

#include <stdio.h>

typedef int (*f_ptr)(int a, int b);
typedef int (*pair_ptr)(f_ptr);

static int PairA, PairB;
static void setPairA(int a) { PairA = a; }
static void setPairB(int b) { PairB = b; }

int f(int a, int b) {
    (void)b; // removed unused parameter warning
    return a;
}

int pair(f_ptr fp) {
    return fp(PairA, PairB);
}

pair_ptr cons(int a, int b) {
    setPairA(a);
    setPairB(b);
    return pair;
}

int car(pair_ptr fun) {
    return fun(f);
}

int main(void) {
    int a = 3;
    int b = 4;
    printf("%d\n", car(cons(a, b)));
    return 0;
}

请注意,pair() 是不可重入的,您也不能同时使用 PairA 和/或 PairB 的不同值调用它。

【讨论】:

  • 您的答案运行良好。感谢您的支持。我已经在你的代码中使用了全局变量概念到我的原始代码中,它工作正常。
【解决方案2】:

C 不支持嵌套函数,但 GCC 扩展支持。 docs 说:

如果你试图在包含函数退出后通过它的地址调用嵌套函数,那么一切都会崩溃。

pair 尝试使用已不存在的 ab。 GCC 可能提供嵌套函数,但它们不提供closures。这意味着函数不会捕获ab 的值;这只是cons返回的地址。

【讨论】: