0

関数のコールバックは、次のような別の関数の呼び出しに別の関数ポインターを埋め込んでいることを知っています。

関数宣言:

function_call_back(int x, int y, void (*functonPtr)(int x, char y , struct newStruct* sptr))


void func(int x , char y , struct newStruct* sptr1)
{
    //perform Algorithm 1 on x,y ,sptr1
}

void func2(int x , char y , struct newStruct* sptr2)
{
    //perform Algorithm 1 on x,y ,sptr2
}


void func3(int x , char y , struct newStruct* sptr3)
{
    //perform Algorithm 1 on x,y ,sptr3
}

void func4(int x , char y , struct newStruct* sptr4)
{
    //perform Algorithm 1 on x,y ,sptr4
}

main()
{
    // function calling 
    function_call_back(23, 2256, func1);
}

func関数名は関数ポインタと同等であるため、ここで3番目の引数はです。

function_call_backを呼び出す前に、上記のメインにこの行を追加することfuncで、同様の関数シグネチャのさまざまなバリエーションでここを変更できることに同意します。

 typedef void (*fptr)(int int x , char y , struct newStruct* ptr);

  fptr f1 = func2; // or func3, or func4

  function_call_back(23, 2256, f1);

3番目の引数はfunc、関数名と同じですが、次の呼び出しに関数呼び出しコードを追加するだけで、以下の方法でも実現できるのではないかと思いましたfunction_call_back

function_call_back(23, 2256, functionCallingcode); //third argument is func 

の新しい宣言function_call_backは次のとおりです。

function_call_back(int x, int y, int functionCallingCode)

そして、その新しい定義は次のとおりです。

void function_call_back(int x, int y, int functionCallingCode)
{
switch(functionCallingCode)
case 1:
func1(1,"g",sptr1);
break;

case 2:
func2(1,"c",sptr2);

break

case 3:
func3(1,"d",sptr3);
break;

case 4 : 
func4(1,"s",sptr4);
break ;

default : 
 printf("Wrong Function calling code");

}
}

では、なぜ関数ポインタを使うのでしょうか?

4

3 に答える 3

3

彼らは良くはありません、彼らはあなたが持っている実質的に唯一の選択肢です。

この切り替えは可能ですが、同じアプローチで、プログラム全体を1つの関数で記述できます。関数はコードユニットを分離するためにあり、この「スイッチ関数」は単に多くのものをユニット化します。

于 2012-05-06T13:52:09.793 に答える
3

switchステートメントを使用すると、コールバック関数にコーディングすることを選択したすべての関数を呼び出すことができます。既知の関数のコレクションの1つだけを呼び出すことができることが保証されています。

関数ポインタを使用すると、開発の後で完全に無関係なポイントで定義する可能性のある任意の関数を呼び出すことができます。シグニチャが一致するコールバック関数を自由に定義して使用できます。

言い換えると、スイッチを使用すると、制限された選択肢のセット間で分岐できますが、関数ポインターを使用すると、制限のない柔軟性が得られます。通常、関数ポインタよりも他のものを好む理由はほとんどありません。

于 2012-05-06T14:31:15.350 に答える
2

説明する場合、関数ポインタを使用しなくても、必要な機能を明確に取得できます。

ただし、数週間以内にfunc5のオプションを追加したい場合はどうなるかを検討してください。そして、時間が経つにつれて、func6、func7、...、func10、func20を追加したいと思います。function_call_back()は大きくなり、乱雑になりますが、関数ポインターバージョンでは、function_call_back()をまったく編集しなくても、必要な数の異なる関数を追加できます。

関数ポインタの実装により、function_call_back()をライブラリの一部としてパーセル化する柔軟性も得られます。このライブラリは、ソースコードをいじったり、持ったりすることなく、別のプログラムで使用できます。これが本当に便利な理由の例については、標準ライブラリのqsort関数を参照してください。

于 2012-05-06T14:18:07.877 に答える