関数ポインタ変数の配列をつかって複数の自作関数を実行することのメリットは自作関数が実行される順序を入れ替えることができることにあります
ソーラー「さて
こう思った人もいるんじゃないかな?
void newmadefunction(void) {
printf("青い海です\n");
return ;
}
と定義された自作関数newmadefunctionがあるとします
このとき
関数ポインタ変数宣言
void(*ptf)(void);
により作製された
関数ポインタ変数ptfに自作関数newmadefunctionの
アドレスを
ptf=newmadefunction;
と
代入したのち
*ptf
を用いて
自作関数newmadefunctionを実行してみなくても
普通に
自作関数newmadefunctionを
newmadefunction();
と
実行すればいいのでは?
関数ポインタ変数を用いて
自作関数newmadefunctionを
*ptf
と
実行する必要はないのでは
と
思われる方がおられるかもしれません」
アレサ「そういえば そうですの」
ソーラー「そこで
関数ポインタ変数を用いて
自作関数を
実行することの利点を述べてみたいと思います。」
アレサ「どのような例がでるのかしら・・・」
ソーラー「まず 次のプログラムを
ご覧ください
#include <stdio.h>
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
int main(void) {
void(*ptf[3])(void);
ptf [0]= newmadefunction1;
ptf [1]= newmadefunction2;
ptf [2]= newmadefunction3;
(*ptf[0])();
(*ptf[1])();
(*ptf[2])();
return 0;
}
コンパイル結果(EAZY IDECの場合)
青い海です
金色の海です
水色の海です
Visual studioの場合
青い海です
金色の海です
水色の海です
ソーラー「このプログラムでは
関数ポインタ変数の配列宣言
void(*ptf[3])(void);
により
関数ポインタ変数が
ptf[0]
ptf[1]
ptf[2]
と3つ生成されるんだよ
まとめて
関数ポインタ変数を作製したいときには
この方法は便利だよね。
関数ポインタ変数名を
ptf1
ptf2
ptf3
のように
3つ考えて
関数ポインタ変数宣言を3つ
void(*ptf1)(void);
void(*ptf2)(void);
void(*ptf3)(void);
と記述しなくてもいいからね。
後は
定義されている自作関数名
newmadefunction1
newmadefunction2
newmadefunction3
を
作製された
関数ポインタ変数
ptf[0]
ptf[1]
ptf[2]
に
ptf[0]= newmadefunction1;
ptf[1]= newmadefunction2;
ptf[2]= newmadefunction3;
と代入すれば
*ptf[0]
*ptf[1]
*ptf[2]
は
プログラムの実行時
機械語に翻訳された自作関数が格納されているメモリにアクセスして
自作関数
newmadefunction1
newmadefunction2
newmadefunction3
の働きをすることになります。
ですので
(*ptf[0])();
(*ptf[1])();
(*ptf[2])();
と記述して
コンパイル結果に
青い海です
金色の海です
水色の海です
が表示できるってわけだね。
つまり
自作関数
newmadefunction1
newmadefunction2
newmadefunction3
を実行できるってわけだね。
ここで
このプログラムの
(*ptf[0])();
(*ptf[1])();
(*ptf[2])();
の部分を
int i;
for(i=0;i<3;i++){
(*ptf[i])();
}
と書き換えて実行することができます。
その時のプログラムはこちらです
👇
#include <stdio.h>
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
int main(void) {
void(*ptf[3])(void);
ptf [0]= newmadefunction1;
ptf [1]= newmadefunction2;
ptf [2]= newmadefunction3;
int i;
for(i=0;i<3;i++){
(*ptf[i])();
}
return 0;
}
コンパイル結果(EAZY IDECの場合)
青い海です
金色の海です
水色の海です
Visual studioの場合
青い海です
金色の海です
水色の海です
ソーラー「どう?アレサ
🌞配列🌞
を用いて
簡単にプログラムを記述することができたね」
今のこのプログラムは
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
を
関数のポインタ変数と配列のシステムを使って
実行しているというわけなんだよ」
アレサ「そうなのですね。
関数のポインタ変数と配列のシステムを使っているといっても
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
が実行されているだけなのですね。」
ソーラー「ところで
あるプログラムで
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
が記述されているとします
この命令文の実行順序を
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
に入れ替えて実行してみたいと思います
ふつうは
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
を
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
と記述しなおせばいいということになりますね。」
アレサ「ソーラーさん そうですね 簡単ですね。」
ソーラー「では
関数のポインタ変数と配列のシステムが用いられた
このプログラムの
👇
#include <stdio.h>
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
int main(void) {
void(*ptf[3])(void);
ptf [0]= newmadefunction1;
ptf [1]= newmadefunction2;
ptf [2]= newmadefunction3;
int i;
for(i=0;i<3;i++){
(*ptf[i])();
}
return 0;
}
コンパイル結果(EAZY IDECの場合)
青い海です
金色の海です
水色の海です
Visual studioの場合
青い海です
金色の海です
水色の海です
👆
の
ビルド実行結果を
青い海です
金色の海です
水色の海です
から
水色の海です
金色の海です
青い海です
に変えて
コマンドプロンプト画面に表示したい場合は
どうしたらいいとおもうかな?」
アレサ「ふ~んん
int i;
for(i=0;i<3;i++){
(*ptf[i])();
}
の部分は
(*ptf[0])();
(*ptf[1])();
(*ptf[2])();
と等しいものです
(*ptf[0])();
(*ptf[1])();
(*ptf[2])();
が実行されると
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
が実行されて
青い海です
金色の海です
水色の海です
が
コマンドプロンプト画面に表示されます
なら
(*ptf[2])();
(*ptf[1])();
(*ptf[0])();
が実行されれば
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
が実行されて
水色の海です
金色の海です
青い海です
が
コマンドプロンプト画面に表示されることになります。
ということは
プログラムの
int i;
for(i=0;i<3;i++){
(*ptf[i])();
}
の部分を
int i;
for(i=0;i<3;i++){
(*ptf[2-i])();
}
のように記述しなおしたらよいのではないですか?」
ソーラー「そうなんだ
やったね アレサ💖
その時のプログラムは
こちらだね
👇
#include <stdio.h>
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
int main(void) {
void(*ptf[3])(void);
ptf [0]= newmadefunction1;
ptf [1]= newmadefunction2;
ptf [2]= newmadefunction3;
int i;
for(i=0;i<3;i++){
(*ptf[2-i])();
}
return 0;
}
コンパイル結果(EAZY IDECの場合)
水色の海です
金色の海です
青い海です
Visual studioの場合
水色の海です
金色の海です
青い海です
ソーラー「このプログラムでは
青い海です
金色の海です
水色の海です
の順序を入れ替えた
水色の海です
金色の海です
青い海です
がコマンドプロンプト画面に表示されています
ようは
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
の実行順序を
関数のポインタ変数と配列のシステムを用いて
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
に入れ替えたというわけなんです。
このことはとても重要なことなんだよ。
例えば
青い海です
金色の海です
水色の海です
水色の海です
青い海です
水色の海です
青い海です
青い海です
金色の海です
水色の海です
金色の海です
水色の海です
青い海です
金色の海です
金色の海です
とコマンドプロンプト画面に
表示されている状態から
順序を逆に
金色の海です
金色の海です
青い海です
水色の海です
金色の海です
水色の海です
金色の海です
青い海です
青い海です
水色の海です
青い海です
水色の海です
水色の海です
金色の海です
青い海です
と
とコマンドプロンプト画面に
表示されている状態に変更したい場合に
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("金色の海です\n");
と記述されている状態を
実行順序を逆に入れ替えて
printf("金色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
と記述する方法もあるのですが
とても大変です
そこで最初に
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("金色の海です\n");
と記述されている状態から
簡単に
実行順序を入れ替えて
printf("金色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
に変更して
実行することができるために
最初から
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("金色の海です\n");
を
関数のポインタ変数と配列のシステムを用いて
記述しておきます。
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("金色の海です\n");
printf("金色の海です\n");
を実行するために
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
を自作関数
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
に設定して
関数のポインタ変数の配列宣言
void(*ptf[15])(void);
により生成される
関数のポインタ変数の配列
ptf[0]
ptf[1]
ptf[2]
ptf[3]
ptf[4]
ptf[5]
ptf[6]
ptf[7]
ptf[8]
ptf[9]
ptf[10]
ptf[11]
ptf[12]
ptf[13]
ptf[14]
に
自作関数
newmadefunction1
newmadefunction2
newmadefunction3
のアドレスを
ptf[0]=newmadefunction1;
ptf[1]=newmadefunction2;
ptf[2]=newmadefunction3;
ptf[3]=newmadefunction3;
ptf[4]=newmadefunction1;
ptf[5]=newmadefunction3;
ptf[6]=newmadefunction1;
ptf[7]=newmadefunction1;
ptf[8]=newmadefunction2;
ptf[9]=newmadefunction3;
ptf[10]=newmadefunction2;
ptf[11]=newmadefunction3;
ptf[12]=newmadefunction1;
ptf[13]=newmadefunction2;
ptf[14]=newmadefunction2;
のように代入し
int i;
for(i=0;i<15;i++){
(*ptf[i])();
}
と記述しておけば
int i;
for(i=0;i<15i++){
(*ptf[14-i])();
}
と記述するだけで
printf("金色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("青い海です\n");
printf("水色の海です\n");
printf("水色の海です\n");
printf("金色の海です\n");
printf("青い海です\n");
が実行できるんです
つまり
以下のプログラムの
👇
#include <stdio.h>
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
int main(void) {
void(*ptf[15])(void);
ptf[0]=newmadefunction1;
ptf[1]=newmadefunction2;
ptf[2]=newmadefunction3;
ptf[3]=newmadefunction3;
ptf[4]=newmadefunction1;
ptf[5]=newmadefunction3;
ptf[6]=newmadefunction1;
ptf[7]=newmadefunction1;
ptf[8]=newmadefunction2;
ptf[9]=newmadefunction3;
ptf[10]=newmadefunction2;
ptf[11]=newmadefunction3;
ptf[12]=newmadefunction1;
ptf[13]=newmadefunction2;
ptf[14]=newmadefunction2;
int i;
for(i=0;i<15;i++){
(*ptf[i])();
}
return 0;
}
ビルド実行結果
青い海です
金色の海です
水色の海です
水色の海です
青い海です
水色の海です
青い海です
青い海です
金色の海です
水色の海です
金色の海です
水色の海です
青い海です
金色の海です
金色の海です
👆
(*ptf[i])();の部分を(*ptf[14-i])();
と記述し直すだけでよいというわけです。
その時のプログラムはこちらです
👇
#include <stdio.h>
void newmadefunction1(void) {
printf("青い海です\n");
return;
}
void newmadefunction2(void) {
printf("金色の海です\n");
return;
}
void newmadefunction3(void) {
printf("水色の海です\n");
return;
}
int main(void) {
void(*ptf[15])(void);
ptf[0]=newmadefunction1;
ptf[1]=newmadefunction2;
ptf[2]=newmadefunction3;
ptf[3]=newmadefunction3;
ptf[4]=newmadefunction1;
ptf[5]=newmadefunction3;
ptf[6]=newmadefunction1;
ptf[7]=newmadefunction1;
ptf[8]=newmadefunction2;
ptf[9]=newmadefunction3;
ptf[10]=newmadefunction2;
ptf[11]=newmadefunction3;
ptf[12]=newmadefunction1;
ptf[13]=newmadefunction2;
ptf[14]=newmadefunction2;
int i;
for(i=0;i<15;i++){
(*ptf[14-i])();
}
return 0;
}
ビルド実行結果
金色の海です
金色の海です
青い海です
水色の海です
金色の海です
水色の海です
金色の海です
青い海です
青い海です
水色の海です
青い海です
水色の海です
水色の海です
金色の海です
青い海です
アレサ「自作関数の実行順序が簡単に入れ替わっています」
ソーラー「そう このように
関数の実行順序を
簡単に入れ替えて実行するために
関数のポインタ変数と配列のシステムは用いられるんだよ
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
を
自作関数
newmadefunction1
newmadefunction2
newmadefunction3
の定義にもちいて
自作関数
newmadefunction1
newmadefunction2
newmadefunction3
を生成したり
関数のポインタ変数の配列宣言
void(*ptf[15])(void);
により生成される
関数のポインタ変数の配列
ptf[0]
ptf[1]
ptf[2]
ptf[3]
ptf[4]
ptf[5]
ptf[6]
ptf[7]
ptf[8]
ptf[9]
ptf[10]
ptf[11]
ptf[12]
ptf[13]
ptf[14]
に
自作関数
newmadefunction1
newmadefunction2
newmadefunction3
のアドレスを
ptf[0]=newmadefunction1;
ptf[1]=newmadefunction2;
ptf[2]=newmadefunction3;
ptf[3]=newmadefunction3;
ptf[4]=newmadefunction1;
ptf[5]=newmadefunction3;
ptf[6]=newmadefunction1;
ptf[7]=newmadefunction1;
ptf[8]=newmadefunction2;
ptf[9]=newmadefunction3;
ptf[10]=newmadefunction2;
ptf[11]=newmadefunction3;
ptf[12]=newmadefunction1;
ptf[13]=newmadefunction2;
ptf[14]=newmadefunction2;
のように代入したりするところに
手間がかかると思います
が
一度
ptf[0]=newmadefunction1;
ptf[1]=newmadefunction2;
ptf[2]=newmadefunction3;
ptf[3]=newmadefunction3;
ptf[4]=newmadefunction1;
ptf[5]=newmadefunction3;
ptf[6]=newmadefunction1;
ptf[7]=newmadefunction1;
ptf[8]=newmadefunction2;
ptf[9]=newmadefunction3;
ptf[10]=newmadefunction2;
ptf[11]=newmadefunction3;
ptf[12]=newmadefunction1;
ptf[13]=newmadefunction2;
ptf[14]=newmadefunction2;
まで実行しておけば
printf("青い海です\n");
printf("金色の海です\n");
printf("水色の海です\n");
の実行順序を
関数のポインタ変数と配列のシステムを
用いて
簡単に管理できることになるというわけです。」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます