TStringList = class; PStringItem = ^TStringItem;
TStringItem = record
FString: string;
FObject: TObject;
end; PStringItemList = ^TStringItemList;
TStringItemList = array[0..MaxListSize] of TStringItem; TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer; TStringList = class(TStrings)
private
FList: PStringItemList;
......
......
......
end;procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
Temp: Integer;
Item1, Item2: PStringItem;
begin
Item1 := @FList^[Index1];
Item2 := @FList^[Index2];
Temp := Integer(Item1^.FString);
Integer(Item1^.FString) := Integer(Item2^.FString);
Integer(Item2^.FString) := Temp;
Temp := Integer(Item1^.FObject);
Integer(Item1^.FObject) := Integer(Item2^.FObject);
Integer(Item2^.FObject) := Temp;
end;这段代码是在TStringList源码中的一段,我想请问下,上面的过程和下面的这个过程有分别吗? 为什么要用integer强制转换?
procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
Temp: TStringItem;
begin
Temp := FList^[Index2];
FList^[Index1]:= FList^[Index2];
FList^[Index2]:= Temp;
end;是不是因为 TStringItem 中包含了 FObject: TObject 而不能直接赋值?那如果是类型
TStringItem = record
FString: string;
FTest: Integer;
end;
这个呢?
TStringItem = record
FString: string;
FObject: TObject;
end; PStringItemList = ^TStringItemList;
TStringItemList = array[0..MaxListSize] of TStringItem; TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer; TStringList = class(TStrings)
private
FList: PStringItemList;
......
......
......
end;procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
Temp: Integer;
Item1, Item2: PStringItem;
begin
Item1 := @FList^[Index1];
Item2 := @FList^[Index2];
Temp := Integer(Item1^.FString);
Integer(Item1^.FString) := Integer(Item2^.FString);
Integer(Item2^.FString) := Temp;
Temp := Integer(Item1^.FObject);
Integer(Item1^.FObject) := Integer(Item2^.FObject);
Integer(Item2^.FObject) := Temp;
end;这段代码是在TStringList源码中的一段,我想请问下,上面的过程和下面的这个过程有分别吗? 为什么要用integer强制转换?
procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
Temp: TStringItem;
begin
Temp := FList^[Index2];
FList^[Index1]:= FList^[Index2];
FList^[Index2]:= Temp;
end;是不是因为 TStringItem 中包含了 FObject: TObject 而不能直接赋值?那如果是类型
TStringItem = record
FString: string;
FTest: Integer;
end;
这个呢?
是不是用integer转换后,是只交换了存储空间的访问地址,而实际存储的空间内容不交换?如果是比较复杂的结构体。如:
TRecTest = record
A: integer;
B: Integer;
C: string;
D: TDateTime;
....
X: string;
end;是否有简单的方法来实现呢
procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
Temp: TStringItem;
begin
Temp := FList^[Index2];
FList^[Index1]:= FList^[Index2];
FList^[Index2]:= Temp;
end;如果象楼主这样使用结构体内容交换...情况会比较微妙...
当便用结构体直接赋值时..编译器实际是把相关语句对应替换
system.pas单元中的_CopyRecord...楼主可以仔细看看它的代码.
那代码不大易懂,不过应该可以比较看出,,它是区分结构体里各字段类型不同而不同处理的,
不是单纯块内存复制..
procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
Temp: TStringItem;
begin
Temp := FList^[Index2];
FList^[Index1]:= FList^[Index2];
FList^[Index2]:= Temp;
end;
是比较微秒的。我想可能对一些较复杂的结构体 容易出现错误(如结构体内包含了另外的一些结构体或一些类),所以交换访问地址应该是保险且高效的方法。刚刚也看了下system.pas单元里的_CopyRecord过程,但小弟水平有限,愣是没看懂。我经常编写一些自定义的结构体的列表,RecordList,编写模式就是参考TStringList。上面的方法是为了实现一个结构体列表内部的排序。对于一些较复杂的结构体,如果采用单独对每个项目进行访问地址转换,貌似也是有点繁琐,不知道是否有更好的方法来实现结构体列表的排序呢? 异或者是可以用另一种类型来储存结构体列表。