C言語関数ポインタまとめ(2)---コールバック関数


次の編に続きます:C言語関数ポインタまとめ(1)プログラマーはしばしばコールバックを実現する必要があります.本稿では,関数ポインタの基本原則を議論し,関数ポインタを用いてコールバックを実現する方法を説明する.ここでは一般的な関数について注意してください.コールバック関数は、プログラマが明示的に呼び出すことができない関数であり、コールバック関数のアドレスを呼び出し者に渡すことで呼び出しを実現します.コールバックを実現するには、まず関数ポインタを定義する必要があります.定義された構文は少し不思議ですが、関数宣言の一般的な方法を熟知している場合は、関数ポインタの宣言が関数宣言と非常に似ていることがわかります.コールバック関数の使用は、統合インタフェースを介して異なるコンテンツを実現したい場合に必要である場合があります.この場合、コールバック関数を使用するのは適切です.例えば、いくつかの異なるデバイスに対してそれぞれ異なる表示関数を書きました:void TVshow();void ComputerShow(); void NoteBookShow()...など.これは統一的な表示関数を使いたいので、コールバック関数を使うことができます.void show(void (*ptr)()); 使用時に、入力されたパラメータに応じて異なるコールバック関数が呼び出されます.プログラミング言語によって文法が異なる場合があります.次の例を見てください.
#include <stdlib.h> 
#include <stdio.h> 
int Test1() 
{ 
  int i; 
  for (i=0; i<30; i++) 
  { 
    printf("The %d th charactor is: %c
", i, (char)('a' + i%26)); } return 0; } int Test2(int num) { int i; for (i=0; i<num; i++) { printf("The %d th charactor is: %c
", i, (char)('a' + i%26)); } return 0; } void Caller1(void (*ptr)())// { (*ptr)(); } void Caller2(int n, int (*ptr)())// , { // void Caller2(int (*ptr)(int n)), 。 (*ptr)(n); return; } int main() { printf("************************
"); Caller1(Test1); // Test2(); printf("&&&&&&************************
"); Caller2(30, Test2); // Test2(30); return 0; }

以上、コールバック関数のアドレスをコールバック者に渡すことによって呼び出しが実現されたが、参照付きコールバック関数の使い方に注意が必要である.コールバックを実現するには、まず関数ポインタを定義する必要があります.
 
C言語の標準ライブラリ関数では,コールバック関数を用いてユーザに処理プロセスをカスタマイズさせることが多い.一般的なクイックソート関数、二分検索関数などです.クイックソート関数のプロトタイプ:
void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
        :
void *bsearch(const void *key, const void *base, size_t nelem,
				 size_t width, int (_USERENTRY *fcmp)(const void *, const void *));

fcmpはコールバック関数の変数です.次に、具体的な例を示します.
#include <stdio.h>
#include <stdlib.h>

int sort_function( const void *a, const void *b);
int list[5] = { 54, 21, 11, 67, 22 };

int main(void)
{
   int  x;

   qsort((void *)list, 5, sizeof(list[0]), sort_function);
   for (x = 0; x < 5; x++)
      printf("%i
", list[x]); return 0; } int sort_function( const void *a, const void *b) { return *(int*)a-*(int*)b; }