IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

 
 Ответить  Открыть новую тему 
> Function, Procedure - аргумент Array?, как передать в качестве аргумента массив
сообщение
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 253
Пол: Мужской

Репутация: -  4  +


Как процедуре или функции передать в качестве аргумента массив?


--------------------
Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гуру
*****

Группа: Пользователи
Сообщений: 1 220
Пол: Мужской

Репутация: -  16  +


Цитата
Параметры - массивы и параметры - строки

Может сложиться впечатление, что объявление переменных в списке формальных параметров подпрограммы ничем не отличается от объявления их в разделе описания переменных. Действительно, в обоих случаях много общего, но есть одно существенное различие: типом любого параметра в списке формальных параметров может быть только стандартный или ранее объявленный тип. Поэтому нельзя, например, объявить следующую процедуру:
Procedure S(a: array [1 .. 10] of Real);
так как в списке формальных параметров фактически объявляется тип-диапазон, указывающий границы индексов массива.

Если мы хотим передать какой-то элемент массива, то проблем, как правило, не возникает, но если в подпрограмму передается весь массив, то следует первоначально описать его тип. Например:
type 
atype = array [1 .. 10] of Real;

Procedure S (a: atype);
...

Поскольку строка является фактически своеобразным массивом, ее передача в подпрограмму осуществляется аналогичным образом:

type 
intype = String [15];
outype = String [30];

Function St(s : intype): outype;
...


Требование описать любой тип-массив или тип-строку перед объявлением подпрограммы на первый взгляд кажется несущественным. Действительно, в рамках простейших вычислительных задач обычно заранее известна структура всех используемых в программе данных, поэтому статическое описание массивов не вызывает проблем. Однако разработка программных средств универсального назначения связана со значительными трудностями. По существу, речь идет о том, что в Турбо Паскале невозможно использовать в подпрограммах массивы с «плавающими» границами изменения индексов. Например, если разработана программа, обрабатывающая матрицу 10х10 элементов, то для обработки матрицы 9x11 элементов необходимо переопределить тип, т.е. перекомпилировать всю программу (речь идет не о динамическом размещении массивов в куче, а о статическом описании массивов и передаче их как параметров в подпрограммы). Этот недостаток, как и отсутствие в языке средств обработки исключительных ситуаций (прерываний), унаследован из стандартного Паскаля и представляет собой объект постоянной и вполне заслуженной его критики. Разработчики Турбо Паскаля не рискнули кардинально изменить свойства базового языка, но, тем не менее, включили в него некоторые средства, позволяющие в известной степени смягчить отмеченные недостатки. Эти недостатки практически полностью устранены в языке Object Pascal, используемом в визуальной среде программирования Delphi.

Прежде всего, в среде Турбо Паскаля можно установить режим компиляции, при котором отключается контроль за совпадением длины фактического и формального параметра-строки (см. прил.1). Это позволяет легко решить вопрос о передаче подпрограмме строки произвольной длины. При передаче строки меньшего размера формальный параметр будет иметь ту же длину, что и параметр обращения; передача строки большего размера приведет к ее усечению до максимального размера формального параметра. Следует сказать, что контроль включается только при передаче строки, объявленной как формальный параметр-переменная. Если соответствующий параметр объявлен параметром-значением, эта опция игнорируется и длина не контролируется.

Значительно сложнее обстоит дело с передачей массивов произвольной длины. Наиболее универсальным приемом в этом случае будет, судя по всему, работа с указателями и использование индексной арифметики. Несколько проще можно решить эту проблему при помощи нетипизированных параметров (см. п.8.5). В версии Турбо Паскаля 7.0 язык поддерживает так называемые открытые массивы, легко решающие проблему передачи подпрограмме одномерных массивов переменной длины.

Открытый массив представляет собой формальный параметр подпрограммы, описывающий базовый тип элементов массива, но не определяющий его размерности и границы:

Procedure MyProc(OpenArray: array of Integer);


Внутри подпрограммы такой параметр трактуется как одномерный массив с нулевой нижней границей. Верхняя граница открытого массива возвращается функцией HIGH, упоминавшейся в п.4.1.1. Используя 0 как минимальный индекс и значение, возвращаемое функцией HIGH, как максимальный индекс, подпрограмма может обрабатывать одномерные массивы произвольной длины:
{
Иллюстрация использования открытых массивов:
программа выводит на экран содержимое двух одномерных
массивов разной длины с помощью одной процедуры ArrayPrint
}

