画像(logo)

HOME/[C言語 入門]小学生でもわかるC言語2 目次/十三日目 関数ポインタ

広告

[C言語 入門 小学生でもわかるC言語2]
十三日目 関数ポインタ

広告

↓2016年02月29日発売↓

12歳からはじめる ゼロからのC言語 ゲームプログラミング教室

目次へ戻る

関数ポインタ

またまたポインタのお時間です。

C言語はポインタとは切っても切り離せないのです。

これまでに変数のポインタ、構造体のポインタを学びました。

では今回はと言いますと、関数のポインタについてやっていきたいと思います。

使い方

手っ取り早く使い方を説明したいと思います。

関数ポインタも基本は変わりません。

やっぱり先頭にアスタリスクをつけてポインタにしていきます。

まずは普通の関数を作りましょう!

void func(void);

何も受け渡しがない関数「func」ですね!

このカタチをそのままポインタにしていきます!

という事はどこかの先頭に「*」アスタリスクをつけるワケですね!

結論から言いますと

void *func_p(void);

「func」の先頭に「*」アスタリスクをつけます。

そして計算の順序が変わらないように()カッコで→(*func)囲んで

その後ろの「void」は省略できるので、

void (*func_p)();

これが何も受け渡しがない関数ポインタの基本のカタチになります。

そしてここに関数ポインタを保存する時は

void (*func_p)() = func;

このように保存します。

これで関数ポインタに関数「func()」のアドレスが保存されます。

今回は「&」アンパサンドは付けてませんが、

void (*func_p)() = &func;

つけても大丈夫です。

使う時は

(*func_p)();

この()カッコで囲んだカタチのまま使います。

まとめてプログラム

/*十三日目 プログラム1*/
#include <stdio.h>

void func(void);

int main(){
	void (*func_p)() = func;

	(*func_p)();

	return 0;
}

void func(){
	printf("関数ポインタの巻\n");
}

■実行結果■

画像(ce_13_1)

元の関数

void func(void);
void func(){
	printf("関数ポインタの巻\n");
}

関数ポインタに保存

void (*func_p)() = func;

使う時は

(*func_p)();

カタチで覚えてしまいましょう!

引数、戻り値あり

では続けて引数と戻り値がある場合を見てみましょう。

int menseki(int ,int );

このカタチの関数をポインタにしてみます。

int (*menseki_p)(int ,int ) = menseki;

こちらが関数ポインタにしたものになります。

そのまま引数、戻り値を加えた感じですね!

ではこれらを踏まえてプログラミングしてみます。

/*十三日目 プログラム2*/
#include <stdio.h>

int menseki(int ,int);

int main(){
	int kotae = 0;
	int (*menseki_p)(int ,int ) = menseki;

	kotae = (*menseki_p)(10,5);

	printf("長さ縦10,横5の四角形の面積 = %d\n",kotae);

	return 0;
}

int menseki(int tate,int yoko){
	return tate * yoko;
}

■実行結果■

画像(ce_13_2)

元の関数

int menseki(int ,int);

関数ポインタ

int (*menseki_p)(int ,int ) = menseki;

こちらもカタチで覚えてしまいましょう!

広告

実用例

ではこの関数ポインタを使って何ができるかと言えば、例えば複数の関数を配列にする事ができます。

/*十三日目 プログラム3*/
#include <stdio.h>

void ohayo(void);
void konnitiha(void);
void konbanha(void);

int main(){
	int i;
	void (*aisatu[3])() = {ohayo,konnitiha,konbanha};
	
	for(i=0;i<3;i++){
		(*aisatu[i])();
	}

	return 0;
}

void ohayo(){
	printf("おはよう!\n");
}

void konnitiha(){
	printf("こんにちは!\n");
}

void konbanha(){
	printf("こんばんは!\n");
}

■実行結果■

画像(ce_13_3)

こうすれば同じような性質を持つ関数群を「for」文などで一気に処理できたりするのでとても便利ですね!

void (*aisatu[3])() = {
	ohayo,
	konnitiha,
	konbanha
};

書き方がちょっとややこしいですが、何度も練習して覚えてしまいましょう!

使う時は

(*aisatu[2])();

のように使います。

関数を変更

さらに画期的な事に関数ポインタは関数を保存できる変数のようなものなので引数と戻り値が同じであれば、関数の内容を入れ替える事ができます。

/*十三日目 プログラム4*/
#include <stdio.h>

void ohayo(void);
void konnitiha(void);
void konbanha(void);

void (*aisatu)();

int main(){
	aisatu = ohayo;
	(*aisatu)();

	aisatu = konnitiha;
	(*aisatu)();
	
	aisatu = konbanha;
	(*aisatu)();

	return 0;
}

void ohayo(){
	printf("おはよう!\n");
}

void konnitiha(){
	printf("こんにちは!\n");
}

void konbanha(){
	printf("こんばんは!\n");
}

■実行結果■

画像(ce_13_4)

これと先ほどの配列を組み合わせれば状況によって変わるメニュー項目などが簡単に作れそうですね!

さきほどのプログラムの前半

#include <stdio.h>

/*プロトタイプ宣言*/
void ohayo(void);
void konnitiha(void);
void konbanha(void);

/*関数ポインタをグローバル宣言している*/
void (*aisatu)();

int main(){
/*以下省略*/
}

プロトタイプ宣言とグローバル宣言している関数ポインタ、この違いと

代入する時の書き方

aisatu = ohayo;

このあたりに注意です!

次回は時間と乱数(らんすう)についてやっていきたいと思います。

次回

最終日 時間と乱数

□ページの先頭へ□

□目次へ戻る□

□HOME□

広告

↓2017年06月16日発売↓

やさしいC 第5版 (「やさしい」シリーズ)

新品価格
¥2,700から
(2017/5/1 13:05時点)

↓2014年08月09日発売↓

新・明解C言語 入門編 (明解シリーズ)

新品価格
¥2,484から
(2017/5/1 13:08時点)

↓2016年02月20日発売↓

新・解きながら学ぶC言語

新品価格
¥2,160から
(2017/5/1 13:10時点)

↓2017年02月11日発売↓

C言語プログラミング基本例題88 88

新品価格
¥3,024から
(2017/5/1 13:12時点)

↓2016年12月15日発売↓

Cの絵本 第2版 C言語が好きになる新しい9つの扉

新品価格
¥1,490から
(2017/5/1 13:13時点)

↓2017年02月08日発売↓

新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ)

新品価格
¥2,700から
(2017/5/1 13:15時点)