{$APPTYPE CONSOLE}
uses
  SysUtils;type
  PRec = ^TRec;
  TRec = record
    I : Integer;
    S : String;
  end;
procedure ChangeConstParam(const R:TRec); {const声明。编译器将向例程直接传入参数的地址,而不再是使用参数值的引用}
begin
  PRec(@R)^.I := 6;{使用指针访问该地址,对原值进行直接修改}
  writeln(R.I);     {显示修改成功}
end;var
  Rec : TRec;
{main function.}
begin
  Rec.I := 4;
  writeln(Rec.I);
  ChangeConstParam(Rec);
  writeln(Rec.I); {调试看,修改成功,但是输出后却是原值.不明白???}
  readln;
end.输出结果是4、6、4,为什么最后输出会是4而不是6呢?ChangeConstParam内明显是改变成功.

解决方案 »

  1.   

    >>procedure ChangeConstParam(const R:TRec); 
    應該修改為:
    procedure ChangeConstParam(const R:PRec);
      

  2.   

    不過, 我在delphi試下, 輸出是 4, 6, 6 啊
      

  3.   

    是procedure ChangeConstParam(const R:TRec); 还是
    procedure ChangeConstParam(const R:PRec);??
      

  4.   

    我是d7+win2000pro,输出是464
      

  5.   

    晕啊,我在最后的writeln(Rec.I); 设断点看Rec.I已经变成6了怎么输出就是4。超晕!!!!!!!!
      

  6.   

    Delphi 做了优化:
    begin
      Rec.I := 4;             // 用了 ebx 来保存 4
      writeln(Rec.I);
      ChangeConstParam(Rec);
      writeln(Rec.I);         // Delphi 发现 Rec.I 没有被修改,所以就直接输出了 ebx 里的值
    end;将const 形的参数按地址传,目的在于节省在栈上复制参数的“时间”与“空间”消耗。
    比如这里:Rect 有 8 个字节大,而一个地址只有 4 个字节。
      

  7.   

    所以说:修改 const 的参数、或者修改常数,其结果是“不确定”的。
      

  8.   

    zhengji(看雨飞)说的很对,谢谢,我后来也发现了。取消最优化{$O-}后显示就466.跟踪进去看{$O+}时,值是在ebx保存,{$O-}时值是在eax保存。
      

  9.   

    你这个用法本身就不对!你想达到这个目的完全可以用 var 来声名嘛,何必搞得那么麻烦。