>>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 回呼ばれるわけ。