procedure DynArrayDelete(var A;elSize:Longint;index,Count:Integer);
  var
      len,MaxDelete:Integer;
      P:PLongint;   //4   个字节的长整形指针
  begin
      P:=PLongint(A);//   取的   A   的地址
      if P = nil then
        Exit;
      len := PLongint(PChar(P) - 4)^;   //   变量的长度   ,偏移量   -4
      if index >= len then   //要删除的位置超出范围,退出
        Exit;
      MaxDelete := len - index;   //   最多删除的数量
      Count := Min(Count,   MaxDelete);   //   取得一个较小值
      if Count = 0 then   //   不要求删除
        Exit;
      Dec(len,Count);//   移动到要删除的位置
      MoveMemory(PChar(P)+index*elSize   ,   PChar(P)+(index   +   Count)*elSize   ,   (len-index)*elSize);   //移动内存
      Dec(P);     //移出   “数组长度”位置
      Dec(P);     //移出“引用计数”   位置
      //重新再分配调整内存,len   新的长度.   Sizeof(Longint)   *   2   =   2*Dec(P)
      ReallocMem(P,   len   *   elSize   +   Sizeof(Longint)   *   2);
      Inc(P);   //   指向数组长度
      P^ := len;   //   new   length
      Inc(P);   //   指向数组元素,开始的位置
      PLongint(A) := P;
  end;procedure TForm1.Button2Click(Sender: TObject);
type
  Ttemp=record
    a:integer;
    b:string;
    c:integer;
  end;
var
  temps:array of Ttemp;
  i: Integer;
begin
  setlength(temps,10);
  for i := 0 to 9 do
  begin
    temps[i].a:=i;
    temps[i].b:=IntToStr(i);
    temps[i].c:=i*2;
  end;
  DynArrayDelete(temps,SizeOf(temps),5,1);
  for i := 0 to High(temps) do
  begin
    ShowMessageFmt('%d,%s,%d',[temps[i].a,temps[i].b,temps[i].c]);
  end;
//  ShowMessage(IntToStr(Length(temps)));
  //ShowMessageFmt('%d,%s,%d',[temps[2].a,temps[2].b,temps[2].c]);
end;{
  以上是我从网上弄的一些代码,不过不起作用。在执行完DynArrayDelete(temps,SizeOf(temps),5,1);这一句后,理想情况是数组中的第5个元素没有了,但是结果发现数据根本没有发生变化。
}

解决方案 »

  1.   

    type
      TDynArray = array of integer;procedure DynArrayDelete(var A: TDynArray; index, Count: Integer);
    var
      i: Integer;
    begin
      for i := index to index + Count - 1 do begin
        if (i + Count) > High(A) then break;
        A[i] := A[i + count];
      end;
      setlength(A, Length(A) - Count);
    end;{ TForm1 }procedure Test;
    var
      i :integer;
      a: TDynArray;
    begin
      setlength(a, 11);
      for I := 0 to 10 do
        a[i] := i;
      DynArrayDelete(a, 3, 4);
      for I := low(a) to high(a) do
        showmessage(inttostr(a[i]));
    end;
      

  2.   

    直接movememory是比循环移元素要效率高一点
    但是使用ReallocMem,说明它移动的不是array of这种动态数组,而是原始的内存块
    另外,P:PLongint;  //4  个字节的长整形指针
    好像也不对,P:Pchar; //就行了,是指针占4个字节,而不是指针所指的内容(数组的元素是4个字节)