Procedure ArrayPrint(aArray: array of Integer);
var
k: Integer;

begin
for k := 0 to High(aArray) do
Write(aArray[k]:8);
WriteLn
end;

const
A:array [-1..2] of Integer = (0,1,2,3);
B: array [5..7] of Integer = (4,5,6);

begin
ArrayPrint(A);
ArrayPrint(B)
end.


Как видно из этого примера, фактические границы массивов А и В, передаваемых в качестве параметров вызова процедуре ArrayPrint, не имеют значения. Однако размерность открытых массивов (количество индексов) всегда равна 1 - за этим следит компилятор. Если бы, например, мы добавили в программу двумерный массив С
var
С: array [1 .. 3, 1 .. 5] of Integer;

то обращение
ArrayPrint(С)


вызывало бы сообщение об ошибке "Error26: Type mismatch" (Ошибка 26: Несоответствие типов.)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Бывалый
***

Группа: Пользователи
Сообщений: 253
Пол: Мужской

Репутация: -  4  +


спасибо! щас почитаю :P


--------------------
Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Бывалый
***

Группа: Пользователи
Сообщений: 253
Пол: Мужской

Репутация: -  4  +


почитал, разобрался, метод понял;
еще один вопрос, как сделать, чтобы значением функции являлся массив?

Код
...
type TArr=array[1..10]of byte;
function DoIt(a:TArr):TArr;{ведь это не правильно !? как тогда поступать?}
...


--------------------
Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Флогримм

Функция не может возвращать такие результаты. С этим ничего не поделать. Есть 2 выхода:
1. Через глобальные переменные
Код

var x: TArr;
Procedure DoIt(a: TArr);
begin
{здесь изменяешь значения х}
end;

2. Через Var-параметры (предпочтительно)
Код

procedure DoIt(a:TArr; var b:TArr);
{ а может просто procedure DoIt(var a:TArr); ? }
begin
{здесь изменяешь значения b (или a)}
end;
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Прогрессор
****

Группа: Пользователи
Сообщений: 602
Пол: Мужской
Реальное имя: Михаил

Репутация: -  9  +


Третий выход: возвращать указатель на массив. "Но это уже совсем другая история.." ;) Пока действительно лучше использовать var
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 247
Пол: Мужской

Репутация: -  1  +


На скока мне известно, функци может возвратить указатель на динамическую переменную типа массив, сформированную ей же при помощи new. Просто потом нужно будет освободить память самостоятельно, чтоб не накапливался мусор.

Код

type TArr:array[1..10] of integer;
       TPArr: ^TArr;
function myfunc:TPArr;
        var temp:TPArr;
        begin
        new(temp);
        temp^[1]:=999;
        myfunc:=temp;
        end;

...

a:=myfunc;
b:=a^[1]; //999
dispose(a);

Проверьте, кому не лень rolleyes.gif


А вообще все это фигня, и без этого всегда можно обойтись, да и вообще зачем функции возвращать массивы? для чего это может быть реально нужно?

Сообщение отредактировано: Digitalator -


--------------------
In byte we trust
ICQ World.ru
mail[dog]digitalator[dot]com
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Бывалый
***

Группа: Пользователи
Сообщений: 253
Пол: Мужской

Репутация: -  4  +


Цитата
А вообще все это фигня, и без этого всегда можно обойтись, да и вообще зачем функции возвращать массивы? для чего это может быть реально нужно?

чтобы писать процедуры обработки массивов lol.gif :yes:


--------------------
Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






Флогримм
Цитата
чтобы писать процедуры обработки массивов


Ты сам ответил на свой вопрос - для массивов лучше писать процедуры. :yes:
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Бывалый
***

Группа: Пользователи
Сообщений: 253
Пол: Мужской

Репутация: -  4  +


Цитата
Ты сам ответил на свой вопрос - для массивов лучше писать процедуры.

Так в том то и дело, что я понял, что "функция не может возвращать такие результаты"(с)volvo поэтому и приходится использовать процедуры. ;)


--------------------
Я не буду жить с этой злобой внутри / Я не буду частью смертельной цепи / Я не буду потребителем твоих идей / Я не буду никогда убивать зверей (Unconform)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 15.05.2024 10:30
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name