***すれ立てるまでもない質問はここで 第18刷***

このエントリーをはてなブックマークに追加
446439
>>444
しかたねーな。ざっくり説明するから、一回で理解してくれよ。

変数といった場合、実際には二つの異なる意味がある。

 i = 1; // 変数 i に対応するメモリ領域に 1 という値を書き込む
 print i; // 変数 i に対応するメモリ領域から値を読み出し、出力する

このうち、アドレスを意味する上の場合を「右辺値」、値を意味する下の場合を「左辺
値」と呼ぶ。

call by value
 引数を右辺値として評価し、その結果を呼び出す関数に渡す
 呼び出された関数内で値を変更しても、それは呼び出し元には影響しない

call by reference / variable
 引数を左辺値として評価し、その結果を呼び出す関数に渡す
 呼び出された関数内で値を変更すると、それは呼び出し元に影響する
 当然の制約として、引数が左辺値を持たない場合 (たとえば 1 のような数値)
 には、そのままでは使えない。

C だと全て call by value。ただし定義を見ても明らかなように、明示的に変数の
アドレスを取得して call by value で渡してやれば、call by reference と同等の
効果を得られる。C++ だとリファレンスを使うことで call by reference になるし、
VB や Pascal なら var をつけてやればいい。

call by name は、上の二つと引数を評価するタイミングが違う。上の二つは
関数呼び出しの「前」に引数を評価するけど、call by name では呼び出され
た関数内で仮引数を使う瞬間に、そこを実引数で置換する。

たとえば triple(int) という関数に int 型を返す foo() という関数を渡したとしよう。

 triple(int n) { n * n * n; }

call by name, call by value であれば foo() は一度呼ばれるだけだが、call by
name だと 3 回呼ばれるわけ。