Форум по программированию Delphi Sources

 



Вернуться   Форум по программированию Delphi Sources > Все о Delphi > Синтаксис
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Закрытая тема
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 07.10.2016, 12:59
igor74 igor74 вне форума
Прохожий
 
Регистрация: 08.06.2011
Адрес: Екатеринбург
Сообщения: 11
Версия Delphi: Delphi 2010
Репутация: -625
По умолчанию Динамический массив как параметр

Всем привет!
Есть разные динамические массивы.
Например:
Код:
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  
Старый 07.10.2016, 13:50
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,026
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Здесь видимо нужно передавать в функцию не массив, а его размерность
Код:
function IndexInArray(Index, lw, hg: integer) : boolean;
begin
Result := (Index >= lw) and (Index <= hg);
end;
пример вызова
Код:
if IndexInArray(3, Low(ABC), High(ABC)) then  ...
  #3  
Старый 07.10.2016, 14:24
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59585
По умолчанию

Так Variant. И VarArrayHighBound (Low)
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 07.10.2016 в 14:26.
  #4  
Старый 07.10.2016, 14:30
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,026
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Действительно
Код:
function IndexInArray(Index : integer; ABC :array of Variant) : boolean;
какжеж забылось-то
  #5  
Старый 07.10.2016, 16:16
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59585
По умолчанию

Либо
ABC: Variant
__________________
Пишу программы за еду.
__________________
  #6  
Старый 07.10.2016, 16:27
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,026
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от NumLock
Либо
ABC: Variant
Пытался, не прокатило, у ТС в заВАРушке массивы дадены, вот с array of.. работает
  #7  
Старый 08.10.2016, 18:00
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,026
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Имелось ввиду что оно работает с разными типами, если A,B,C: array of variant, я делал так при проверке
  #8  
Старый 08.10.2016, 20:13
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,513
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

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  
Старый 09.10.2016, 20:02
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,513
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Сейчас еще раз посмотрел. Без обходных путей, похоже, способа нет.
Можно просто декларировать массивы через TArray<T> и сделать хэлпер именно к этому generic'у. Можно не пользоваться массивами, а применить различные контейнеры на основе классов (TList, TStringList, TObjectLost, etc). тогда там можно просто сделать этот метод встроенным.
  #10  
Старый 10.10.2016, 08:49
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59585
По умолчанию

Код:
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  
Старый 10.10.2016, 22:00
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 7,513
Версия Delphi: 7, XE3, 10.2
Репутация: 49088
По умолчанию

Num,

1. Это хак. Не факт, что будет работать на всех версиях. Ты затачиваешься на то, как компилятор хранит массив.
2. А что со статическими массивами?


ТС,

1. Low(), High() и Length() являются библиотечными функциями и реализованны хардкодом для текущей версии библиотеки и компилятора. Тебя же не смушает, что есть процедура writeln, у которой произвольное кол-во параметров, хотя ты подобную средствами самого языка создать не можешь (кстати, разработчики Delphi тоже не могут, именно поэтому мы имеем функцию Format с параметром array Of const).
2. Ну, если очень хочется без указания типа, то отдавай это на откуп компилятору. Т.е. пиши функцию с overload для каждого типа. Компилятор потом сам подставит нужную. Одна проблема - что делать для пользовательских типов и что делать, когда массив неизвестно чего передается из вне.

Как я говорил - проблема кардинально решается путем отказа от массивов и перехода на контейнеры. Я бы даже сказал - на generic-контейнеры. Т.е. наследуешь от стандартного generic-контейнера свой, дописываешь ему нужные тебе вещи и уже "рожаешь" свои классы от своего контейнеры с типизацией на этапе компиляции.
  #12  
Старый 12.10.2016, 12:51
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,503
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Зайду с другого боку, ты как хочешь использовать эту функцию?
Есть некий массив и ты по какому-то своему алгоритму берешь произвольный индекс и пытаешься обратиться по нему к элементу массива (предварительно проверив вхождение индекса)?
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 12.10.2016 в 13:06.
Закрытая тема



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:53.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources", 2004-2019

ВКонтакте   Facebook   Twitter