动态数组与静态数组有何不同?

时间:2012-11-15 13:06:02

标签: arrays delphi gdi+ delphi-xe2

我正在尝试使用GDI绘制多边形。此代码有效:

type
  TPolygon: Array[0..2] of TPoint;

var 
  ACanvas: TGPGraphics;
  MyBrush: TGPLinearGradientBrush;

...

procedure DrawPolygon;
var
  Polygon: TPolygon;
begin
  Polygon[0].X := 1;
  Polygon[0].Y := 5;
  Polygon[1].X := 10;
  Polygon[1].Y := 15;
  Polygon[2].X := 1;
  Polygon[2].Y := 5;

  ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon), length(Polygon));
end;

...

此代码产生 GDI值溢出错误:

type
  TPolygon: Array of TPoint;

var 
  ACanvas: TGPGraphics;
  MyBrush: TGPLinearGradientBrush;

...

procedure DrawPolygon;
var
  Polygon: TPolygon;
begin
  SetLength(Polygon, 3);

  Polygon[0].X := 1;
  Polygon[0].Y := 5;
  Polygon[1].X := 10;
  Polygon[1].Y := 15;
  Polygon[2].X := 1;
  Polygon[2].Y := 5;

  ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon), length(Polygon));
end;

...

唯一的区别是一个点阵列是动态的,另一个是静态的。显然,底层的内存值是不同的,但是以什么方式?

2 个答案:

答案 0 :(得分:8)

您的代码无效。 (首先,FillPolygon中没有TCanvas,其次,多边形需要至少三个顶点。此外,还有一些语法错误,例如:在const声明中代替=。)I建议样本

Polygon[0].X := 1;
Polygon[0].Y := 1;
Polygon[1].X := 1;
Polygon[1].Y := 100;
Polygon[2].X := 100;
Polygon[2].Y := 1;

这是一个漂亮的三角形。无论如何,而

Windows.Polygon(Canvas.Handle, Polygon, 3)

适用于静态数组,你必须这样做

Windows.Polygon(Canvas.Handle, Polygon[0], 3)

表示动态数组。原因是 static 数组在内存中“就地”存储,即直接存储在@Polygon,就像存储一个数字(例如,cardinal)一样,或ShortString,或这些简单类型的记录。相反,如果Polygon是一个动态数组,那么它实际上是一个指向实际可变长度数据的指针(与普通可变长度字符串的工作方式大致相同) )。也就是说,在@Polygon,您只有一个指针NativeUInt。实际数据从这个新地址开始,您可以通过编写@Polygon[0]来获得。

答案 1 :(得分:5)

动态数组已经是指针,因此在将动态数组传递给@时只需删除FillPolygon()运算符:

ACanvas.FillPolygon(MyBrush, PGPPoint(Polygon), length(Polygon));

或者,如果要使用适用于静态和动态数组的语法,请改为:

ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon[0]), length(Polygon));