Arioch1
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Цитата: компилятор его должен знать заранее. | Количество должно быть определено до начала компиляции, либо же нельзя вставить массив. Цитата: Описывайте конечную цель, а не отдельные шаги Если вы пытаетесь разобраться как что-либо сделать (а не сообщать об ошибке), начинайте с описания цели. И только потом описывайте конкретный шаг на пути к ней, который вы не смогли выполнить. http://maddog.sitengine.ru/smart-question-ru.html#goal | Трудно угадывать что ты вообще хочешь сделать и зачем. Я как-то читал файл с картой, создаваемой другой программой, т.е. мне нужно было находить повторяющиеся элементы. Там правда данные шли не подряд, а в разных местах файла были на них указатели, считающие в разных единицах и от разной начальной точки. Если же они идут подряд, я бы писал примерно так: Цитата: {$T+} TLevel = packed record iValue1, iValue2, iValue3: Integer; end; PLevel = ^TLEvel; TMainLevels = packed record iSize: Integer; iReserved: Integer; aLevels: array[0..0] of TLevel; function SelfPtr: Pointer; function NextItem: Pointer; function SizeOf: Integer; procedure CheckIdx(const i: integer); inline; procedure setter(const idx: integer; const Value: PLevel); inline; procedure getter(const idx: integer): PLevel; inline; property Levels[I:integer]: PLevel read getter write setter; end; function TMainLevels.SizeOf: Integer; begin Result := SizeOf(TMainLevels) + (-1 + iSize)*SizeOf(TLevel); end; function TMainLevels.SelfPtr: Pointer; begin Result := @iSize; // для разных типов - разный элемент первый // возможно хватило бы @Self, не помню, проверять лень end; function TMainLevels.NextItem: Pointer; begin Result := SelfPtr; Inc(Result, SizeOf); end; procedure TMainLevels.CheckIdx(const i: integer); begin {$IfOpt R+} if (i<0) or (i>= iSize) then raise ERangeError.CreateFmt ('Levels are from #0 to #%d, access attempted to #%d', [iSize - 1, i]); {$EndIf} end; {$UnDef WasRangeChecking} {$IfOpt R+} {$Define WasRangeChecking} {$R-} {$EndIF} procedure TMainLevels.setter(const idx: integer; const Value: PLevel); begin CheckIdx(idx); aLevels[idx] := Value^; end; procedure TMainLevels.getter(const idx: integer): PLevel; begin CheckIdx(idx); Result := @aLevels[idx]; end; {$ifDef WasRangeChecking} {$R+} {$UnDef WasRangeChecking} {$EndIF} ..... var ScanningPtr: Pointer; ..... while ... do begin if тип элемента TMainLevels then with TMainLevels(ScanningPtr)^ do begin xyz := Levels[2]^.iValue2; ... ScanningPtr := NextItem; continue; end; if тип элемента какой-другой-тип then ... if тип элемента какой-другой-тип then ... end; | Другой вариант разбора структуры (парсинга) файлов был описан http://synopse.info/forum/viewtopic.php?pid=3950, там вместо записей использовали объекты (но не классы!). Впрочем, объекты скорее всего удалят в следующих версиях Дельфи рано или поздно. | Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 16:13 04-04-2012 | Исправлено: Arioch1, 16:18 04-04-2012 |
|