如何交换二维数组的两行,为什么它会起作用?
总结:
请查看以下来自 David、Uwe 和其他专家的评论。
=================================================== ================================
以下代码交换二维动态双精度值数组中的两行。我想知道:(1)下面的代码是否是交换二维数组的两行的最佳实践?如果不是,那么完成此类工作的最佳实践是什么? (2) 为什么下面的代码会起作用?我的意思是,二维数组不是连续连续的内存部分吗?下面的代码是否只能靠运气才能工作?任何建议表示赞赏!
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TAADouble = array of array of Double;
TForm5 = class(TForm)
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form5: TForm5;
procedure SwapRows(arr: TAADouble; row0, row1: Integer);
implementation
{$R *.dfm}
procedure SwapRows(arr: TAADouble; row0, row1: Integer);
var
Tmp: Integer;
begin
{$IFDEF FPC}
Tmp := PtrUInt(arr[row0]);
PtrUInt(arr[row0]) := PtrUInt(arr[row1]);
PtrUInt(arr[row1]) := Tmp;
{$ELSE}
Tmp := Integer(arr[row0]);
Integer(arr[row0]) := Integer(arr[row1]);
Integer(arr[row1]) := Tmp;
{$ENDIF}
end;
procedure TForm5.FormShow(Sender: TObject);
var
tmpArray: TAADouble;
I, J: Integer;
rowStr: string;
begin
SetLength(tmpArray, 10, 10);
rowStr := '';
for I := 0 to 9 do
for J := 0 to 9 do
tmpArray[I][J] := I * J;
for I := 0 to 9 do
begin
rowStr := '';
for J := 0 to 9 do
rowStr := rowStr + FloatToStr(tmpArray[I][J]) + ' ';
OutputDebugString(PWideChar(rowStr));
end;
SwapRows(tmpArray, 3, 4);
for I := 0 to 9 do
begin
rowStr := '';
for J := 0 to 9 do
rowStr := rowStr + FloatToStr(tmpArray[I][J]) + ' ';
OutputDebugString(PWideChar(rowStr));
end;
end;
end.
Summarization:
Please check the comments below from David, Uwe, and other experts.
================================================================================
The following code swaps two rows in a two-dimensional, dynamic array of double values. I am wondering: (1) whether the following code is a best practice of swapping two rows of a two-dimensional array? If not, then what is the best practice to do this kind of job? (2) why would the following code work? I mean, isn't two-dimensional array a continuous contiguous section of memory? Does the following code work only by luck? Any suggestion is appreciated!
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TAADouble = array of array of Double;
TForm5 = class(TForm)
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form5: TForm5;
procedure SwapRows(arr: TAADouble; row0, row1: Integer);
implementation
{$R *.dfm}
procedure SwapRows(arr: TAADouble; row0, row1: Integer);
var
Tmp: Integer;
begin
{$IFDEF FPC}
Tmp := PtrUInt(arr[row0]);
PtrUInt(arr[row0]) := PtrUInt(arr[row1]);
PtrUInt(arr[row1]) := Tmp;
{$ELSE}
Tmp := Integer(arr[row0]);
Integer(arr[row0]) := Integer(arr[row1]);
Integer(arr[row1]) := Tmp;
{$ENDIF}
end;
procedure TForm5.FormShow(Sender: TObject);
var
tmpArray: TAADouble;
I, J: Integer;
rowStr: string;
begin
SetLength(tmpArray, 10, 10);
rowStr := '';
for I := 0 to 9 do
for J := 0 to 9 do
tmpArray[I][J] := I * J;
for I := 0 to 9 do
begin
rowStr := '';
for J := 0 to 9 do
rowStr := rowStr + FloatToStr(tmpArray[I][J]) + ' ';
OutputDebugString(PWideChar(rowStr));
end;
SwapRows(tmpArray, 3, 4);
for I := 0 to 9 do
begin
rowStr := '';
for J := 0 to 9 do
rowStr := rowStr + FloatToStr(tmpArray[I][J]) + ' ';
OutputDebugString(PWideChar(rowStr));
end;
end;
end.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你问:
嗯,是的,您依赖于特定于实现的细节。
事实上,正确的编写方法是非常自然和简单的:
您需要为行声明一个中间类型 TDoubleArray,以便您可以在交换例程中执行对 Temp 的赋值。
二维常量大小数组
是连续的内存块。
您拥有的二维动态大小数组不是。事实上,它甚至可能是参差不齐的,因为行具有不同数量的列。所以你可以有一个三角矩阵。
You ask:
Well, yes, you are relying on implementation specific details.
In fact the correct way to write it is perfectly natural and simple:
You need to declare an intermediate type for the row, TDoubleArray, so that you can perform the assignment to Temp in the swap routine.
A 2D constant size array
is a contiguous block of memory.
A 2D dynamically size array as you have is not. Indeed it can even be ragged in the sense that the rows have different numbers of columns. So you can have, say, a triangular matrix.
动态数组被实现为指向表示该数组的内存块的指针。所以二维动态数组实际上是一个指向指针数组的指针。这就是为什么交换行(-指针)实际上有效。
请参阅大卫的回答以获得更简洁的方法。
更新:
如果您被允许使用泛型,您不妨这样做:
A dynamic array is implemented as a pointer to a memory block representing that array. So a two-dimensional dynamic array is actually a pointer to an array of pointers. Thats why swapping the row(-pointer)s actually works.
See David's answer for a cleaner approach.
Update:
If you are allowed to use generics you might as well do this: