第11講 ポインタの学習

第12話 関数ポインタによって関数をアドレスで操作する
この話においても、先に事例を示してから解説しましょう。
関数ポインタによって関数をアドレスから操作する例
#include<stdio.h>
int f(int x); //xを2倍して返す
int g(int x); //xを2乗して返す
int main(){
  int (*h[2])(int x); /* 関数ポインタ配列の宣言 */
  int x,i;
  h[0]=f;
  h[1]=g;
  x=5;
  for(i=0;i<2;i++)printf("%d\n",(*h[i])(x));
}
int f(int x){
  return(2*x);
}
int g(int x){
  return(x*x);
}
コピペ用添付ファイル
実行画面
10
25


  int (*h[2])(int x); /* 関数ポインタ配列の宣言 */
が関数ポインタ配列の宣言です。
要するに関数の先頭アドレスを収納する配列です。
  h[0]=f;
  h[1]=g;
によって、関数fの先頭アドレスがh[0]に、
関数gの先頭アドレスがh[1]に収納されています。
関数fは送られてきた値xを2倍にして返す関数ですし、
関数gは送られてきた値xを2乗(x×xのことですよ。)にして返す関数です。
今回の例では引数xに5が代入されていますから、
関数fと関数gには5を送っています。
fとgから返ってきた値を表示していますから、
10
25

となります。10は5の2倍ですし、25は5の2乗(5×5)です。
  for(i=0;i<2;i++)printf("%d\n",(*h[i])(x));
関数ポインタ配列を使わなければ、
for文で制御できませんが、
関数ポインタ配列を使うことによって、
制御できるようになります。
  h[0]=f;
によって、(*h[0])(x)は関数f(int x)すなわち
int f(int x){
  return(2*x);
}

そのものになります。
(*h[0])(x)は先頭アドレスがfである関数という意味です。


(*h[i])(x)は(*(h+i))(x))でも可です。
関数のメモリ容量は、分かりませんが、
C言語の方で自動的に判断して
h+iのiを適切なものに変換してくれるのでしょう。
第7講第5話の
ポインタxの先頭アドレスが
w
1000だとすると、i=1のときx+iは1000+1で1001のハズですが、
xがint型のポインタとして宣言されていますので、
コンピュータは、自動的に
i=1のときx+iに対して1000+4
i=2のときx+iに対して1000+8
i=3のときx+iに対して1000+12
i=4のときx+iに対して1000+16
と解釈してくれるのです。

を思い出して下さい。
つまり、iが1のときh+iは『h+(関数fのメモリ容量)』にしてくれるということだと思います。
C言語は大変お利口な言語ですね。

以上でポインタの学習は終了します。
次講では、今回学んだポインタを利用して、
テトリスのコードを書き換え、
すべてのグローバル変数を追放してみましょう。
メモリの節約のために、
なるべくグローバル変数は使わない!
が原則です。
一気にやると頭が混乱しますから、
少しずつ追放してきます。




第11話へ   第12講第1話へ

第2部目次に戻る  第1部目次に戻る

初心者のための excel 2016 マクロ VBA 入門講義 基礎から応用まで
vc++ c言語 c++ 入門 初心者 基礎から応用まで
ecliqse c++ 入門
魔方陣 数独で学ぶ VBA 入門

数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
ecliqse java 入門
java 入門 サイト 基礎から応用まで
本サイトトップへ