2

最近我发现可以通过在函数调用中强制转换来将隐式数组传递给函数

void foo(int* array);
foo((int[4]) {1,2,3,4});

但是,我想知道在将函数指针传递给函数时是否可以做同样的事情,比如:

void bar(void (*foobar)(void));
bar((void) {printf("foobar\n");});

那么有可能做到这一点吗?

我想知道的原因是,如果我有一大块代码可能具有一定的循环结构,但核心功能在实例之间发生变化,我不想为了传递而用多个临时函数乱扔代码他们到另一个功能。因此希望能够在参数中定义临时函数。

非常感谢

4

3 回答 3

5

不,不在标准 C 中。不过,您有两种非标准替代方案:

一。GCC 的“嵌套函数”扩展(仅限 GCC):

void call(void (*fn)())
{
    fn();
}

void somefunc()
{
    void tmp_func()
    {
        printf("Hello world!\n");
    }
    call(tmp_func);
}

二、Apple的blocks(最近的GCC和Clang):

void call(void (^blk)())
{
    blk();
}

call(^{
    printf("Hello world!\n");
});
于 2013-02-23T19:37:40.150 回答
1

“隐式数组”实际上是一个复合文字,它是 C99 特定的。

另一方面,使用标准 C 无法实现匿名功能。如果您使用 GNU GCC,则可以使用两个扩展来模仿它们:

  1. 嵌套函数
  2. 语句表达式

首先创建一个包装宏:

#define lambda(return_type, body)     \
({                                    \
    return_type lambda_function body; \
    lambda_function;                  \
})

然后你可以像这样使用它

bar(lambda(void, (void)
    {
        printf("foobar\n");
    })
);
于 2013-02-23T20:02:00.527 回答
0

您正在寻找的功能不是 C 标准的一部分。然而,这正是阻塞(Apple 对该标准的扩展)旨在解决的问题(或问题之一)。如果您正在为 OS X 10.5 或更高版本进行编译(或clang在其他受支持的平台上使用 Blocks 运行时;请参阅mackyle/blocksruntime),您可以将代码更改为如下所示:

void bar(void (^foobar)(void));

并像这样调用:

bar(^{
    printf("foobar\n");
});
于 2013-02-23T19:38:46.340 回答