2017年11月18日
《その136》 関数へのポインタ
関数へのポインタ
次のプログラムで、関数 print_bits は main関数から与えられた数値を 2進数のビット表示にして出力します。
そして、さらにこの関数は、main関数が指示する別の関数を呼び出します。
別の関数というのは、func1, func2, func3, func4 の4つです。
関数 print_bits は、この4つの関数のうちの一つを呼び出すのですが、どれを呼び出すかの指示は、関数へのポインタという形で受け取ります。
func1 〜 func4 は、どれも、Type型の値を受け取って string型の値を返却します。
string func1(Type x);
string func2(Type x);
string func3(Type x);
string func4(Type x);
これら func1 〜 func4 のポインタの型は、
「Type型の値を受け取って string型の値を返却する関数へのポインタ型」です。
p がこの型のポインタである場合、p の宣言は次のようになります。
string (*p)(Type)
下のプログラムの ★印の関数は、
void print_bits(Type x, string (*func)(Type))
となっていますが、仮引数の一つが string (*func)(Type) です。
このポインタ func が、main関数から渡されるポインタを受け取ります。
そして、main関数は、例えば
print_bits(x, func1);
のように関数 print_bits に引数として 整数 x と 関数へのポインタ func1 を渡します。
プログラムを見てわかるように、func1 というのは関数名ですが、関数名はその関数へのポインタと解釈されます。
もし、func5, func6 と種類が増えても、関数 print_bits は一切書き替える必要がありません。
main関数から関数へのポインタを渡すだけで、関数 print_bits は、その指示通りの関数を呼び出します。
------------------------------------------------------------
#include <string>------------------------------------------------------------
#include <iostream>
using namespace std;
template <class Type> // 十進数表示
string func1(Type x) {
return "十進数表示 : " + to_string(x);
}
template <class Type> // 型名
string func2(Type x) {
return "型名 : " + (string)typeid(x).name();
}
template <class Type> // 1 であるビット数
string func3(Type x) {
int bits = 0;
while (x) { x &= x - 1; bits++; }
return "1 であるビット数 : " + to_string(bits);
}
template <class Type> // 奇数か偶数か
string func4(Type x) {
if (x % 2) return "奇数";
else return "偶数";
}
template <class Type> // ★
void print_bits(Type x, string (*func)(Type)) {
int n = numeric_limits<Type>::digits;
char* vec = new char[n + 1];
for (int i = 0; i < n; i++) {
if ((x >> i) & 1U) vec[n - i - 1] = '1';
else vec[n - i - 1] = '0';
}
vec[n] = '\0';
cout << vec; delete[] vec;
cout << " " << (*func)(x) << '\n';
}
int main() {
unsigned long a = 123456;
print_bits(a, func1);
print_bits(a, func2);
print_bits(a, func3);
print_bits(a, func4);
cout << '\n';
unsigned short b = 77;
print_bits(b, func1);
print_bits(b, func2);
print_bits(b, func3);
print_bits(b, func4);
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/6982466
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック