プロが教える店舗&オフィスのセキュリティ対策術

JavaやCでの関数の引数の渡し方についてですが、以下の(1)〜(3)の質問への回答お願い致します。

(1)通常の値のcall by valueでの動作ですが、実引数の変数をaとして、仮引数の変数をb
とした場合、変数aの中身(value)が変数bにコピーされるのでしょうか。それとも変数aが
いったんtempの変数にコピーされて、それが変数bにコピーされるのでしょうか?
(2)CのポインタやJavaの参照が渡される場合、いったんそれらがtempの変数に値として
書き込まれて、そのコピーが仮引数の渡されるという理解でいいでしょうか?
(3)CやJavaにはありませんが、call by referenceの場合、実引数のアドレスが、そのまま
仮引数に渡されるという理解でいいでしょうか?

質問者からの補足コメント

  • 参照渡しとポインタの値渡しについて調べていると、あるC++の書籍で次のような記述がありました。
    「これは、呼び出しを行う側に秘密があるからです。呼び出し先が参照になっていたらアドレスを渡すし、単なる引数ならコピーを作って渡すのです。ポインタによるアドレス渡しのときは、値渡しと同じですから単なる引数扱いです。」
    この記述から(2)、(3)の動作の違いを書いてみました。この動作の違いが、参照渡しとポインタの値渡しで何かの差異を生みそうな気もしたので確認のため質問させていただきました。
    (1)は(2)との整合性というか、色々書籍を読んでいると一度コピーしたものを渡しているという様に書かれているものもあるので、一体どっちが正しいのだろうと思ったからです。(1)に関しては、私も一旦コピーしようがしまいが結果は同じだという事は理解しています。
    何か重要な事を理解してない気がして質問しています。

    No.2の回答に寄せられた補足コメントです。 補足日時:2020/12/19 09:18
  • 頭の中がぐちゃぐちゃになっていました。多分以下の動作で正しいとおもいます。

    (1)a=1でf(a)で呼んだ場合、実引数の変数(名前は何でも良い)にaの内容(1)がコピーされて、そのコピーされた中身(value)が仮引数にコピーされる。
    (2)a=1でf(&a)で呼んだ場合、実引数の変数(名前は何でも良い)にaのアドレス(ポインタ)がコピーされて、そのコピーされた中身(value)が仮引数にコピーされる。
    (3)a=1でf(a)で呼んだ場合、仮引数に&が付いていたら、aのアドレスがそのまま仮引数にコピーされる。

    これでもし間違っている様であれば、ご指摘ください。

      補足日時:2020/12/19 15:17

A 回答 (4件)

間違ってます。


> (1)a=1でf(a)で呼んだ場合、実引数の変数(名前は何でも良い)にaの内容(1)がコピーされて、そのコピーされた中身(value)が仮引数にコピーされる。

実引数の変数aの中身1が仮引数にコピーされる。

> (2)a=1でf(&a)で呼んだ場合、実引数の変数(名前は何でも良い)にaのアドレス(ポインタ)がコピーされて、そのコピーされた中身(value)が仮引数にコピーされる。

実引数aのアドレスが仮引数にコピーされる。


> (3)a=1でf(a)で呼んだ場合、仮引数に&が付いていたら、aのアドレスがそのまま仮引数にコピーされる。

実引数aのアドレスが仮引数にコピーされて、仮引数アクセスの時はそのアドレス経由で間接参照される。

> 一度コピーしたものを渡しているという様に書かれているものもあるので、

渡すときにコピーしているという意味です。
    • good
    • 0
この回答へのお礼

色々読んでいると頭の中がぐしゃぐしゃになってしまいました。素直に考えれば良いのですね。おっしゃっていることが正しと思います。ありがとう御座いました。

お礼日時:2020/12/20 00:53

その辺の細かい話は言語や処理系によっても変わる可能性がある (実際規格上の Java の動作と現実的なたいていの C の処理系とでは違う) ので, そういうことを無視して詳細を語ることは不可能かつ無意味.



さらにいえば文章も意味不明. 「実引数の変数(名前は何でも良い)」ってなに? 「仮引数に&が付いていたら」とはどういうこと?
    • good
    • 0

(1) 両方とも結果は同じです。


(2) 上記参照
(3) 仮引数をアクセスすると実引数がアクセスされます。
仕組み的には実引数のアドレスが渡されて、関数側では、仮引数へのアクセスがそのアドレスを経由しての実引数へのアクセスに置き換わります。

(1)(2) 直接コピーしようが、ワンクッション置いてコピーしようが、効果は同じで言語のレベルでそれらを区別することは出来ません。
何故そんなことを疑問に思ったのでしょうか?郵便物を送るときに途中幾つの郵便局を経由するのか気になってしょうがないみたいな質問です。
この回答への補足あり
    • good
    • 0

どういう方法を想定しているのかわからんけど.



まず Java は仕様上の動作が確定しているので簡単. 全ての実引数 (と存在するならメソッド呼び出しの対象となるオブジェクト) を評価して値を決定し, それらを (呼び出されるメソッドのローカル変数である) 仮引数にコピーしてメソッドを実行する.

C だと「仕様上の動作」はあっても「結果的にそれと同じ動作になるならいい」ので厳密にいえば「処理系に聞いてくれ」なわけだが, 典型的な動作としては実引数の値を決定したあと「それらの値があるところ」に仮引数を設定する.

ついでにいうと, 参照をアドレスだと思い込むのはよくない. 実装上は「各オブジェクトのアドレスを覚えている配列へのインデックス」であってもいい.
    • good
    • 2

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!