- ベストアンサー
関数への変数の受け渡しについて
関数に変数を受け渡すとき、配列とそれ以外の変数では受け渡すものが違いますよね。 変数の場合は、変数の値を関数側の変数にコピーする。 配列の場合は、配列そのもの(配列のポインタ)を関数に渡す。 なぜ配列の場合は値のコピーではなくて、ポインタを渡す仕様になっているんでしょうか。 ひとつめは、どのような意図でそのような仕様になっているのかという質問です。 もうひとつは、関数に配列の値だけを渡すにはどうすればいいのか、つまり元の配列のほうの値は書き換えないで欲しいというときはどうすればよいのかという質問です。 よろしくおねがいします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
Cでは「添え字のない配列変数は、配列の実体のポインタを現わす」からです。 これは「関数の引数に限らず、いつも」です。 例えば、 int a[10]; int *p; p=a; /* p=&a[0]; と同じ効果を得る。但し、異なる構文なので、厳密には異なる */ など。 「aは配列の実体のポインタ」なので「ポインタ変数であるp」に代入出来るのです。 なので、 sub(a); などのように関数の引数に「a」を使えば「aは配列の実体のポインタ」なので、ポインタが渡されます。 注意しないとならないのは「関数の引数だから、ではない」と言う事。「関数の引数にしたからポインタになった」と考えるのは「大間違い」です。 また「a」と「&a[0]」は「値は同じ」ですが「意味が違う」ので注意しましょう。例えば「a+1」と「(&a[0])+1」は「異なる値」になります。 >もうひとつは、関数に配列の値だけを渡すにはどうすればいいのか ・呼び出し前にコピーを作って、コピーのポインタを渡す。 ・呼び出し前にコピーを作って、戻ってきたらコピーを元の配列に書き戻す。 ・呼ばれた方でコピーを作って、コピーを書き替える。 ・呼ばれた方でコピーを作って、帰る前にコピーを元の配列に書き戻す。 など。
その他の回答 (3)
- titokani
- ベストアンサー率19% (341/1726)
関数に配列全体を渡すのと、配列の先頭アドレスだけを渡すのとでは、処理の重さがぜんぜん違います。 昔はCPUが非力でしたので、配列は先頭アドレスを渡すもの、と決めて、文法もそのようになりました。 それからCPUも強力になって、構造体なんかは全体を渡せるようになりましたが、配列に関しては文法的な問題もあって、昔のままの仕様です。 というわけで、関数に配列の値だけを渡す方法は存在しません。 呼び出し側でコピーするか、呼び出される側でコピーするか、あるいは構造体でラップしてやるかのどれかですね。
- SaKaKashi
- ベストアンサー率24% (755/3136)
言語によって異なるし、参照渡しとか、値渡しとかあるし。 言語を特定しないと質問にならない。
- Tacosan
- ベストアンサー率23% (3656/15482)
2つ目については「受け取った方で適当にコピーしてください」となるでしょうか. 1つ目は, たぶん「配列全部をコピーしてたら (いろいろと) もったいない」からでは.
補足
一応カテゴリーがC/C++になっているのでわかると思ったのですが、C言語でお願いします。