Как передать массив в функцию паскаль
Перейти к содержимому

Как передать массив в функцию паскаль

  • автор:

Bilety_OI_2 / 17) Передача массивов в качестве агрументов функций

Функции и процедуры в Object Pascal могут воспринимать в качестве параметров не только массивы фиксированного размера, но и так называемые открытые массивы, размер которых неизвестен. В этом случае в объявлении функции или процедуры они описываются как массивы базовых типов без указания их размерности. Например:

procedure SumArray(A:array of integer; var B: array of integer);

При таком определении передаваемый в функцию первый массив будет копироваться и с этой копией — массивом A, будет работать процедура. Второй открытый массив определен как var. Этот массив передается по ссылке, т.е. он не копируется и процедура будет работать непосредственно с исходным массивом.

Массив, переданный как открытый, воспринимается в теле процедуры или функции как массив с целыми индексами, начинающимися с 0. Размер массива может быть определен функциями Length — число элементов и High — наибольшее значение индекса. Очевидно, что всегда High = Length — 1.

Как передать массив в процедуру?

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

Код выглядит следующим образом:
procedure test(a,b: array of integer);
собственно сами массивы, которые я передаю вызываю как
a: array [0..3] of integer;
Как действовать?

  • Вопрос задан более трёх лет назад
  • 12507 просмотров
  • Facebook
  • Вконтакте
  • Twitter

AnnTHony

Установил Pascal ABC.net (версия 3.1, сборка 1179 от 29.02.2016)

Передача статического массива в подпрограмму

При передаче статического массива в подпрограмму по значению также производится копирование содержимого массива — фактического параметра в массив — формальный параметр:

Это крайне расточительно, поэтому статические массивы рекомендуется передавать по ссылке. Если массив не меняется внутри подпрограммы, то его следует передавать как ссылку на константу (const), если меняется — как ссылку на переменную:

Для доступа к нижней и верхней границам размерности одномерного массива используются функции Low и High .

Как передать массив в функцию

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

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

И очень часто, пытаясь передать массив в процедуру или функцию, новички сталкиваются с очень неприятным для них случаем — они просто не могут это сделать. Потому что вот такая попытка:

function TestFunc(M : array[1..8] of Byte) : boolean;

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

Ошибка при передаче массива

А дело в том, что передавать массивы в подпрограммы таким образом нельзя!

Как же быть? Не отказываться же от этого? Ведь передавать массивы в подпрограммы приходится довольно часто!

Но как это сделать?

Есть два способа:

  • Передать в функцию указатель на массив.
  • Создать новый тип данных.

Первый способ рассматривать не будем, потому что для новичка он может оказаться малопонятным. Если кому любопытно, то у меня есть книга, посвящённая указателям.

Рассмотрим второй способ. Он очень прост — надо создать пользовательский тип данных, и передавать в функцию уже параметр, имеющий этот тип. И таким образом передать массив в функцию в Паскале, Delphi, Lazarus (да и в большинстве других языков программирования) можно очень даже легко:

Как передать массив в функцию паскаль

От ё моё. Сишники. Попривыкали! Всё бы вам как указатели рассмотреть. А что данные тип имеют, это так. Фигня.
array [от . до] of Тип — это статический массив, а array of Тип — динамический. Это две большие разницы.
Если ты объявляешь L как array[0..9] of Integer, то и в функции он должен быть обязательно также объявлен.

Вообще здесь лучше использовать динамические массивы. Тогда придётся инициализировать их в коде.
Это будет нагляднее. И из функции otbor уйдёт лишний параметр col_vo, так-как текущую длинну массива можно всегда узнать через Length().

Можно и подругому. Оставляем массивы статическими, т.е.:

3. Аналогом оператора с — sizeof(. ) для Pascal является оператор Length(. );
Хотя в принципе и в сях этот оператор сделать можно, было бы желание.

Огромное спасибо за помощь, знания как деньги — лишними не бывают.

1. Почти.
1.1. Количество_элементов в Паскале задаётся границами, т.е. вместо С-шного [6] будет [0..5]. Или [3..8], или как угодно по-другому.
1.2. Инициализировать можно только глобальные переменные, т.е. переменные, созданные в процедурах и функциях так инициализировать не удастся. Ну, естественно, типизированную константу тоже можно. Это, как говорится, и ежу.

2. Как-то так. Но это, почти как и любое приведение типов, не расово для Паскаля. Логичнее было бы использовать динамические массивы. Заметь, что при объявлении array[0..0], если есть проверка на индексы, то при попытке доступа к элементу с индексом более 0, будет сообщение об ошибке. Можно кол-во элементов увеличить до максимально возможного.
Вообще-то правильнее было бы передат массив честно — как указатель (тип Pointer).

Вызов процедуры выглядит так — otbor(@L, @L1, Length(L)).
Оператор @ вернёт указатель (адрес) на массивы. В процедуре объявляем две переменные Src и Dst. Если перед их типом поставить ‘^’, то они будут УКАЗАТЕЛЯМИ на соответствующий тип (здесь Integer, т.к. элементы массива Integer). К ЗНАЧЕНИЮ указателя получаем доступ, ставя ‘^’ после имени идентификатора.
Сначала Src и Dst устанавливаем на начала массивов (Src := inp — после Src нет ‘^’. Изменяем не значение, а адрес, куда ссылается Src). Далее работаем с ДАННЫМИ, на которые ссылаются указатели, — Src^ < 0 и Dst^ := Src^. Чтобы переместить указатель на следующий элемент, используем Inc(). В Паскаль для указателей Inc() и Dec() увеличивают и уменьшают АДРЕС, куда ссылается указатель, на величину типа указателя (для Integer в Делфи — на 4 байта). Поэтому Inc(Src) переместит указатель на следующий элемент массива. НЕ ПУТАТЬ с Inc(Src^)! Это увеличит ЗНАЧЕНИЕ элемента на 1.

3. SizeOf и Length совершенно разные операторы. Length возвращает длинну строк и массивов, в т.ч. динамических. А SizeOf — размер, занимаемый переменной в памяти.
SizeOf(L) = 40 Байт, так как это массив из 10-ти элементов по 4 байта (Integer в Делфи).
Length(L) = 10 — количество элементов в массиве L.
SizeOf для указателей всегда = 4 (в Делфи). Например для строк (String) это тоже 4, так как строки в делфи по сути — указатели. Вне всякой зависимости от длинны хранимой строки (которую можно получить с пом. Length).

4! По-моему у тебя ашыпка. Не ‘MyArr(outp)[i] := MyArr(inp)[i]’, а ‘MyArr(outp)[p] := MyArr(inp)[i];’

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *