スレッドを学んでいたところ、
Delphi6 Personalのスレッドサンプル("Threads")のソース中に下記の記述がありました。
>procedure TQuickSort.Sort(var A: array of Integer);
>
> procedure QuickSort(var A: array of Integer; iLo, iHi: Integer);
> var
> Lo, Hi, Mid, T: Integer;
> begin
> Lo := iLo;
> Hi := iHi;
> Mid := A[(Lo + Hi) div 2];
> repeat
> while A[Lo] < Mid do Inc(Lo);
> while A[Hi] > Mid do Dec(Hi);
> if Lo <= Hi then
> begin
> VisualSwap(A[Lo], A[Hi], Lo, Hi);
> T := A[Lo];
> A[Lo] := A[Hi];
> A[Hi] := T;
> Inc(Lo);
> Dec(Hi);
> end;
> until Lo > Hi;
> if Hi > iLo then QuickSort(A, iLo, Hi);
> if Lo < iHi then QuickSort(A, Lo, iHi);
> if Terminated then Exit;
> end;
>
>begin
> QuickSort(A, Low(A), High(A));
>end;
procedureの中にprocedureがあります。
これはなんていう記述方法なのでしょうか?
また、目的、利点は?
私はよく使います。
procedure TQuickSort.Sort(var A: array of Integer);
の中でのみ使うための関数です。
他から参照できないため、結構適当に名前を付けれたり、Exitで抜けたりと慣れると結構便利です。
たしか、ローカル関数とか言うんじゃなかったけ。
使い方は、ママんさんの言う通り。
後は、再帰を使う時にこういう書き方をすると
わかりやすいかも。
私も初めてみたときには「へー、こんなことができるんだ」と思ったものです。
引数(パラメータ)をだらだら付けなくても良いので重宝しています。
例1
procedure Sample;
// これはアウト procedure rootin(i, j: Integer); が正しい
procedure rootin;
var
k: Integer;
begin
k := i + j; // i, j は未定義の識別子
・・・・
end;
var
i, j: Integer;
begin
rootin; // ここも rootin(i, j); でなければならない
・・・・
end;
例2
procedure Sample;
var
i, j: Integer; // 前方で定義をしておく
procedure rootin; // これはセーフ
var
k: Integer;
begin
k := i + j;
・・・・
end;
begin
rootin;
・・・・
end;
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=075246
↑ここで「ローカル関数」について興味深いやりとりがされていますね。
そこでも書かれていますが、「ローカル関数」は入れ子関数ではない場合もあるので、入れ子になった関数は「関数内関数(手続き内手続き)」と呼ぶ方が適切ではないかと...
みなさん、ありがとうございます。
ときおりサンプルソースにこの記述があって、少々混乱していました。
みなさんのおかげでよく分かりました。
ありがとう。
ツイート | ![]() |