2017年11月21日
《その146》 メニュードリブンなプログラム(関数へのポインタを利用) & p.104演習3-5
メニュードリブンなプログラムとは、利用者がメニューを選択することによって、異なる内容の処理をさせることのできるプログラムのことです。
次のプログラムは、九九の加算表と乗算表のどちらかを選択させ、選択された表を表示するプログラムです。
計算を受け持つ関数は、sum, mul の二つしかありませんが、関数へのポインタの配列を利用する形になっています。
それ以外の九九の表(あるかどうか分かりませんが、減算の九九とか、累乗の九九とか (..*)・・・ )を追加する必要が生じたときの拡張性に考慮したのかもしれません。
// ------------------------------------------
#include <iomanip>
#include <iostream>
using namespace std;
enum Calc { Sum, Mul, Invalid };
int sum(int x1, int x2) { return x1 + x2; } // 和
int mul(int x1, int x2) { return x1 * x2; } // 積
void kuku(int calc(int, int)) { // 九九の表を出力
cout << " |";
for (int i = 1; i <= 9; i++)
cout << setw(3) << i;
cout << "\n--+";
for (int i = 1; i <= 27; i++)
cout << '-';
cout << '\n';
for (int i = 1; i <= 9; i++) {
cout << i << " |";
for (int j = 1; j <= 9; j++)
cout << setw(3) << calc(i, j);
cout << '\n';
}
cout << '\n';
}
Calc select() { // 九九の表の種類を選ばせる。
int tmp;
do {
cout << "◆九九の表を出力します。\n";
cout << "(0)…加算表 (1)…積算表 (2)・・・終了 : ";
cin >> tmp;
} while (tmp < Sum || tmp > Invalid);
return static_cast<Calc>(tmp);
}
int main() {
Calc selected;
// 関数へのポインタの配列
int(*fp[])(int, int) = { sum, mul };
do {
selected = select();
if (selected < Invalid)
kuku(fp[selected]);
} while (selected != Invalid);
}
// ------------------------------------------
新版明解C++中級編 p.104 演習3-5
上の九九のプログラムを基にして、次の二通りのプログラムを作成すること。
@ 関数へのポインタ型に typedef名を与え、配列の宣言時にそれを使うようにしたプログラム。
A 関数 select が、該当する関数へのポインタを返却するようにしたプログラム。
// p104_演習3-5
// @ 関数へのポインタ型に typedef名を与え、
// 配列の宣言時にそれを使うようにしたプログラム。
#include <iomanip>
#include <iostream>
using namespace std;
enum Calc { Sum, Mul, Invalid };
int sum(int x1, int x2) { return x1 + x2; } // 和
int mul(int x1, int x2) { return x1 * x2; } // 積
void kuku(int calc(int, int)) { // 九九の表を出力
cout << " |";
for (int i = 1; i <= 9; i++)
cout << setw(3) << i;
cout << "\n--+";
for (int i = 1; i <= 27; i++)
cout << '-';
cout << '\n';
for (int i = 1; i <= 9; i++) {
cout << i << " |";
for (int j = 1; j <= 9; j++)
cout << setw(3) << calc(i, j);
cout << '\n';
}
cout << '\n';
}
Calc select() { // 九九の表の種類を選ばせる。
int tmp;
do {
cout << "◆九九の表を出力します。\n";
cout << "(0)…加算表 (1)…積算表 (2)・・・終了 : ";
cin >> tmp;
} while (tmp < Sum || tmp > Invalid);
return static_cast<Calc>(tmp);
}
int main() {
typedef int(*FP)(int, int);
Calc selected;
FP fp[] = { sum, mul };
do {
selected = select();
if (selected < Invalid)
kuku(fp[selected]);
} while (selected != Invalid);
}
// p104_演習3-5
// A 関数 select が、該当する関数へのポインタを返却するようにしたプログラム。
#include <iomanip>
#include <iostream>
using namespace std;
enum Calc { Sum, Mul, Invalid };
int sum(int x1, int x2) { return x1 + x2; } // 和
int mul(int x1, int x2) { return x1 * x2; } // 積
void kuku(int calc(int, int)) { // 九九の表を出力
cout << " |";
for (int i = 1; i <= 9; i++)
cout << setw(3) << i;
cout << "\n--+";
for (int i = 1; i <= 27; i++)
cout << '-';
cout << '\n';
for (int i = 1; i <= 9; i++) {
cout << i << " |";
for (int j = 1; j <= 9; j++)
cout << setw(3) << calc(i, j);
cout << '\n';
}
cout << '\n';
}
int(*select())(int, int) {
// typedef int (*T)(int, int);
// と宣言するものとすれば、
// この関数は、
// T select();
// と書いたものと同じ。
int tmp;
while (1) {
cout << "◆九九の表を出力します。\n";
cout << "(0)…加算表 (1)…積算表 (2)・・・終了 : ";
cin >> tmp;
switch (tmp) {
case Sum: return sum;
case Mul: return mul;
case Invalid: return NULL;
}
}
}
int main() {
while (1) {
int(*ptr)(int, int) = select();
if (ptr == NULL)
break;
kuku(ptr);
}
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/6993576
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック