変数パラメータの不思議


はざま  2008-12-10 09:34:05  No: 32881

いつもお世話になっております.
はざまです.

先日Mr.XRAYさんのHPにて
http://mrxray.on.coocan.jp/Delphi/plSamples/780_FileInfoListETC.htm#05
FrontPage : http://mrxray.on.coocan.jp/index.htm
「指定フォルダ内の指定拡張子のファイルを取得」
の項目がありましたので,実験しました.
サンプルではボタンのクリックイベントのところを手続きにして
チェックリストボックスのクリックでリスト一覧できるようにしたものです.

具体的には以下のとおりです.

procedure TForm1.GetFilesListAllExt(APath, Ext: String;
  FileList: TStringList);
var
    SearchPath : String;
    SearchRec  : TSearchRec;
begin
    if FindFirst(APath+'*.*', faAnyFile,SearchRec)=0 then begin
      repeat
        if not ((SearchRec.Name='..') or (SearchRec.Name='.')) then begin
          if SearchRec.Attr=faDirectory then begin
            SearchPath:=IncludeTrailingPathDelimiter(APath+SearchRec.Name);
            GetFilesListAllExt(SearchPath,Ext,FileList);
          end else begin
            if ExtractFileExt(SearchRec.Name)=Ext then begin
              FileList.Add(APath+SearchRec.Name);
              Inc(FilesCount);
            end;
          end;
        end;
      until FindNext(SearchRec)<>0;
      FindClose(SearchRec);
    end;
end;

procedure TForm1.CheckListbox1Click(Sender: TObject);
var
    FList    : TStringList;
    BasePath : String;
    AExt     : String;
    i        : Integer;
begin
    FilesCount:=0;
    BasePath:=ExtractFileDir(ParamStr(0));
   // if SelectDirectory('検索フォルダ指定', '',BasePath) then begin
      BasePath:=IncludeTrailingPathDelimiter(BasePath)+'BU\';
      AExt    :='.doc';
      FList   :=TStringList.Create;
      FList.Clear;
      checkListbox1.Items.Clear;
      try
        GetFilesListAllExt(BasePath,AExt,FList);
        checkListbox1.Items.BeginUpdate;
        //checkListbox1.Columns[0].Width:=500;
        for i:=0 to FList.Count-1 do begin
          checkListbox1.Items.Add(FList[i]);
        end;
        checkListbox1.Items.EndUpdate;
      finally
        FreeAndNil(FList);
      end;
end;

これで問題なく動いたのですが,
大変恐縮なのですがほぼ丸コピなので

procedure TForm1.GetFilesListAllExt(APath, Ext: String;
  FileList: TStringList);

は本当のところ

procedure TForm1.GetFilesListAllExt(APath, Ext: String;
  var FileList: TStringList);

と変数パラメータにするべき?だと気がつきました.
とここが疑問なんですが
値パラメータでも変数パラメータでも問題なく動きます.
クリックイベントで手続きを実行して,そのとき渡す変数を使用しているので
変数パラメータでないといけない気がするのです.

もちろんヘルプで変数パラメータの項は読み返しましたが,何も納得できるものは得られませんでした.
VB出身の初心者なのですが,どなたかご教授お願いします.


えーと  2008-12-10 12:59:41  No: 32882

>変数パラメータにするべき?だと気がつきました.

オブジェクト参照は実質を指すポインタなんだよ。だから、値パラメータで渡しても
実質を参照できるんだ。var をつけると、ポインタのポインタとなって、やはり実質を参照できる。これは、関数の中で参照そのものを変更する時に使う。今回は、実質を参照してそのメソッドを関数の中で使用するだけだから、var をつけない方が副作用がなくてよいんだ。


Fusa  2008-12-11 22:40:22  No: 32883

そうですね。FileList: TStringList、っていうオブジェクトは
FileList自体が参照なんですよね。

だから、varをつけなくってもちゃんと動くんです。
Delphiのオブジェクトは参照になっています。

それでvar付きと無しを区別するとよいですよ。

integerとかは、varの有無ではざまさんが考えるとおりの動きをしますよ。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加