転送:C言語のコールバック関数(コールバック関数) の記事C言語のコールバック関数を知ってもらうために
まず、コールバック関数の定義と使用シナリオ
コールバック関数が他の関数によって、実行時に呼び出すために、他の関数へのパラメータとして関数(エントリアドレス)次に、関数ポインタを介して呼び出されます。コールバック関数は、ユーザー自身によって実装されます。単にあなたが達成コールバック関数中に関数に他の人が、入れて実行します。
この設計は、(図1-1に示すように)定義されたハイレベルのコードサブルーチンコールを可能にします。主にコールバック関数ポインタ方法を介して、C言語の関数。
図1-1
コールバックの広い範囲を使用します。
例えば、その機能のオプションに対応するコンテンツファイルによって提供される構成ファイルを読み取ることである関数があると仮定する。これらのオプション場合ハッシュ値タグ(ハッシュ関数)には、次にせコールバック関数は、プログラムがより柔軟になり、設計を受け入れ:所望のハッシュアルゴリズムの呼び出し元の関数を使用することができ、アルゴリズムは、オプションに名前から成り実現コールバック関数のハッシュ値であるため、コールバック関数は、実行時の動作における発呼者の本来の機能を調整することができます。
別の用途は、コールバックということであるプロセスがセマフォ。例えば、POSIXのプログラムが受け取ることができるSIGTERMをすぐに信号を終端する必要はありません。すべてがうまく機能していることを確認するために、プログラムはコールバックを対応するクリーンアップ機能SIGTERMシグナルを登録することができます。
コールバックは、制御に使用することができるかどうかなどの機能:Xlibには、あなたが特定のイベントに対処するかどうかを判断するために使用されるカスタム述語(NSPredicate)手続きすることができます。
書式#include <iostreamの> の#include < 文字列 > 使用して 名前空間はstdを、 typedefのボイド(* FP)(CHAR * S); // 構造体は、関数ポインタで表される 空隙 F1(CHAR * S){COUT << S;} ボイド F2(CHAR * S){COUT << S;} ボイド F3(CHAR * S){COUT << S;} INTメイン(int型 ARGC、CHAR * ARGV []) { INT funcselector = 0 ; // 実行される制御する整数関数の定義 ボイド * [] = {F1、F2、F3}; //は、ポインタ配列を定義する、一般的にポインタがある A [ 0 ](" こんにちは\ N-!"); // コンパイルエラー、ポインタ配列は、通話機能を受けることができない、実施 FP F [] = {F1、F2、F3を}; //は、fは関数ポインタの配列を定義します関数ポインタ / * funselectorのハンドル* / // ここfunselectorを処理するために、制御機能を実行する F [funselector](「Hello Worldの\ N-!」); // 正しい、関数ポインタの配列は、標準的な操作機能で行うことができます間接呼び出し リターン 0 ; }
例について、コールバック関数の上述の効果の一部です。ここでF1、F2、F3(図示:平均出力が、最小出力を達成F3最大出力、F2用具を達成F1)は、3つの異なる機能の関数を表します。コールバック関数の利点のいくつかを要約すると:
Funcselectorマーカーとして使用量、容易に実行されるべき機能を選択し、ステップ関数の制御フロー。
F1、F2、F3モジュール式の3つの特定の機能が大幅に変更し、維持するためにデザイナーを支援します。図1-1に示すように、多くのソフトウェア・ライブラリ・システムは完全に開発者は、コールバック関数を介して関数に機能を変更することができるようにカプセル化されます。
より明確に思考解析機能、コールバック関数のlwIPの広範な使用は、開発者がシステムの構成は、コールバック関数に従った処理を呼び出して分析することができます。
第二に、構造解析
メイン関数、および関数呼び出しと呼ばれる関数(図1-1):三つの部分の主なコールバック構造。C、形態の(関数に対応するエントリのアドレスを指す)と呼ばれる関数一般関数ポインタ。
ここでは、簡単なコールバック構造であり、かつデータ構造を分析します。
// コールバック関数を定義 無効)(PrintfTextを { printf(" Hello Worldの\ nは!" ); } // コールバック関数の実装を定義する「機能を呼び出す」 無効 CallPrintfText(無効 *( )()callfuct) { callfuct(); } // コールバック関数実装 INTがメイン(INT ARGC、CHAR * ARGV []) { CallPrintfText(PrintfText)。 リターン 0 ; }
(ボイド)コール転送機能ボイド(* callfuct)この関数は、空隙callfuct(ボイド)関数アドレスへのエントリである、即ち、ポインタはPC空隙callfuct(ボイド)を実施することができるアレイをアドレス指定するために移動させることにより、この機能は、同様にしてあってもよいです理解。
関数呼び出しを実装し、機能は、さらに、コールがあった中で、「コール機能」、呼び出す「呼び出し元の関数を。」メイン関数直接呼び出し「と呼ばれる機能」に比べて、この方法は、ユーザではなく、開発者のための柔軟なインタフェースを提供します。また、変数セットのような入り口缶機能は、開発者のための柔軟性を提供します。
実施例2:信号関数
信号の宣言:
無効(*信号(int型 SIG、無効(* FUNC)(int型)))(int型)
書式#include <stdio.hに> する#include <signal.hに> / * 信号処理機能をキャプチャする* / ボイド handlefunc(int型SIG){//コールバック もし(SIGINT == {SIG) printf(" GOT SIGINT信号\ n " ); } 他{ printf(" GOT SIGHUP信号\ n " ); } } INT メイン(){ //関数を呼び出します 信号(SIGINT、handlefunc); // はCtrl + C信号 信号(SIGHUP、handlefunc); // 終端信号 一方、(1 ){ 睡眠(1 )。 } }
要約:
コールバック関数は、呼び出し元が実行時の動作に本来の機能を調整することができます。
ダイレクトコール機能の主な機能に関して、コールバック関数は、着信通話機能などの変数は、同じ、柔軟なユーザインタフェースは、パフォーマンス関数入口(パラメータパッシング)に設定することができる提供します。