如何在整数/实数的二维动态数组上使用移动?

问题描述 投票:0回答:1

在我的Delphi Rio应用程序中,我使用了很多2维动态数组。为了加快某些操作,我想使用move命令而不是copy。我可以使它适用于一维动态数组,但是对于2D或更高版本,我不能。对于第二维,在发出move(A,B,size)之后,数组B的元素指向数组A的元素的相同内存地址,即B引用A。实际上,我想与A的B分开工作。请参见我的代码:

program ProjArrayMove;

    {$APPTYPE CONSOLE}

    {$R *.res}

    uses
      System.SysUtils;

    Type

         Arrayint   = Tarray<Integer>;
         Arrayreal  = TArray<Real>;
         MatrixInt  = Array of Arrayreal;
    var
        vectorA, vectorB : Arrayint;
        matA, matB       : MatrixInt;
        idx,idy          : integer;
    begin
         TRY
           // =============== TESTING WITH 1D DYNAMIC ARRAYS OF SIMPLE TYPES ==================
              Writeln('==============================================================');
              Writeln('========= TESTING 1-DIMENSION DYNAMIC ARAYS ==================');
              Writeln('===============================================================');

              readln;
              Writeln('------- Fills Vector A ----------------------------');
              SetLength(vectorA,5);
              for idx :=0 to 4 do
              begin
                    vectorA[idx] := (idx+1) * 10;
                    Writeln('VectorA : [' + idx.tostring + ']  '  +
                              Format('Address : %p  [%d]' ,[PPointer(@VectorA), VectorA[idx] ]) );
              end;

              readln;
              Writeln('--------------------------------------------------');
              Writeln('------ Moves VectorA to VectorB ------------------');

              SetLength(VectorB,Length(vectorA));
              Move(VectorA[0],VectorB[0],SizeoF(VectorA[0]) * Length(VectorA));
              for idx :=0 to 4 do
                    Writeln('VectorB : [' + idx.tostring + ']  '  +
                              Format('Address : %p  [%d]' ,[PPointer(@VectorB), VectorB[idx] ]) );

              readln;
              Writeln('---------------------------------------------------');
              Writeln('------ Changes VectorB contents  ------------------');

              for idx :=0 to 4 do
              begin
                    vectorB[idx] := (idx+1) * 200;
                    Writeln('VectorB : [' + idx.tostring + ']  '  +
                              Format('Address : %p  [%d]' ,[PPointer(@VectorB), VectorB[idx] ]) );
              end;

              readln;
              Writeln('--------------------------------------------------');
              Writeln('------ Checking Vector A  ------------------------');

              for idx :=0 to 4 do
                    Writeln('VectorA : [' + idx.tostring + ']  '  +
                              Format('Address : %p  [%d]' ,[PPointer(@VectorA), VectorA[idx] ]) );
              Writeln;
              Writeln('CONCLUSION : ===>>  MOVE command works fine for 1-Dimension Dynamic Arrays!');
              readln;


    //=========================== TESTING WITH MATRIX 2D DYNAMIC ARRAYS OF SIMPLE TYPES ==================

              Writeln('===============================================================');
              Writeln('========= TESTING 2-DIMENSIONS DYNAMIC ARAYS ==================');
              Writeln('===============================================================');
              readln;
              Writeln('------ Fills MatrixA -----------------------------');
              SetLength(matA,5,2);
              for idx :=0 to 4 do
                 for idy := 0 to 1 do
                 begin
                       matA[idx][idy] := (idx +1) * (idy +1);
                        Writeln('Mat A : [' + idx.tostring + '][' + idy.tostring +']  '  +
                                  Format('Address : %p  [%f]' ,[PPointer(@matA[idx][idy]), matA[idx][idy] ] ));
                 end;

              readln;
              Writeln('-------------------------------------------------');
              Writeln('------ Move MatrixA to MatrixB ------------------');

              SetLength(matB,length(matA));
              //move(matA[0],MatB[0],Sizeof(matA[0]) * length(matA));
              move(matA,MatB,Sizeof(matA[0]) * length(matA));
              for idx :=0 to 4 do
              begin
                   Setlength(MatB[idx],length(matA[idx]));
                   //Move(matA[idx][0],matB[idx][0],sizeof(matB[idx][0]) * length(matB[idx]) );
                   Move(matA[idx],matB[idx],sizeof(matB[idx][0]) * length(matB[idx]) );
                   for idy := 0 to 1 do
                   begin
                          Writeln('Mat B : [' + idx.tostring + '][' + idy.tostring +']  '  +
                                  Format('Address : %p  [%f]' ,[PPointer(@matB[idx][idy]), matB[idx][idy] ] ));

                   end;
              end;

              readln;

              Writeln('-------------------------------------------------');
              Writeln('------ Change MatrixB content  ------------------');
              readln;

              for idx :=0 to 4 do
                 for idy := 0 to 1 do
                 begin
                      matB[idx][idy] := 100.5 * (idx+1) * (idy +1);
                      Writeln('Mat B : [' + idx.tostring + '][' + idy.tostring +']  '  +
                              Format('Address : %p  [%f]' ,[PPointer(@matB[idx][idy]), matB[idx][idy] ] ));
                 end;

              Writeln('-------------------------------------------------');
              Writeln('------ Checking Matrix A ------------------------');
              readln;

              for idx :=0 to 4 do
                 for idy := 0 to 1 do
                        Writeln('Mat A : [' + idx.tostring + '][' + idy.tostring +']  '  +
                                 Format('Address : %p  [%f]' ,[PPointer(@matA[idx][idy]), matA[idx][idy] ] ));


              Writeln;
              Writeln('CONCLUSION : ===>>  MOVE command DOES NOT WORK on 2-Dimensions Dynamic Arrays!');
              readln;

          except
            on E: Exception do
                 begin
                       Writeln(E.ClassName, ': ', E.Message);
                       readln;
                 end;
          end;
    end.

