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 ではありません。ただし、非標準の代替手段が 2 つあります。

1。GCC の「ネストされた関数」拡張 (GCC のみ):

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

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

2 つ、Apple のブロック (最近の GCC と Clang):

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

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

「暗黙の配列」は実際には複合リテラルであり、C99 固有です。

一方、匿名関数は標準 C を使用して実現することはできません。GNU GCC を使用する場合は、2 つの拡張機能を使用してそれらを模倣できます。

  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 の拡張機能) が修正するように設計された問題 (または問題の 1 つ) です。OS X 10.5 以降用にコンパイルする場合 (またはclangサポートされている他のプラットフォームで Blocks ランタイムを使用する場合。 makyle/blocksruntimeを参照)、コードを次のように変更できます。

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

そして、次のように呼び出します。

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