|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Динамический массив как параметр
Всем привет!
Есть разные динамические массивы. Например: Код:
var A : array of integer; B : array of TPoint; C : array of TClass; Есть желание определять вхождение в размерность функцией, т.е. Код:
function IndexInArray(Index : integer; ABC : TArray) : boolean; begin Result := (Index >= Low(ABC)) and (Index <= High(ABC)); end; Открытый статический массив (array of const) использовать нельзя, т.к. массив динамический, а для открытого динамического надо указывать конкретый тип. Может как то можно через указатель, но как потом с ним работать? Есть решение данной задачи? Кто подскажет? Последний раз редактировалось Admin, 08.10.2016 в 17:19. |
#2
|
||||
|
||||
Здесь видимо нужно передавать в функцию не массив, а его размерность
Код:
function IndexInArray(Index, lw, hg: integer) : boolean; begin Result := (Index >= lw) and (Index <= hg); end; Код:
if IndexInArray(3, Low(ABC), High(ABC)) then ... Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#3
|
||||
|
||||
Так Variant. И VarArrayHighBound (Low)
Пишу программы за еду. __________________ Последний раз редактировалось NumLock, 07.10.2016 в 14:26. |
#4
|
||||
|
||||
Действительно
Код:
function IndexInArray(Index : integer; ABC :array of Variant) : boolean; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#5
|
||||
|
||||
Либо
ABC: Variant Пишу программы за еду. __________________ |
#6
|
||||
|
||||
Цитата:
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#7
|
||||
|
||||
Имелось ввиду что оно работает с разными типами, если A,B,C: array of variant, я делал так при проверке
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#8
|
|||
|
|||
Generics вам в руки (как минимум с Delphi XE, вроде. Этот пример проверял на Delphi 10.1 Berlin):
Код:
type TArrayHelper<T> = class class function IndexInBounds(AIndex : Integer; A : Array Of T) : Boolean; end; class function TArrayHelper<T>.IndexInBounds(AIndex : Integer; A : Array Of T) : Boolean; begin Result := (AIndex >= Low(A)) And (AIndex <= High(A)); end; procedure TForm1.btTestClick(Sender: TObject); function BoolToStr(V : Boolean) : String; begin if V then Result := 'Yes' Else Result := 'No'; end; var A : Array Of String; B : Array Of Integer; C : Array Of TObject; D : Array [1..20] Of Pointer; E : Array [20..30] Of Char; begin edLog.Lines.Clear; SetLength(A,10); SetLength(B,20); SetLength(C,30); edLog.Lines.Add('Dynamic array A Of String, Index 15: ' + BoolToStr(TArrayHelper<String>.IndexInBounds(15,A))); edLog.Lines.Add('Dynamic array B Of Integer, Index 15: ' + BoolToStr(TArrayHelper<Integer>.IndexInBounds(15,B))); edLog.Lines.Add('Dynamic array C Of TObject, Index 15: ' + BoolToStr(TArrayHelper<TObject>.IndexInBounds(15,C))); edLog.Lines.Add('Static array D Of Pointer, Index 15: ' + BoolToStr(TArrayHelper<Pointer>.IndexInBounds(15,D))); edLog.Lines.Add('Static array E Of Char, Index 15: ' + BoolToStr(TArrayHelper<Char>.IndexInBounds(15,E))); end; Результат: Код:
Dynamic array A Of String, Index 15: No Dynamic array B Of Integer, Index 15: Yes Dynamic array C Of TObject, Index 15: Yes Static array D Of Pointer, Index 15: Yes Static array E Of Char, Index 15: No Последний раз редактировалось lmikle, 08.10.2016 в 22:05. |
#9
|
|||
|
|||
Сейчас еще раз посмотрел. Без обходных путей, похоже, способа нет.
Можно просто декларировать массивы через TArray<T> и сделать хэлпер именно к этому generic'у. Можно не пользоваться массивами, а применить различные контейнеры на основе классов (TList, TStringList, TObjectLost, etc). тогда там можно просто сделать этот метод встроенным. |
#10
|
||||
|
||||
Код:
function IndexInArray(Index: Integer; var V): Boolean; var p: PInteger; begin p:=PInteger(PInteger(@V)^); Dec(p); Result:=(Index>=0) and (Index<p^); end; procedure TForm1.FormCreate(Sender: TObject); var a: array of Integer; b: array of TPoint; c: array of TClass; begin SetLength(a, 20); SetLength(b, 30); SetLength(c, 40); if IndexInArray(35, a) then Memo1.Lines.Add('a'); if IndexInArray(35, b) then Memo1.Lines.Add('b'); if IndexInArray(35, c) then Memo1.Lines.Add('c'); end; Low = 0, т.к. xor edx,edx = 0 Пишу программы за еду. __________________ |
#11
|
|||
|
|||
Num,
1. Это хак. Не факт, что будет работать на всех версиях. Ты затачиваешься на то, как компилятор хранит массив. 2. А что со статическими массивами? ТС, 1. Low(), High() и Length() являются библиотечными функциями и реализованны хардкодом для текущей версии библиотеки и компилятора. Тебя же не смушает, что есть процедура writeln, у которой произвольное кол-во параметров, хотя ты подобную средствами самого языка создать не можешь (кстати, разработчики Delphi тоже не могут, именно поэтому мы имеем функцию Format с параметром array Of const). 2. Ну, если очень хочется без указания типа, то отдавай это на откуп компилятору. Т.е. пиши функцию с overload для каждого типа. Компилятор потом сам подставит нужную. Одна проблема - что делать для пользовательских типов и что делать, когда массив неизвестно чего передается из вне. Как я говорил - проблема кардинально решается путем отказа от массивов и перехода на контейнеры. Я бы даже сказал - на generic-контейнеры. Т.е. наследуешь от стандартного generic-контейнера свой, дописываешь ему нужные тебе вещи и уже "рожаешь" свои классы от своего контейнеры с типизацией на этапе компиляции. |
#12
|
||||
|
||||
Зайду с другого боку, ты как хочешь использовать эту функцию?
Есть некий массив и ты по какому-то своему алгоритму берешь произвольный индекс и пытаешься обратиться по нему к элементу массива (предварительно проверив вхождение индекса)? — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 12.10.2016 в 13:06. |