第二维的移动命令中是否存在某些错误或缺失?

谢谢!

arrays delphi move dynamic-arrays
1个回答
0
投票

您的问题从这里开始:

Move(matA, matB, Sizeof(matA[0]) * Length(matA));

您正在将动态数组传递给Move。动态数组被实现为指向数组第一个元素的指针。因此,您正在覆盖指针。

也许您想做这样的事情:

Move(matA[0], matB[0], Sizeof(matA[0]) * Length(matA));

但是您也不想这样做。这是在托管类型上使用Move,这与您在your previous question中犯的错误完全相同。

实际上,如果仅删除该行代码,它应该可以工作。注意:我没有详细检查,因此可能还有其他缺陷。

您的代码确实非常复杂,很难看到正在发生什么。至少您的某些问题是由于您的代码过于混乱所致。尝试停止将大量代码放入单个过程中。将代码分成较小的部分,然后在驱动程序例程中将这些较小的部分粘合在一起。

您想使用这样的功能:

function CloneMatrixInt(const matrix: array of ArrayInt): MatrixInt;
var
  i: Integer;
begin
  SetLength(Result, Length(matrix));
  for i := 0 to High(Result) do
    Result[i] := Copy(matrix[i]);
end;

请注意,这与您先前的问题的答案基本相同。为什么会这样?

您需要停止将MatrixInt视为多维数组。不是。它只是一个数组。这是一个数组,其元素又是数组。从技术上讲,它是一个锯齿状的数组。但是,您只需要将其视为一维数组即可。

因此,用于克隆它的功能的操作如下:

  1. 分配目标数组。
  2. 遍历目标数组,从源数组中克隆每个元素。

与您上一个问题的过程完全相同。那里我们有一个记录数组,并带有一个克隆记录的函数。但是,因为我们已经将克隆外部数组的任务与克隆数组的元素分开了,所以结果代码基本相同。

现在假设您有一个MatrixInt数组。假设

type
  ArrayMatrixInt = array of MatrixInt;

嗯,克隆这样的东西:

function CloneArrayMatrixInt(const arrayMatrix: array of MatrixInt): ArrayMatrixInt;
var
  i: Integer;
begin
  SetLength(Result, Length(arrayMatrix));
  for i := 0 to High(Result) do
    Result[i] := CloneMatrixInt(matrix[i]);
end;

猜猜是什么,和以前完全一样的代码!

© www.soinside.com 2019 - 2024. All rights reserved.