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


Автор: vespa 8.6.2007, 09:57
В программе объявленно несколько двумерных статических массивов разной размерности. Нужно написать функцию, которая на вход получала бы любой из этих массивов + его длины и обрабатывала его. 

должно быть примерно так:
Код

A : array [1..10, 1..5] of double;
B : array [1..3, 1..2] of double;

// примерный прототип функции
procedure LoadArr2(var arr: array of array of double; M,N: integer);
var i,j : integer;
begin
  for i := 1 to M do
    for j := 1 to N do
       arr[i,j] := i + j;
end;

// вызов
LoadArr2(A,10,5);
LoadArr2(B,3,2);



Как это можно реализовать, желательно без указателей? В случае, если без указателей никак, то как с ними?

Автор: Sunvas 8.6.2007, 10:31
Цитата(vespa @  8.6.2007,  09:57 Найти цитируемый пост)
var arr: array of array of double;

Так в процедурах используються открытые массивы (кажется так называется). Поэтому для твоего случая это не подходит.

Вынеси свои массивы в тип. И объявляй примерно так:
Код

type MyArr1 = array [1..10, 1..5] of double;
        MyArr2 = array [1..3, 1..2] of double;
var
  A:MyArr1;
  B:MyArr2;


Автор: vespa 8.6.2007, 14:31
Цитата

Вынеси свои массивы в тип


Это не выход. Если у меня будет 1000 разных массивов, мне придется объявить 1000 типов.

Автор: aktuba 8.6.2007, 15:42
Код

type
  TArray = array of array of Double;
...
var
  a: TArray;
  b: TArray;
  procedure DoArr(var arr: TArray; m, n: Integer);
...
  SetLength(a, 1, 10);
  SetLength(b, 3, 15);
  DoArr(a, 1, 10);
  DoArr(b, 3, 15);


Так пойдет?

Автор: vespa 8.6.2007, 20:03
К сожалению, нет.  Я не могу поменять массивы.  Мне нужно решить задачу именнно в такой постановке. Как мне одной функцией обрабатывать двумерные статические массивы произвольной размерности.
Причем вся проблема именно в двумерности. Для одномерных все получается. Я просто пишу в функции:

Код

// прототип
procedure LoadArr1(var arr: array of double; size: integer);

// вызов для A: array[1..3] of double
LoadArr1(A, 3);



и все работает.

Автор: Sunvas 8.6.2007, 21:36
http://forum.vingrad.ru/forum/topic-109022.html
http://forum.vingrad.ru/forum/topic-40135.html

Автор: vespa 8.6.2007, 22:59
To Sunvas:
Цитата

http://forum.vingrad.ru/forum/topic-109022.html

это про одномерные массивы
для них работает
Цитата

http://forum.vingrad.ru/forum/topic-40135.html

это примерно то же самое, что и в первой ссылке и несет мало смысловой нагрузки именно по моему вопросу,
там для двумерных массивов проблема так и не решена

лучше бы какой дельный совет дали, чем ссылки давать(поиском я пользоваться умею)

Автор: Yanis 8.6.2007, 23:42
Цитата(vespa @  8.6.2007,  23:59 Найти цитируемый пост)
там для двумерных массивов проблема так и не решена

А http://forum.vingrad.ru/index.php?showtopic=40135&view=findpost&p=307773 что тогда?

Автор: vespa 9.6.2007, 10:21
To Yanis:

Что конкретно Вы имеете в виду под словами "это" ?
Процитируйте, напрямую, пожалуйста.

Автор: Yanis 9.6.2007, 11:03
Цитата(Петрович @ 21.1.2005,  10:50)
Аналогично.
Код

type
 tMyArray = array of array of real;

procedure Test (a :tMyArray);
begin
 //
end;

абырвалг

Автор: Rennigth 9.6.2007, 11:21
vespa, 
Ну нельзя со статическими массивами. Они не содержат в себе размерность, а динамические содержат. Единственный вариант это в функцию передавать указатель на область памяти массива и также туда передавать его размерность. Это имхо изврат. Статические массивы не для того предназначены. Используй динамические. Что тебя мешает?

Автор: vespa 9.6.2007, 12:08
Цитата(Yanis @ 9.6.2007,  11:03)
Цитата(Петрович @ 21.1.2005,  10:50)
Аналогично.
Код

type
 tMyArray = array of array of real;

procedure Test (a :tMyArray);
begin
 //
end;


В этом фрагменте функция вызывается с тем же параметром, с каким объявлена. Этот вариант не подходит.

Добавлено @ 12:19
To Rennigth:

Я тоже думаю что со статическими массивами не получится такая процедура.
Динамические массивы я использовать не могу, т.к. не могу менять код, который у меня есть. А он весь основан исключительно на статических массивах.

Вообще, для меня довольна странная ситуация. Казалось, бы такая простая задача, а простого решения нет. В Си, например, такой проблемы вообще бы не стояло.

Автор: aktuba 9.6.2007, 17:03
Цитата

т.к. не могу менять код, который у меня есть.


Если у тебя есть код, то почему нельзя его поменять??? Объяви как динамический и при запуске программы присвой размеры, а при выгрузке обнуляй...

Автор: vespa 9.6.2007, 21:50
Цитата(aktuba @ 9.6.2007,  17:03)
Цитата

т.к. не могу менять код, который у меня есть.


Если у тебя есть код, то почему нельзя его поменять??? Объяви как динамический и при запуске программы присвой размеры, а при выгрузке обнуляй...

Почему нельзя менять код - это долгая история.

Вообще, я тут в одной статье прочитала, что динамические массивы работают раза в три медленнее статических. Думаю, не имеет смысла переводить их в динамические.
Хотя если бы я сама писала бы подобный код, то я бы, не задумываясь, обявила бы как динамические.

Автор: MetalFan 9.6.2007, 22:17
Цитата(vespa @  9.6.2007,  21:50 Найти цитируемый пост)
я тут в одной статье прочитала, что динамические массивы работают раза в три медленне статических

гм... на сарае, знаете ли, тоже написано... а там дрова.
а если я вам напишу, что если все правильно реализовать, то медленнее ну может быть на десяток процентов будет, но не в 3 раза ;)

Добавлено через 13 минут и 43 секунды
реализуй с указателями...
Цитата(vespa @  8.6.2007,  09:57 Найти цитируемый пост)
В случае, если без указателей никак, то как с ними? 


Код

var
  A : array [1..10, 1..5] of double;
  B : array [1..3, 1..2] of double;

procedure LoadArr2(ArrPtr: PDouble; M,N: integer);
var
  i : integer;
  lPtr1: PDouble;
begin
  lPtr1 := ArrPtr;
  for i := 1 to (M * N) do
  begin
    lPtr1^ := i;
    Inc( lPtr1 );
  end;
end;


procedure TForm1.btn2Click(Sender: TObject);
begin
  LoadArr2( @A[1,1], 10, 5 );
  LoadArr2( @B[1,1], 3, 2 );
end;

Автор: vespa 10.6.2007, 08:48
To MetalFan:
честно, не на заборе читала, могу ссылку на источник привести

И спасибо за код. После праздников попробую сделать так. smile

Автор: MetalFan 10.6.2007, 08:58
Цитата(vespa @  10.6.2007,  08:48 Найти цитируемый пост)
честно, не на заборе читала, могу ссылку на источник привести

не все йогурты одинаково полезны ;) т.е. не в заборе дело. возможно человек, что писал текст по ссылке, не очень оптимально работал с дин.массивами... отсюда и замедление работы. 

Автор: vespa 13.6.2007, 08:11
Еще раз большое спасибо MetalFan. smile 

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