2017年11月27日
《その152》 「配列へのポインタを void* で受け取る関数」 の動作 と 返却値の処理
◆ 「配列へのポインタを void* で受け取る関数」 の動作 と 返却値の処理 ◆
たとえば、
char s[][3] = { "ab", "bc", "ca" ,"d" } と定義すると、下図のように文字が記憶されます。
図にはビットの区切りは書いてありませんが、1文字を表すのに 8ビット使っています。
1文字(8ビット)分を大きさ 1 と考えるので、この場合は、大きさ 3 のデータが 4個並んでいます。
この状況で、main関数から、関数 func を
char* ptr = reinterpret_cast<char*>(func(201, 4, 3)); ・・・ ※
と、呼び出したとします。
3つの引数は 配列 s の「最初の番地へのポインタ 201」、「データの個数 4」、「データの大きさ 3」です。
ここでは、関数 func は次のように宣言されているものとしました。
void* func(const void* base, size_t nmemb, size_t size);
関数 func は、受け取った配列が本当は何型なのか知らなくても、例えば、2番目の要素へのポインタなら、受け取った情報から、
201 + 3 × (2 − 1)
を計算して 204番地であると知ることができます。
今、関数 func が、関数内での処理の結果、207番地を返却することになったとします。
main関数は、受け取った 207 を char*型に変換してから、ptr に代入します( ※印の式 )。
ここで
ptr − s
を計算すると、
207 − 201 = 6 ですから、
6文字分離れていることがわかります。
この配列は、要素の大きさが 3文字分ですから、6文字分離れているということは、配列の添字でいえば 2 だけ離れていることになります。
先頭の s[0] から 2 つ先は s[2] です。
以上のような感じで、main関数は、関数 func が s[2]へのポインタを返してきてくれたことを知ることができます。
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7011333
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック