如何使用for循環遍歷G1-G4的記錄字段?迭代記錄字段
TrFireGroup = record
idx: integer;
G1: integer;
G2: integer;
G3: integer;
G4: integer;
FGroup: integer;
MstIdx: integer;
Status: byte;
procedure Clear;
end;
如何使用for循環遍歷G1-G4的記錄字段?迭代記錄字段
TrFireGroup = record
idx: integer;
G1: integer;
G2: integer;
G3: integer;
G4: integer;
FGroup: integer;
MstIdx: integer;
Status: byte;
procedure Clear;
end;
如果你需要維持現有記錄界面結構的兼容性,你可以使用屬性來做到這一點。將值存儲在數組中允許枚舉它們,並且可以使用現有名稱定義屬性以直接以現有方式訪問值。
program Project1;
{$APPTYPE CONSOLE}
type
TGArray = array[0..3] of integer;
TrFireGroup = record
private
FGArr : TGArray;
public
idx: integer;
FGroup: integer;
MstIdx: integer;
Status: byte;
property G1 : integer read FGArr[0] write FGArr[0];
property G2 : integer read FGArr[1] write FGArr[1];
property G3 : integer read FGArr[2] write FGArr[2];
property G4 : integer read FGArr[3] write FGArr[3];
property GArray : TGArray read FGArr;
end;
var
LFireGroup : TrFireGroup;
j : integer;
begin
LFireGroup.G1 := 1;
LFireGroup.G2 := 3;
LFireGroup.G3 := 5;
LFireGroup.G4 := 7;
for j in LFireGroup.GArray do
WriteLn(j);
ReadLn;
end.
如果需要記錄佈局爲二進制兼容(無論何種原因),你可以放棄一些tidyness和重新安排事物
TrFireGroup = record
idx: integer;
GArray : TGArray;
FGroup: integer;
MstIdx: integer;
Status: byte;
procedure Clear;
property G1 : integer read GArray[0] write GArray[0];
property G2 : integer read GArray[1] write GArray[1];
property G3 : integer read GArray[2] write GArray[2];
property G4 : integer read GArray[3] write GArray[3];
end;
離開GArray
作爲一個公共領域,您還可以做索引寫入(而這是不可能的,它作爲一個普通的屬性) - 即:
for i := Low(TGArray) to High(TGArray) do
LFireGroup.GArray[i] := 2*i;
另外,如果你可以放棄for/in
語義你可以定義數組作爲默認屬性和直接引用記錄:
TrFireGroup = record
private
FGArr : TGArray;
procedure SetG(index:integer; Value:integer);
function GetG(index:integer) : integer;
public
property G1 : integer read FGArr[0] write FGArr[0];
property G2 : integer read FGArr[1] write FGArr[1];
property G3 : integer read FGArr[2] write FGArr[2];
property G4 : integer read FGArr[3] write FGArr[3];
property GArray[index:integer]:integer read GetG write SetG; default;
end;
procedure TrFireGroup.SetG(index:integer; Value:integer);
begin
FGArr[index] := Value;
end;
function TrFireGroup.GetG(index: Integer) : integer;
begin
result := FGArr[index];
end;
它可以讓你做的事:
for i := Low(TGArray) to High(TGArray) do
LFireGroup[i] := 2*i;
for i := Low(TGArray) to High(TGArray) do
WriteLn(LFireGroup[i]);
很好的提示你使用的屬性 – fantaghirocco
這可能不是一個好主意,但它是可能的。
procedure Test();
var
i: Integer;
rec: TrFireGroup;
GPtr: PInteger;
value: Integer;
begin
// Initialize rec ...
// Get pointer to first G? field
GPtr := @rec.G1;
// Loop over G fields
for i := 0 to 3 do
begin
// Use value G? field here...
// For example: value := GPtr^;
// Increment pointer, thus moving it with four bytes.
Inc(GPtr);
end;
end;
首先獲得在拍攝的指針(GPtr
)到第一場。
然後,我們通過取消引用指針(GPtr^
)來使用該值。
最後,將指針增加到下一個值(Inc(GPtr)
)。 請注意增量正在將指針移動到所引用類型的大小。
而且,由於我們使用指向Integer的指針(PInteger
),所以Inc
將指針移動到SizeOf(Integer)
,該指針前進到記錄中的下一個字段。
再次,這不是好的做法。
在這種情況下,指針算術是矯枉過正的,除非你在記錄中有數百個字段(這是非常非常罕見的),但如果你真的需要,這是一種方法。
僅供參考,對在Delphi指針和指針運算這裏非常詳細和質量解釋:
如果你是在最近的Delphi版本,只需要G1的電流值。 .G4(即不寫他們)也可以用這種方法:
var
I: Integer;
fg: TrFireGroup;
arr: TArray<Integer>;
begin
...
arr := [fg.G1, fg.G2, fg.G3, fg.G4];
for I in arr do begin
Writeln(I);
end;
...
end;
恕我直言,如果你不需要的二進制兼容性那麼最簡單的方法是使用一個variant record:
TrFireGroup = record
idx: integer;
FGroup: integer;
MstIdx: integer;
Status: byte;
procedure Clear;
case Integer of
0: (G1: integer; G2: integer; G3: integer; G4: integer);
1: (GArr: array[0..3] of integer);
end;
這相當於舊的Delphi absolute
的關鍵字。陣列和四個G?變量在內存中共享相同的點。
總的來說,你沒有。你問來幹什麼?上下文會有幫助。 –
最好的方法 - 將語義上緊密的字段組合到數組'G:array [1..4] Integer;' – MBo
@DavidHeffernan我認爲它會比寫四個肉體更優雅if語句,但我接受你的建議。整個想法從第一次聞起來。 (: – grinner