751

一連のデータに対してパラメーターによって渡される関数を実行する関数を作成したいと考えています。Cで関数をパラメーターとしてどのように渡しますか?

4

9 に答える 9

893

宣言

関数パラメーターを取る関数のプロトタイプは次のようになります。

void func ( void (*f)(int) );

これは、パラメーターが戻り値の型を持ち、単一のパラメーターを取るf関数へのポインターになることを示しています。次の関数 ( ) は、適切な型であるため、パラメーターとして渡すことができる関数の例です。voidintprintfunc

void print ( int x ) {
  printf("%d\n", x);
}

関数呼び出し

関数パラメーターを指定して関数を呼び出す場合、渡される値は関数へのポインターである必要があります。これには関数の名前 (括弧なし) を使用します。

func(print);

を呼び出しfunc、それに print 関数を渡します。

関数本体

他のパラメーターと同様funcに、関数本体でパラメーターの名前を使用して、パラメーターの値にアクセスできるようになりました。func渡された関数を0〜4の数字に適用するとしましょう。最初に、print を直接呼び出す場合のループを考えてみましょう。

for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
  print(ctr);
}

funcのパラメータ宣言は、 が目的の関数へのポインタの名前であると述べているため、最初に、がポインタである場合は が指すもの(つまり、この場合は関数) でfあることを思い出してください。その結果、上記のループ内のすべての print を次のように置き換えます。f*ffprint*f

void func ( void (*f)(int) ) {
  for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
    (*f)(ctr);
  }
}

ソース

于 2008-08-13T02:22:24.007 に答える
152

この質問には、関数ポインターを定義するための答えが既にありますが、特にアプリケーションでポインターを渡す場合は、非常に面倒になる可能性があります。この不快感を避けるために、関数ポインターをより読みやすいものに型定義することをお勧めします。例えば。

typedef void (*functiontype)();

void を返し、引数を取らない関数を宣言します。この型への関数ポインタを作成するには、次のようにします。

void dosomething() { }

functiontype func = &dosomething;
func();

int を返し、char を取る関数の場合は、次のようにします。

typedef int (*functiontype2)(char);

そしてそれを使用する

int dosomethingwithchar(char a) { return 1; }

functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

関数ポインタを読みやすい型に変換するのに役立つライブラリがあります。ブースト関数ライブラリは素晴らしく、努力する価値があります!

boost::function<int (char a)> functiontype2;

上記よりもずっといいです。

于 2008-08-13T02:34:47.850 に答える
41

以下に示すように、関数のアドレスをパラメーターとして別の関数に渡します

#include <stdio.h>

void print();
void execute(void());

int main()
{
    execute(print); // sends address of print
    return 0;
}

void print()
{
    printf("Hello!");
}

void execute(void f()) // receive address of print
{
    f();
}

また、関数ポインタを使用して関数をパラメータとして渡すこともできます

#include <stdio.h>

void print();
void execute(void (*f)());

int main()
{
    execute(&print); // sends address of print
    return 0;
}

void print()
{
    printf("Hello!");
}

void execute(void (*f)()) // receive address of print
{
    f();
}
于 2015-11-23T12:07:40.563 に答える
4

関数ポインタを渡す必要があります。構文は少し面倒ですが、慣れると非常に強力です。

于 2008-08-13T02:18:28.163 に答える
0
typedef int function();

function *g(function *f)
{
    f();
    return f;
}

int main(void)
{
    function f;

    function *fn = g(f);

    fn();
}

int f() { return 0; }
于 2021-09-23T14:29:50.047 に答える
-4

これは実際には関数ではありませんが、ローカライズされたコードです。もちろん、結果だけをコードに渡すわけではありません。後で実行するためにイベント ディスパッチャに渡された場合は機能しません (イベントの発生時ではなく、現在計算されているため)。ただし、コードを 1 か所にローカライズするだけであれば、コードを 1 か所にローカライズできます。

#include <stdio.h>

int IncMultInt(int a, int b)
{
    a++;
    return a * b;
}

int main(int argc, char *argv[])

{
    int a = 5;
    int b = 7;

    printf("%d * %d = %d\n", a, b, IncMultInt(a, b));

    b = 9;

    // Create some local code with it's own local variable
    printf("%d * %d = %d\n", a, b,  ( { int _a = a+1; _a * b; } ) );

    return 0;
}
于 2019-03-15T02:46:46.043 に答える