Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Как правильно вызывать функцию, возвращающую дин.


Автор: Juice 24.12.2009, 23:15
Господа, подскажите, как правильно вызвать функцию, возвращающую динамический массив значений?
Подробнее: надо создать функцию (только чур не подсказывать  smile ), которая бы резала строку по определённым позициям.
Вижу это так:

Код

function SplitByPos (st: string; ar: array of integer):array of string


В самой программе
Код

var MyAr, SimpleAr: array of integer;
...
begin
   SetLength(MyAr,0);
   SetLength(SimpleAr, 2);
   SimpleAr[0]:= 2;
   SimpleAr[1]: = 5;
   MyAr:=splitByPos ('Исходная строка', SimlpeAr);
end;

По моей логике в MyAr должно содержаться 'Ис', 'ход', 'ная строка'.
Это я описАл, как по моему мнению должно работать. На самом деле этот вариант не работает. Тест и номер ошибки не привожу, т.к., мне кажется это не суть важно из-за того, что я либо неправильно объявляю, либо неправильно вызываю. Пытаюсь это в D7 сделать.

Автор: profesiachuvak 24.12.2009, 23:33
Цитата(Juice @  24.12.2009,  23:15 Найти цитируемый пост)
Тест и номер ошибки не привожу


Так а как нам понять, в чём ошибка? Телепатически? С точки зрения синтаксиса тут всё правильно smile 
Хотелось бы увидеть ошибку  и текст самой функции:
 
Код

function SplitByPos (st: string; ar: array of integer):array of string


Автор: volvo877 24.12.2009, 23:43
Цитата(profesiachuvak @  24.12.2009,  22:33 Найти цитируемый пост)
С точки зрения синтаксиса тут всё правильно
Неправда... ОТКРЫТЫЙ и ДИНАМИЧЕСКИЙ массив - это совсем разные вещи...
Код
Type
  arrInt = array of integer;
  arrStr = array of string;
function SplitByPos (st: string; ar: arrInt): arrStr;
Вот теперь - правильно (для того куска кода, который привел автор...)

Автор: Juice 25.12.2009, 00:18
volvo877, удивляюсь, почему у тебя плюсов так мало. Спасибо, заработало.
А не подскажешь ещё синтаксис, как вызвать функцию без передачи ей в качестве параметров предварительно заполненного массива, а задавая конкретные значения? Например 
Код

AnyArray:=SplitByPos (st: string; 2, 5, 7);

Автор: Snowy 25.12.2009, 12:42
Код
AnyArray:=SplitByPos (st, [2, 5, 7]);

Автор: profesiachuvak 25.12.2009, 14:12
Цитата(volvo877 @  24.12.2009,  23:43 Найти цитируемый пост)
Неправда... ОТКРЫТЫЙ и ДИНАМИЧЕСКИЙ массив - это совсем разные вещи...


volvo877, В функцию нужно отправлять только динамический массив?


Автор: volvo877 25.12.2009, 14:34
Цитата(profesiachuvak @  25.12.2009,  13:12 Найти цитируемый пост)
В функцию нужно отправлять только динамический массив?
Это автору виднее... Хочешь - отправляй динамический, хочешь - нет...

Но уж если он отправляет динамический (что видно из его кода), то функция должна ожидать динамический, правда? Что для этого надо сделать - я написал выше.

Автор: profesiachuvak 25.12.2009, 14:41
Цитата(volvo877 @  25.12.2009,  14:34 Найти цитируемый пост)
Но уж если он отправляет динамический (что видно из его кода), то функция должна ожидать динамический, правда? Что для этого надо сделать - я написал выше.

Понятно, то есть как решение проблемы можно было описать массив так :
Код

var MyAr, SimpleAr: array [0..3] of integer;

Или описание фун-ции SplitByPos от этого тоже изменилось?

Автор: Juice 25.12.2009, 18:48
Просто хочется сделать универсальную функцию. Например, если тебе надо разбить строку на две (по определённой позиции), то надо писать функцию SplitNumberOne, где у тебя происходит разбивка на 2 подстроки. Следующую строку надо бить на четыре (по определённой позиции), опять пишем функцию SplitNumberTwo, бьющую входящую строку на 4 подстроки. 
Ну так вот, что бы не писать эти множество функций, проще сделать универсальную функцию, которой передаёшь исходную строку и номера позиций в ней, а она будет возвращать необходимое количество подстрок.
Кроме как передавать функции динамический массив целых, а та, в свою очередь, возвратит динамический массив строк, я не знаю как достичь этой универсальности. А если использовать 
Код
var MyAr, SimpleAr: array [0..3] of integer;
, то это только для частного случая, который, как я написал, не интересует.

Автор: Qu1nt 25.12.2009, 19:28
Код

procedure SplitByPos(const Text: AnsiString; const Args: array of const; List: TStringList);
var
  Value: TVarRec;
begin
  if not Assigned(List) then
    { epic fail }
    Exit;
  for Value in Args do
    if Value.VType = vtInteger then
      { do something }
      List.Add(IntToStr(Value.VInteger))
    else
      { fail }
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  List: TStringList;
  Item: AnsiString;
begin
  List := TStringList.Create;
  try
    SplitByPos('text', [1, '2', 3, 4, 5], List);
    for Item in List do
      ShowMessage(Item);
  finally
    List.Free;
  end;
end;

Автор: profesiachuvak 25.12.2009, 22:17
Цитата(Juice @  25.12.2009,  18:48 Найти цитируемый пост)
то это только для частного случая

Конечно. Динамический массив универсальнее.

Автор: bems 26.12.2009, 08:44
Цитата(volvo877 @  25.12.2009,  14:34 Найти цитируемый пост)
Но уж если он отправляет динамический (что видно из его кода), то функция должна ожидать динамический, правда?
Не совсем. Если ожидается открытый, то можно передать дианмический. В этом случае и 
Цитата(Snowy @  25.12.2009,  12:42 Найти цитируемый пост)
AnyArray:=SplitByPos (st, [2, 5, 7]);

будет работать. 

Автор: Juice 26.12.2009, 17:13
Вызов процедуры вида 
Код

temp2:=SplitByPos('asdf+123456=idkn', [1,3,7]);

не получается. 
Ошибка "[Error] Unit1.pas(39): Incompatible types: 'Set' and 'ArrInt'", ArrInt = array of integer;

Автор: bems 26.12.2009, 17:30
Я ж говорю, окрытый объявляй

Автор: Qu1nt 26.12.2009, 17:44
Чем мой пример не понравился?

Автор: Juice 26.12.2009, 17:45
Да, действительно, при объявлении 
Код

function SplitByPos(s: string; a: array of integer):arrstr;

вызов 

Код

temp2:=SplitByPos('asdf+123456=idkn', [2,5,8]);

Отрабатывает на ура.
Спасибо.
Получается, у меня ошибка была не в вызове функции, а в её описании.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)