C 関数ポインタ 新しいページはコチラ
提供: yonewiki
(→関数ポインタ) |
|||
1行: | 1行: | ||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る | ||
+ | |||
+ | |||
※このページではC言語にも存在していたという意味で記事タイトルがC 関数ポインタになっていますが、<br /> | ※このページではC言語にも存在していたという意味で記事タイトルがC 関数ポインタになっていますが、<br /> | ||
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | ||
<br /> | <br /> | ||
== '''関数ポインタ''' == | == '''関数ポインタ''' == | ||
+ | |||
関数っていうのは、スタートアップ関数であるmain関数やWindowsであればwmain(_tmain)関数、あるいはwWinMain関数も含めて、すべて関数であると言えます。VisualStudioであればプロジェクトのプロパティでリンカのオプションとして指定する詳細設定の中のエントリポイントの設定によって最初に実行される関数を指定するようになっていて、最初に実行される関数を含めて、すべては関数やクラスの中の関数を呼び出すことによってプログラムが実行されます。Windowsのようなユーザインターフェースを持つプログラムの場合は大抵、割り込み処理を基にした概念が使われ、プログラムは動きっぱなしで、最初の起動時に呼ばれる関数さえ決まっていれば、一連の起動時にだけ実行する処理を実行し、何もしない待機状態になったり、特定の信号によってOSが割り込みを感知するとプログラムに割り込み処理が発生したことを通知し、通知されたイベントに対する関数が動作したりするような動作になります。あるいは特定の処理や特定の割り込み通知によって呼び出された関数によって、プログラムを終了することになります。このような関数と呼ばれているもの自体もメモリのどこかに配置されてプログラムは処理されることから、関数自体もアドレスを持ちます。呼び出し規約というものにしたがって、一定の法則に従って関数はメモリ上にスタックした関数パラメータを読み込んだり、ポップしたりしながら処理を進めます。関数とはそういうものだというイメージをもっていただければ、この項目は理解しやすくなると思います。具体的な個々の関数呼び出し規約の仕組みやスタートアップ関数の決定方法については別の記事で記述したいと思いますが、どこまでわかりやすく説明できるかは未知数です。関数は外部(OSあるいはタイプライブラリあるいは外部機器信号)から呼び出されたり、内部から呼び出されたり、内部から外部を呼び出したりするのが一般的です。そこにはセキュリティのような概念も登場します。 | 関数っていうのは、スタートアップ関数であるmain関数やWindowsであればwmain(_tmain)関数、あるいはwWinMain関数も含めて、すべて関数であると言えます。VisualStudioであればプロジェクトのプロパティでリンカのオプションとして指定する詳細設定の中のエントリポイントの設定によって最初に実行される関数を指定するようになっていて、最初に実行される関数を含めて、すべては関数やクラスの中の関数を呼び出すことによってプログラムが実行されます。Windowsのようなユーザインターフェースを持つプログラムの場合は大抵、割り込み処理を基にした概念が使われ、プログラムは動きっぱなしで、最初の起動時に呼ばれる関数さえ決まっていれば、一連の起動時にだけ実行する処理を実行し、何もしない待機状態になったり、特定の信号によってOSが割り込みを感知するとプログラムに割り込み処理が発生したことを通知し、通知されたイベントに対する関数が動作したりするような動作になります。あるいは特定の処理や特定の割り込み通知によって呼び出された関数によって、プログラムを終了することになります。このような関数と呼ばれているもの自体もメモリのどこかに配置されてプログラムは処理されることから、関数自体もアドレスを持ちます。呼び出し規約というものにしたがって、一定の法則に従って関数はメモリ上にスタックした関数パラメータを読み込んだり、ポップしたりしながら処理を進めます。関数とはそういうものだというイメージをもっていただければ、この項目は理解しやすくなると思います。具体的な個々の関数呼び出し規約の仕組みやスタートアップ関数の決定方法については別の記事で記述したいと思いますが、どこまでわかりやすく説明できるかは未知数です。関数は外部(OSあるいはタイプライブラリあるいは外部機器信号)から呼び出されたり、内部から呼び出されたり、内部から外部を呼び出したりするのが一般的です。そこにはセキュリティのような概念も登場します。 | ||
33行: | 37行: | ||
具体的には、以下のような記述になります。 | 具体的には、以下のような記述になります。 | ||
<syntaxhighlight lang="cpp" line start="1"> | <syntaxhighlight lang="cpp" line start="1"> | ||
+ | #include "stdafx.h" | ||
+ | |||
void example_function1(int n,int m){ | void example_function1(int n,int m){ | ||
− | printf( | + | printf("example_function1 %d %d\n",n, m); |
}; | }; | ||
+ | |||
int _tmain(int argc, _TCHAR* argv[]) | int _tmain(int argc, _TCHAR* argv[]) | ||
{ | { | ||
49行: | 56行: | ||
メイン関数のようなスタートアップ関数は2回呼び出してはいけないことになっているので、最初の例で_tmain関数のアドレスを取得しましたが、調子に乗って関数ポインタを使って呼び出し処理をするようなことはしてはいけません。お忘れなく。たぶん、そんなことをしようと思う人はいないと思いますが…念のため。 | メイン関数のようなスタートアップ関数は2回呼び出してはいけないことになっているので、最初の例で_tmain関数のアドレスを取得しましたが、調子に乗って関数ポインタを使って呼び出し処理をするようなことはしてはいけません。お忘れなく。たぶん、そんなことをしようと思う人はいないと思いますが…念のため。 | ||
+ | |||
+ | |||
+ | 更に | ||
+ | |||
+ | |||
+ | ポインタで配列を扱うことができますので、関数ポインタも同様に配列のように扱うことができます。具体的には以下のように利用します。 | ||
+ | <syntaxhighlight lang="cpp" line start="1"> | ||
+ | #include "stdafx.h" | ||
+ | |||
+ | void example_function1(int n,int m){ | ||
+ | printf("example_function1 %d %d\n",n, m); | ||
+ | }; | ||
+ | void example_function2(int n,int m){ | ||
+ | printf("example_function2 %d %d\n",n, m); | ||
+ | }; | ||
+ | void example_function3(int n,int m){ | ||
+ | printf("example_function3 %d %d\n",n, m); | ||
+ | }; | ||
+ | |||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | void (*pfuncExample[])(int,int) ={example_function1, | ||
+ | example_function2, | ||
+ | example_function3};//定義と配列初期化 | ||
+ | |||
+ | (*pfuncExample[0])(100, 200);//関数ポインタを使った関数の利用(呼び出し) | ||
+ | (*pfuncExample[1])(300, 400); | ||
+ | (*pfuncExample[2])(500, 600); | ||
+ | retrun 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | という具合に使うことができます。サンプルは関数ポインタの配列利用のパターンを無理矢理に作りましたので、実用性がありませんが、配列番号だけで、動的に呼び出す関数を変えるようなプログラムにもできます。スッキリする場合もありますが、ややこしさも増幅する感じがあります。メモリの使い方が変わるので、処理速度改善が見込めるケースもあるかもしれません。本当かどうかはやったことが無いので知りません。ゴメンナサイ。 | ||
+ | |||
+ | |||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る |