プログラム func1.rr
/* func1.rr */ def max(A,B) { if (A>B) return(A); else return(B); } end$ 実行例 [123] load("func1.rr"); 1 [124] max(10,20); 20 |
max(A,B) は A と B の大きい方を 戻す関数である. |
def abs(A) { if (A<0) return(-A); return(A); } def mygcd(A,B) { if (abs(B)>abs(A)) { T=A; A=B; B=T;} while (B != 0) { R = A % B; A = B; B = R; } return(A); }
|
[349] mygcd(13,8); 1 [350] mygcd(8,6); 2abs(A) は A の絶対値を戻す関数である. |
プログラム
/*func2.rr*/ def main() { I = 0; print(I); foo(); print(I); } def foo() { I = 100; } main(); end$
|
左のプログラムの実行結果は
[48] load("func2.rr"); 1 [49] 0 0となる. けっして、100とは表示されない. たとえfoo を def foo() { I=100; return(I); }としたろころで同じである. |
プログラム
/* func4.rr */ def xn(N) { Re=0; for (K=0; K<N; K++) { Re = 2*Re+1; } return(Re); }
|
実行例は以下のとうり.
[345] load("func4.rr")$ [346] xn(1); 1 [347] xn(10); 1023 [348] xn(20); 1048575 |
/* func3.rr */ def minmax(A) { N = length(A); if (length(A) == 0) return(0); Max = Min = A[0]; for (K=1; K<N; K++) { if (Max < A[K]) { Max = A[K]; } if (Min > A[K]) { Min = A[K]; } } return([Max,Min]); } end$
|
さて, 前の節で引数はその関数の実行中のみ存在する変数であると
説明した.
ベクトルやリストが引数として関数にわたされたときは内部的にはその先頭
アドレスが関数にわたされベクトルやリスト自体は複製されていないことを
了解しておく必要がある.
このことを明確に理解するには, C のポインタや機械語の間接アドレシングの
仕組みをきちんと勉強する必要があるかもしれない.
次のプログラムは, あたえらたベクトルのすべての成分を 1 にかえる.
def vector_one(V) { N = size(V)[0]; for (I=0; I<N; I++) { V[I] = 1; } } end$
|
実行例:
[349] A=newvect(10); [ 0 0 0 0 0 0 0 0 0 0 ] [350] vector_one(A); 1 [351] A; [ 1 1 1 1 1 1 1 1 1 1 ]このようにベクトル A のすべての要素が 1 にかきかえれた. size(V)[0] は ベクトル V の長さを戻す. |
V = 0;を加えると,
[351] A; [ 1 1 1 1 1 1 1 1 1 1 ]となるだろうか. それとも,
[351] A; 0となるだろうか? 関数実行中のメモリの様子を考えてどちらか答えよ.
図 8.3 にあるように, 関数にベクトルがわたされても その複製は作成されない. これが普通の引数と違う点である.
|
プログラム言語 Pascal では引数の配列を関数内で複製する(clone)か 複製しないかを指示できる. キーワード var をつけると複製せず, つけないと複製する. プログラム言語 C や Java の場合は複製はされない. 複製は明示的におこなう必要がある. Asir でもベクトルやリストの複製は明示的におこなう必要がある. 代入演算子を用いても複製されていないことに注意. たとえば, A がベクトルとするとき B に代入しても 複製はつくられない. 次の例を見よ.
[347] A=newvect(10); [ 0 0 0 0 0 0 0 0 0 0 ] [348] B=A; [ 0 0 0 0 0 0 0 0 0 0 ] [349] B[0]=100; 100 [350] B; [ 100 0 0 0 0 0 0 0 0 0 ] [351] A; [ 100 0 0 0 0 0 0 0 0 0 ]A がベクトルとするとき複製(close)はつぎのようにおこなう.
N=size(A)[0]; B=newvect(N); for (I=0; I<N; I++) { B[I] = A[I]; }