アフィリエイト広告を利用しています

広告

posted by fanblog

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';
}
// ------------------------------------------

e03_0014.png


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)





この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/7009278
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。