真的C静态局部变量替换?

时间:2011-12-11 11:29:00

标签: delphi pascal

只是试图在ObjectPascal / Delphi中实现C / C ++静态局部变量的类似功能。 让我们在C中有以下功能:

bool update_position(int x, int y)
{
    static int dx = pow(-1.0, rand() % 2);
    static int dy = pow(-1.0, rand() % 2);

    if (x+dx < 0 || x+dx > 640)
        dx = -dx;
    ...
    move_object(x+dx, y+dy);
    ...
}

使用类型常量作为静态变量替换的等效ObjectPascal代码无法编译:

function UpdatePosition(x,y: Integer): Boolean;
const
  dx: Integer = Trunc( Power(-1, Random(2)) );  // error E2026
  dy: Integer = Trunc( Power(-1, Random(2)) );
begin
  if (x+dx < 0) or (x+dx > 640) then
    dx := -dx;
  ...
  MoveObject(x+dx, y+dy);
  ...
end;

[DCC错误] test_f.pas(332):E2026预期的常量表达

那么一次性传递初始化的本地变量是否有某种方式?

2 个答案:

答案 0 :(得分:6)

在Delphi中没有直接等效的C静态变量。

可写入类型常量(请参阅user1092187's answer)几乎相同。它具有相同的作用域和实例化属性,但不允许使用C或C ++静态变量进行一次性初始化。在任何情况下,我认为应该将可写入的类型常量作为古怪的历史脚注避开。

您可以使用全局变量。

var
  dx: Integer;
  dy: Integer 

function UpdatePosition(x,y: Integer): Boolean;
begin
  if (x+dx < 0) or (x+dx > 640) then
    dx := -dx;
  ...
  MoveObject(x+dx, y+dy);
  ...
end;

您必须在initialization部分进行一次性初始化:

initialization
  dx := Trunc( Power(-1, Random(2)) );
  dy := Trunc( Power(-1, Random(2)) );

当然,与C静态变量的有限范围不同,这会使全局命名空间变得混乱。在现代Delphi中,您可以将它全部包装在一个类中,并使用类方法,类变量class constructors的组合来避免污染全局命名空间。

type
  TPosition = class
  private class var
    dx: Integer;
    dy: Integer;
  private
    class constructor Create;
  public
    class function UpdatePosition(x,y: Integer): Boolean; static;
  end;

class constructor TPosition.Create;
begin
  dx := Trunc( Power(-1, Random(2)) );
  dy := Trunc( Power(-1, Random(2)) );
end;

class function TPosition.UpdatePosition(x,y: Integer): Boolean;
begin
  // your code
end;

答案 1 :(得分:4)

启用"Writable typed constants"

{$J+}
procedure abc;
const
  II: Integer = 45;

begin
  Inc(II);
  ShowMessage(IntToStr(II));
end;
{$J-}

procedure TForm1.Button1Click(Sender: TObject);
begin
  abc;
  abc;
  abc;
end;