Hallo,
ich bin gerade dabei einen kleinen Formel-Parser zu programmiern, allerdings nur zu grafischen Darstellung der Formeln.
Doch darum geht es bei meinem Problem nicht direkt:
Ich habe zum Speichern der Zahlen und Operanten eine eigene Liste definiert, die ich mir von "TList" abgeschaut habe.
Deren Einträge soll allerdings eben nicht vom Typ "Pointer" sein, sondern hiervon:
Delphi-Quelltext
1: 2: 3: 4: 5:
| type TFormelTeil= packed record Str:String; Art:Byte; End; |
Die folgende Unit beinhaltet mein Resultat:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216:
| unit FormelListUnit;
interface
uses Windows, Messages, Classes ,Dialogs;
type TFormelTeil= packed record Str:String; Art:Byte; End;
PFTeile = ^TFTeile; TFTeile = array[0..MaxListSize - 1] of TFormelTeil;
TFTList = class(TObject) private FFTList: PFTeile; FCount: Integer; FCapacity: Integer; protected function Get(Index: Integer): TFormelTeil; procedure Grow; virtual; procedure SetCapacity(NewCapacity: Integer); procedure SetCount(NewCount: Integer); procedure Put(Index: Integer; Item: TFormelTeil); public procedure PutInLast(Item: TFormelTeil); destructor Destroy; override; function Add(Item: TFormelTeil): Integer; procedure Clear; virtual; procedure Delete(Index: Integer); procedure Exchange(Index1, Index2: Integer); function Expand: TFTList; function First: TFormelTeil; procedure Insert(Index: Integer; Item: TFormelTeil); function Last: TFormelTeil; procedure Move(CurIndex, NewIndex: Integer); property Capacity: Integer read FCapacity write SetCapacity; property Count: Integer read FCount write SetCount; property Items[Index: Integer]: TFormelTeil read Get write Put; default; property List: PFTeile read FFTList;
function Str(Index: Integer): String; function Art(Index: Integer): Byte; end;
implementation
function TFTList.Art(Index: Integer): Byte; begin Result:=0; if (Index < 0) or (Index >= FCount) then exit; Result := Get(Index).Art; end;
function TFTList.Str(Index: Integer): String; begin Result:=''; if (Index < 0) or (Index >= FCount) then exit; Result := Get(Index).Str; end;
destructor TFTList.Destroy; begin Clear; end;
function TFTList.Add(Item: TFormelTeil): Integer; begin Result := FCount; if Result = FCapacity then Grow; Items[Result]:= Item; Inc(FCount); end;
procedure TFTList.Clear; begin SetCount(0); SetCapacity(0); end;
procedure TFTList.Delete(Index: Integer); var Temp: TFormelTeil; begin if (Index < 0) or (Index >= FCount) then exit;
Temp := Items[Index]; Dec(FCount); if Index < FCount then System.Move(FFTList^[Index + 1], FFTList^[Index],(FCount - Index) * SizeOf(TFormelTeil)); end;
procedure TFTList.Exchange(Index1, Index2: Integer); var Item: TFormelTeil; begin if (Index1 < 0) or (Index1 >= FCount) then exit; if (Index2 < 0) or (Index2 >= FCount) then exit; Item := FFTList^[Index1]; FFTList^[Index1] := FFTList^[Index2]; FFTList^[Index2] := Item; end;
function TFTList.Expand: TFTList; begin if FCount = FCapacity then Grow; Result := Self; end;
function TFTList.First: TFormelTeil; begin Result := Get(0); end;
function TFTList.Get(Index: Integer): TFormelTeil; begin if (Index < 0) or (Index >= FCount) then exit; Result := FFTList^[Index]; end;
procedure TFTList.Grow; var Delta: Integer; begin if FCapacity > 64 then Delta := FCapacity div 4 else if FCapacity > 8 then Delta := 16 else Delta := 4; SetCapacity(FCapacity + Delta); end;
procedure TFTList.Insert(Index: Integer; Item: TFormelTeil); begin if (Index < 0) or (Index > FCount) then exit; if FCount = FCapacity then Grow; if Index < FCount then System.Move(FFTList^[Index], FFTList^[Index + 1], (FCount - Index) * SizeOf(TFormelTeil)); FFTList^[Index] := Item; Inc(FCount); end;
function TFTList.Last: TFormelTeil; begin Result := Get(FCount - 1); end;
procedure TFTList.Move(CurIndex, NewIndex: Integer); var Item: TFormelTeil; begin if CurIndex <> NewIndex then begin if (NewIndex < 0) or (NewIndex >= FCount) then exit; Item := Get(CurIndex); Delete(CurIndex); Insert(NewIndex, Item); FFTList^[NewIndex] := Item; end; end;
procedure TFTList.Put(Index: Integer; Item: TFormelTeil); var Temp: TFormelTeil; begin if (Index < 0) or (Index >= FCount) then exit; if (Item.Str <> FFTList^[Index].Str)and (Item.Art <> FFTList^[Index].Art)then begin Temp := FFTList^[Index]; FFTList^[Index] := Item; end; end;
procedure TFTList.SetCapacity(NewCapacity: Integer); begin if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then exit; if NewCapacity <> FCapacity then begin ReallocMem(FFTList, NewCapacity * SizeOf(TFormelTeil)); FCapacity := NewCapacity; end; end;
procedure TFTList.SetCount(NewCount: Integer); var I: Integer; begin if (NewCount < 0) or (NewCount > MaxListSize) then exit; if NewCount > FCapacity then SetCapacity(NewCount); if NewCount > FCount then FillChar(FFTList^[FCount], (NewCount - FCount) * SizeOf(TFormelTeil), 0) else for I := FCount - 1 downto NewCount do Delete(I); FCount := NewCount; end;
procedure TFTList.PutInLast(Item: TFormelTeil); begin Put(Count-1,Item); end;
end. |
Die im Quellcode makierten Zeilen führen allerdings leider bei der Verwendung wie hier(drunter) zu Fehlern:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| uses FormelListUnit;
procedure TForm1.Button1Click(Sender: TObject); Var F:TFTList; FT:TFormelTeil; begin
F:=TFTList.Create; FT.Str:='123'; FT.art:=1;
F.Add(FT);
Label1.Caption:=IntToStr(F.Art(0));
end; |
Fehlermeldung: "Invalid pointer operation"
Ich habe leider keine Ahnung von Pointern und deren Verwendung.
Soweit ich das richtig erkannt habe, muss der Fehler wohl schon beim "Schreiben" zustande kommen...
Hoffe, dass ihr mir beim Lösen des Problems weiterhelfen könnt!
Danke im Voraus für Antworten!
Gruß, Jonas