2017年11月26日
《その151》 配列へのポインタを void* で受け取る関数
配列へのポインタを void* で受け取る関数
汎用性を持たせるために配列へのポインタを void*型 で受け取るようにした関数について、次のプログラムでチェックしてみます。
関数 rtrv_3rd は、受け取った配列 x の第3要素 x[2] へのポインタを返すだけの、単純で実用性のないものですが、void*型を利用して関数に汎用性を持たせる仕組みを見ることができます。
// ------------------------------------------
#include <iostream>
using namespace std;
void* rtrv_3rd(const void* base, size_t nmemb, size_t size) {
// ↑配列の第3要素へのポインタを void*型で返す関数。
// base … 配列の先頭要素へのポインタ
// nmemb … 配列要素の個数
// size … 配列要素の大きさ
if (nmemb < 3) return NULL;
// 配列の要素数が 3未満のときは NULL を返す。
const char* x = reinterpret_cast<const char*>(base);
// 配列の先頭要素を指すポインタ base を型変換して
// const char* x に代入。
return const_cast<void*>(
// 返却値は void*型
reinterpret_cast<const void*>(&x[2 * size])
// char型配列の要素の大きさは 1、配列 base の要素
// の大きさは size なので、
// &base[0] は &x[0 * size] に、
// &base[1] は &x[1 * size] に、
// &base[2] は &x[2 * size] に、それぞれ
// 対応します。
);
}
int main() {
int a[] = { 10, 11, 12, 13, 14, 15 }; // @
double b[] = { 0.0, 1.1, 2.2, 3.3 }; // A
char c[][3] = { "ab", "bc", "ca" }; // B
const char* d[] = { "xy", "yz", "zx" }; // C
// @
int* p =
reinterpret_cast<int*>(
rtrv_3rd(
a,
// 配列の先頭要素へのポインタ
sizeof(a) / sizeof(a[0]),
// 配列要素の個数
sizeof(int)
// 配列要素の大きさ
)
);
if (p != NULL)
cout << a[p - a] << '\n';
// int*型の p, a の差は、int型配列 a の添字の差。
// この場合は p - a = 2 になり、
// a[p - a] は a[2] のことになります。
else
cout << "無し" << '\n';
// A
double* q =
reinterpret_cast<double*>(
rtrv_3rd(
b,
sizeof(b) / sizeof(b[0]),
sizeof(double)
)
);
if (q != NULL)
cout << b[q - b] << '\n';
else
cout << "無し" << '\n';
// B
char* r =
reinterpret_cast<char*>(
rtrv_3rd(
c,
sizeof(c) / sizeof(c[0]),
sizeof(c[0])
)
);
if (r != NULL)
cout << c[(r - c[0]) / sizeof(c[0])] << '\n';
// char*型の r, c[0] の差は
// 「char[3][3]型配列の添字の差」であり、
// それは「c[3]型配列の添字の差」の
// sizeof(c[0])倍です。
// ※sizeof(c[0]) の値は 3。
else
cout << "無し" << '\n';
// C
char** s =
reinterpret_cast<char**>(
// rtrv_3rd関数からの返却値は void*型ですが、実際
// には文字列へのポインタのポインタな
// ので、char**型にキャストして受け取
// ります。
rtrv_3rd(
d,
// 配列 d の要素 d[0], d[1], ・・・ は
// 文字列へのポインタなので、
// d は文字列へのポインタの
// ポインタです。
sizeof(d) / sizeof(d[0]),
sizeof(d[0])
)
);
if (s != NULL)
cout << d[s - d] << '\n';
else
cout << "無し" << '\n';
}
// ------------------------------------------
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7009278
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック