C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: 配列の参照に関する質問


(過去ログ 116 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■68605 / inTopicNo.1)  配列の参照に関する質問
  
□投稿者/ 初心者 (13回)-(2013/10/31(Thu) 17:03:06)

分類:[C/C++] 

下記のような配列の参照を使いたいですが、引数としてどう渡せば良いのでしょうか。

unsigned char a[20][5];

void foo( ??? ) // ???の処の書き方は分かりません。
{
  b[10][1] = 20; // このbは関数fooの参照型のパラメータとして渡された上に定義されている配列aの参照です。

}



引用返信 編集キー/
■68607 / inTopicNo.2)  Re[1]: 配列の参照に関する質問
□投稿者/ (こ) (3回)-(2013/10/31(Thu) 18:30:07)
> unsigned char a[20][5];
>
> void foo( ??? ) // ???の処の書き方は分かりません。

void foo(unsigned char (*b)[5])
void foo(unsigned char b[][5])
void foo(unsigned char b[20][5])

お好きなものをどうぞ。
呼び出しはどれも foo(a); でいけます。

引用返信 編集キー/
■68608 / inTopicNo.3)  Re[2]: 配列の参照に関する質問
□投稿者/ 774RR (116回)-(2013/10/31(Thu) 19:15:38)
厳密には提示サンプルの3つとも「参照」ではなくて「ポインタ」だよね。
実用上ポインタでまったく問題ないんだけど。

真に「参照」にするなら下記サンプルとかどーぞ。

int funca(int(&a)[2][5]) {
  return a[0][0];
}

int funcb(int a[2][5]) {
  return a[0][0];
}

int main() {
  int t1[2][5];
  funca(t1);
  funcb(t1);
  int t2[3][5];
  funca(t2);
  funcb(t2);
}

引用返信 編集キー/
■68623 / inTopicNo.4)  Re[3]: 配列の参照に関する質問
□投稿者/ 初心者 (14回)-(2013/11/01(Fri) 13:59:37)
皆さま
ご教授ありがとうございます。

(こ)さまが書かれたやりかたのほうは良く分かりますけれども、
自分がやりたいのはまさに774RR さまご指摘のやり方です。

でも、「参照」の使い方は試してみたいではありますが、
正直に言って、「参照」の存在意義は分かりません。

ポインターのほうはすっきりではないでしょうか。
機能的に違う処あります?




No68608 (774RR さん) に返信
> 厳密には提示サンプルの3つとも「参照」ではなくて「ポインタ」だよね。
> 実用上ポインタでまったく問題ないんだけど。
>
> 真に「参照」にするなら下記サンプルとかどーぞ。
>
> int funca(int(&a)[2][5]) {
> return a[0][0];
> }
>
> int funcb(int a[2][5]) {
> return a[0][0];
> }
>
> int main() {
> int t1[2][5];
> funca(t1);
> funcb(t1);
> int t2[3][5];
> funca(t2);
> funcb(t2);
> }
>
引用返信 編集キー/
■68626 / inTopicNo.5)  Re[4]: 配列の参照に関する質問
□投稿者/ とっちゃん (172回)-(2013/11/01(Fri) 14:24:36)
とっちゃん さんの Web サイト
No68623 (初心者 さん) に返信
> でも、「参照」の使い方は試してみたいではありますが、
> 正直に言って、「参照」の存在意義は分かりません。
>
> ポインターのほうはすっきりではないでしょうか。
> 機能的に違う処あります?
>

class Hoge
{
public:
int value;
char buff[65536];
};
void RefParam( Hoge& hoge )
{
hoge.value = 0;;
++hoge; // NG.
}

void PtrParam( Hoge* hoge )
{
hoge->value = 0;
++hoge; // 位置が変わる!
}

PtrParam( nullptr ); // OK.
RefParam( nullptr ); // NG.

{
Hoge hoge;
PtrParam( &hoge );
RefParam( hoge );
}

という違いがあります。
大きな違いはこのくらいかな。

一番ありがたみがある使い方は...

void ConstRefParam( const Hoge& hoge )
{
}
void ValurParam( Hoge hoge )
{
}
ですね。
ValueParam( hoge );
ConstRefParam( hoge );

は、どちらも呼び出し元の hoge の内容は変わりませんし、見た目も変わりません。
ですが、前者はスタック上に巨大なhogeの内部データ(char配列)を確保して、コピーするのに対し
後者は、呼出し元のhogeの実体を「参照」するだけで、スタックは、ポインタサイズ分、コピー処理はポインタの代入速度で済みます。

今のCPUなら、1回程度なら大したコストではないと思います。
でも、再帰したり(呼ばれるたびにスタックを64KB消費)、数千単位で回るようなループ中に呼ばれる(呼ばれるたびに64KBコピー)関数だったりすると
悲惨極まりないことになります。

引用返信 編集キー/
■68631 / inTopicNo.6)  Re[5]: 配列の参照に関する質問
□投稿者/ 774RR (117回)-(2013/11/01(Fri) 18:00:07)
「配列への参照」を離れて、参照の意義を論じることにしよう。
コピーコンストラクタと代入演算子は、参照でないと文法的に記述するすべがないんだ。

struct mytype {
  mytype& operator=(mytype& that);
  mytype(const mytype& that);
};

もし参照がなかったとしたら
1. コピーコンストラクタは mytype::mytype(mytype that) { ... } という形式になる。
2. これを関数呼び出しする引数の複写にコピーコンストラクタが使われる
3. 無限ループ

コピーコンストラクタが mytype::mytype(const mytype* that) { ... } であったなら
代入演算子が mytype& mytype::operator=(const mytype* that) { ... } であったなら
mytype a;
mytype b(&a); // これって複写?不自然すぎる
b=&a; // これって代入?不自然すぎる
ということになる。

生成される機械語としては、参照とポインタで同じになる(違うコードになる処理系が思いつかない)
ので、性能的にはどっちを使っても同じだよ。

引用返信 編集キー/
■68632 / inTopicNo.7)  Re[6]: 配列の参照に関する質問
□投稿者/ 初心者 (15回)-(2013/11/02(Sat) 12:03:51)

皆さま

丁寧なご指導本当にありがとうがざいます。

色々分かりやすい実例で良く分かりました。

”生成される機械語としては、参照とポインタで同じになる”
---------これも知りたかったのです!

もう一度お礼を申し上げたいです。






解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -