一連のデータに対してパラメーターによって渡される関数を実行する関数を作成したいと考えています。Cで関数をパラメーターとしてどのように渡しますか?
9 に答える
宣言
関数パラメーターを取る関数のプロトタイプは次のようになります。
void func ( void (*f)(int) );
これは、パラメーターが戻り値の型を持ち、単一のパラメーターを取るf
関数へのポインターになることを示しています。次の関数 ( ) は、適切な型であるため、パラメーターとして渡すことができる関数の例です。void
int
print
func
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
*f
f
print
*f
void func ( void (*f)(int) ) {
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
(*f)(ctr);
}
}
この質問には、関数ポインターを定義するための答えが既にありますが、特にアプリケーションでポインターを渡す場合は、非常に面倒になる可能性があります。この不快感を避けるために、関数ポインターをより読みやすいものに型定義することをお勧めします。例えば。
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;
上記よりもずっといいです。
以下に示すように、関数のアドレスをパラメーターとして別の関数に渡します
#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();
}
関数ポインタを渡す必要があります。構文は少し面倒ですが、慣れると非常に強力です。
typedef int function();
function *g(function *f)
{
f();
return f;
}
int main(void)
{
function f;
function *fn = g(f);
fn();
}
int f() { return 0; }
これは実際には関数ではありませんが、ローカライズされたコードです。もちろん、結果だけをコードに渡すわけではありません。後で実行するためにイベント ディスパッチャに渡された場合は機能しません (イベントの発生時ではなく、現在計算されているため)。ただし、コードを 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;
}