「C言語の基礎 - 関数ポインタ」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
(Wiki がページ「関数ポインタ」を「C言語の基礎 - 関数ポインタ」に、リダイレクトを残さずに移動しました)
(文字列「<source」を「<syntaxhighlight」に置換)
11行目: 11行目:
型 (*変数名)(仮引数)<br>
型 (*変数名)(仮引数)<br>
<br>
<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  #include <stdio.h>
  #include <stdio.h>
   
   
50行目: 50行目:
<br>
<br>
ちなみに、以下のように宣言して配列として使うこともできる。<br>
ちなみに、以下のように宣言して配列として使うこともできる。<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  int main(int argc, char *argv[])
  int main(int argc, char *argv[])
  {
  {
69行目: 69行目:
== コールバック関数を使用する ==
== コールバック関数を使用する ==
下記のように、コールバック関数として使用することができる。<br>
下記のように、コールバック関数として使用することができる。<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  #include<stdio.h>
  #include<stdio.h>
   
   
112行目: 112行目:
== typedefを使用する(C++11以降) ==
== typedefを使用する(C++11以降) ==
C++11以降の場合、typedefを使用することを推奨する。<br>
C++11以降の場合、typedefを使用することを推奨する。<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  // C++98, C++03の記述
  // C++98, C++03の記述
  typedef void (*pfunc)(int, char);
  typedef void (*pfunc)(int, char);

2021年11月16日 (火) 17:22時点における版

概要

ポインタの参照先を関数にすると、そのポインタが指し示す関数を呼び出すことができる。
ポインタに格納する関数のアドレスを変えることで、呼び出す関数を動的に変更することが可能となる。


関数ポインタの使用方法

関数ポインタは、アドレスを格納する関数と同じ戻り値の型を使って宣言する。
関数ポインタの仮引数の型と、ポインタに格納する関数の型は一致させる必要がある。

関数ポインタを使う時は、下記のようにポインタ名に()を付けて使用する。
型 (*変数名)(仮引数)

<syntaxhighlight lang="c++">
#include <stdio.h>

int addition(int x, int y);
int subtraction(int x, int y);

int main(int argc, char *argv[])
{
   int answer = 0;
   int (*pFunc)(int, int);

   pFunc = addition;
   answer = (*pFunc)(5, 3);
   printf("a + b = %d\n", answer);

   pFunc = subtraction;
   answer = (*funcp)(10, 7);
   printf("a - b = %d\n", answer);

   return 0;
}

int addition(int x, int y)
{
   return x + y;
}

int subtraction(int x, int y)
{
   return (x - y);
}
</source>

1度目の関数呼び出し時は、pFuncに関数additionのアドレスが格納されており、
2度目の関数呼び出し時は、関数subtractionのアドレスが格納される。
このようにして、ポインタに関数のアドレスを格納することで、呼び出す関数を変更することができる。

関数ポインタの仮引数は、仮引数の型だけを入れて宣言すればよい。

ちなみに、以下のように宣言して配列として使うこともできる。

<syntaxhighlight lang="c++">
int main(int argc, char *argv[])
{
   int answer;
   int (*pFunc[])(int, int) = { addition, subtraction };

   answer = (*pFunc[0])(5, 3);
   printf("a + b = %d\n", answer);

   answer = (*pFunc[1])(10, 8);
   printf("a - b = %d\n", answer);

   return 0;
}
</source>



コールバック関数を使用する

下記のように、コールバック関数として使用することができる。

<syntaxhighlight lang="c++">
#include<stdio.h>

typedef void (* PFUNC)(char *);

void printText1(char *s);  // 文字列をそのまま出力
void printText2(char *s);  // 文字列を""で囲んで出力
void exec(char *s, PFUNC p);

int main(int argc, char *argv[])
{
   PFUNC pFunc;

   pFunc = printText1;
   exec("ぷりんとてきすと1", pFunc);

   pFunc = printText2;
   exec("ぷりんとてきすと2", pFunc);

   return 0;
}

void printText1(char *s)
{
   printf("%s\n", s);
}

void printText2(char *s)
{
   printf("\"");
   printf("%s", s);
   printf("\"\n");
}

void exec(char *s, PFUNC pFunc)
{
   pFunc(s);
}
</source>



typedefを使用する(C++11以降)

C++11以降の場合、typedefを使用することを推奨する。

<syntaxhighlight lang="c++">
// C++98, C++03の記述
typedef void (*pfunc)(int, char);

// C++11以降の記述
using pfunc = void (*)(int, char);
</source>