web-dev-qa-db-ja.com

引数としての関数ポインター

Cの関数に引数として関数ポインターを渡すことは可能ですか?

もしそうなら、関数ポインタを引数として取る関数をどのように宣言して定義しますか?

39
inquisitive

間違いなく。

void f(void (*a)()) {
    a();
}

void test() {
    printf("hello world\n");
}

int main() {
     f(&test);
     return 0;
}
67
Mehrdad Afshari

機能があるとしましょう

int func(int a, float b);

それへのポインタは

int (*func_pointer)(int, float);

このように使用できるよりも

  func_pointer = func;
  (*func_pointer)(1, 1.0);

  /*below also works*/
  func_pointer(1, 1.0);

必要なたびに完全なポインタタイプを指定しないようにするには、typedef itを使用します。

typedef int (*FUNC_PTR)(int, float);

他のタイプのように使用するよりも

void executor(FUNC_PTR func)
{ 
   func(1, 1.0);
}

int silly_func(int a, float b)
{ 
  //do some stuff
}

main()
{
  FUNC_PTR ptr;
  ptr = silly_func;
  executor(ptr); 
  /* this should also wotk */
  executor(silly_func)
}

世界的に有名な C faqs を見ることをお勧めします。

25
Michal Sznajder

これは良い例です:

int sum(int a, int b)
{
   return a + b;
}

int mul(int a, int b)
{
   return a * b;
}

int div(int a, int b)
{
   return a / b;
}

int mathOp(int (*OpType)(int, int), int a, int b)
{
   return OpType(a, b);
}

int main()
{

   printf("%i,%i", mathOp(sum, 10, 12), mathOp(div, 10, 2));
   return 0;
}
The output is : '22, 5'
10
BattleTested

他の答えで言ったように、次のようにできます

_void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));
_

ただし、関数ポインター型の引数を宣言するための特別なケースが1つあります。引数が関数型を持っている場合、配列がパラメーターリストでポインターに変換されるように、関数型へのポインターに変換されます。次のように書くこともできます

_void qsort(void *base, size_t nmemb, size_t size,
           int compar(const void *, const void *));
_

当然、これはパラメーターのみに適用されます。パラメーターリストの外部int compar(const void *, const void *);は関数を宣言するためです。

2
Antti Haapala

qsort()を確認してください

_void qsort(void *base, size_t nmemb, size_t size,
           int (*compar)(const void *, const void *));
_

関数の最後の引数は関数ポインターです。自分のプログラムでqsort()を呼び出すと、そのポインターを使用して、実行が「ライブラリーに入り」、「独自のコードに戻ります」。

2
pmg