Перейти к содержимому

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

  • автор:

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.

Передача массивов в подпрограммы

Первый способ – безразмерный (динамический) массив. Записывается он так:
Procedure One (Arr: array of integer);
Как Вы видите, размерность массива здесь не указана и таким образом, она будет подобрана автоматически, в зависимости от передаваемого массива. Это очень удобно, поскольку позволяет использовать этот способ для передачи в одну процедуру массивов разного размера.
Недостатком такого способа является то, что его нельзя использовать для многомерных массивов, этим способом можно передать лишь одномерный массив. Другой недостаток – это сбивание нумерации элементов. Поскольку номера ни первого ни последнего элемента не заданы, Pascal назначает их автоматически и делает он это начиная с нуля. Таким образом, если нумерация Вашего массива была от 1 до N, то после передачи в подпрограмму она станет от 0 до N-1. Это нужно не забывать и учитывать.
Второй способ – это создание нового типа переменной! В параметрах основной программы (после const но до var), можно создавать свой тип переменной, сделав его массивом заданного размера. Делается это так:
Type Имя_типа = array [1..N,1..M] of real
После этого Вы объявляете массив присваивая ему уже этот, новый тип и не указывая размерность:
Mas: Имя_типа
Если представить, что имя типа мы задали Massiv, то объявление подпрограммы будет выглядеть так:
Procedure One (Arr: massiv);
Такой способ позволяет передавать в качестве параметра массивы с любым количеством измерений и многомерные массивы можно передать только так. Недостатком же этого способа является то, что количество измерений и размеры передаваемых массива должны совпадать с принимаемым массивом, т.е. этим способом в подпрограмму можно передать лишь одинаковые массивы.

Задание:
Создать три одномерных и три двумерных массива. Заполнить и выдать на экран их с помощью подпрограмм. Для обработки одномерных массивов использовать первый способ передачи массивов, а для обработки двумерных – второй. При этом, одномерные массивы должны быть разных размеров, а двумерные состоять из 3 строк по 15 столбцов.

Подпрограммы. Обработка массивов
Составить процедуру, исходными данными которой является матрица A(n,n). Результат процедуры -.

Подпрограммы. Обработка массивов
Задан массив, Найти среднее арифметической элементов над главной диагональю. у меня получилось.

Подпрограммы. Найти максимальные элементы массивов
Написать процедуру/функцию реализующую выполнение задания по вариантам. Предусмотреть передачу.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Использование массивов и функций в качестве формального параметра.

Формальным параметром функции может быть не только переменная скалярного типа, но и идентификатор переменной структурированного типа данных.

Использование массива в качестве параметра.

Пример 3. Массивы X(k), Y(m), Z(n) представляют собой три выборки значений случайной величины из общей генеральной совокупности. Требуется для каждой из трех выборок X, Y и Z вычислить их эмпирическую среднюю М и несмещенную дисперсию D.
Для решения этой задачи нужно запрограммировать две групповые пользовательские функции Avg и VarD, которые описываются с помощью формул:

podprogrammih.

Функции Avg и VarD имеют в качестве параметра имя массива, содержащего значения случайной величины и объем выборки.

podprogrammih.

Для описания этого примера понадобилось целых три структурограммы, однако они просты, наглядны, компактны и легки для понимания. Для составления текста программы сделаем предположение, что объемы выборок не превосходят целого числа G: G= Sup.
Для передачи имени объекта в качестве параметра этот объект нужно в явном виде описать в разделе TYPE. Мы хотим в качестве параметра передавать имя одномерного массива, поэтому дадим этому типу идентификатор VEK.

PROGRAM PR3;
CONST G = 50;
TYPE VEK = ARRAY [ 1 .. G] OF REAL;
VAR X, Y, Z: VEK; I, К, M, N: INTEGER;
FUNCTION AVG(P: INTEGER; W: VEK): REAL;
VAR J: INTEGER; S: REAL;
BEGIN
S:=0;
FOR J := 1 TO P DO S := S + W[J];
AVG := S/P
END;
FUNCTION VARD(P: INTEGER; W: VEK): REAL;
VAR J: INTEGER; M, S: REAL;
BEGIN
M:= AVG(P, W); S := 0;
FOR J := 1 TO P DO S := S + SQR(W[J] — M);
VARD:=S/(P- 1)
END;
BEGIN
WRITELN(‘Укажите размерность К массива X ‘); READLN(K);
WRITELN(‘Введите массив X, из ‘, К:2,’ вещественных чисел’);
FOR I := 1 ТО К DO READ(X[I]);
WRITELN(‘Укажите размерность M массива Y ‘); READLN(M);
WRITELN(‘Введите массив Y, из ‘,M:2,’ вещественных чисел’);
FOR I := 1 ТО M DO READ(Y[I]);
WRITELN(‘Укажите размерность N массива Z ‘); READLN(N);
WRITELN(‘Введите массив Z, из ‘, N:2,’ вещественных чисел’);
FOR I := 1 ТО N DO READ(Z[I]);
WRITELN(‘M(X) = ‘, AVG(K, X) :10:6,’, D(X) = ‘, VARD(K, X) :10:6);
WRITELN(‘M(Y) = ‘, AVG(M, Y) :10:6,’, D(Y) = ‘, VARD(M, Y) :10:6);
WRITELN(‘M(Z) = ‘, AVG(N, Z) :10:6,’, D(Z) = ‘, VARD(N, Z) :10:6)
END.

Использование функций в качестве параметра.

Идентификатор функции или процедуры может использоваться в качестве параметра другой функции. Если такая необходимость появилась, то требуется соответствующим образом специфицировать каждый такой формальный параметр.
Спецификацией в этом случае являются: заголовок передаваемой функции, включающей имя функции, список формальных параметров и тип результата. Спецификация функции описывается в разделе TYPE следующим образом: TYPE <имя спецификации> = FUNCTION(<список параметров>): <тип результата>;
Пример 4. В интервале [А, В] методом поразрядного приближения найти максимум функции
F(X) = 0.1Х 3 – 2Х 2 + 10Х.
Формульно-словесный алгоритм метода состоит в следующем.
1. Задается начальное приближение Х0= А слева от максимума F(X) и вычисляется F(X0). Задается D = h, где h = ?Х — начальный шаг поиска.
2. Полагаем G = F(Xn), где вначале F(Xn) = F(X0), задаем X = X + D и вычисляем F(Xn+1)=F(X).
3. Проверяем условие F(Xn+1) > G; если оно выполняется, то идем к п. 2, если нет – к п. 4.
4. Полагаем D = –D/4. Проверяем условие | D | >Е/4, где Е — заданная погрешность вычисления Хn в точке максимума. Если она выполняется, идем к п. 2, то есть обеспечиваем поиск максимума в другом направлении с шагом в четыре раза меньше прежнего. Если данное условие выполняется, заканчиваем счет, принимая за максимум X.
В этом известном алгоритме не учитывается тот факт, что в заданном интервале [А, В] нет экстремума (максимума). В этом случае максимум будет на границе интервала либо в точке А, либо в точке В. Учитывая простоту функции F(X) и основной программы, приведем структурограмму только функции PRP(A, В, Е, F), которая осуществляет поиск максимума функции F в интервале [А, В] с погрешностью приближения Е.
Структурограмма функции PRP(A, В, Е, F):

podprogrammih.

PROGRAM PR4;
TYPE FUN = FUNCTION(X: REAL):REAL; <Спецификация функции>
VAR X, А, В, E: REAL; N: INTEGER;
<$F+> <Директива. Компиляция функций с дальним типом обращения >
FUNCTION F(Z: REAL): REAL; <Исследуемая на экстремум функция>
BEGIN
F:=((0.1*Z-2)*Z+10)*Z
END;
FUNCTION PRP(A, В, E: REAL; W: FUN): REAL;
CONST N = 10; <Число участков, на которые разбивается [А, В]>
VAR I: INTEGER; D, G, X: REAL;
BEGIN
D := (В — A)/N; X := A;
WHILE ABS(D) > Е DO BEGIN REPEAT
G := W(X); PRP:=X; X := X + D;
IF ((X > B) OR (X < A)) AND (W(X) > G) <Максимум на границе интервала>
THEN EXIT; <Досрочное завершение функции>
PRP:=X;
UNTIL W(X) < G;
D := -D/4
END
END;
<$F->
BEGIN
WRITELN(‘Укажите границы диапазона А, В’); READLN(A,B);
WRITELN(‘Задайте погрешность расчетов E’); READLN(E);
X := PRP(A, В, E, F); <Вычисление Xmax>
WRITELN(‘Xmax = ‘, X:11:9,’F(Xmax) =’, F(X):13:9);
END.

Задав значения [А, В] = [2,3], E = 10 -9 , получим X = 3,0; F(X) = 14.7. Очевидно, что экстремума в этом интервале нет, так как Хmax на границе интервала в точке В. Изменив исходные данные: [А, В] = [2, 5], Е = 10 -9 , получим Хmax = 3,333332149; F(Хmax)= 14.814814815.
В теле функции использован оператор EXIT, который обеспечивает нормальный выход из фун-ции в том случае, когда нет экстремума и максимальное значение — на границе интервала.
Замечание. Как правило, компилятор Паскаля автоматически подбирает метод адресации подпрограмм. Если подпрограмма находится в одном тексте с телом основной программы, то она компилируется с «ближним» (near) адресом входа и возврата, содержащим только величину смещения адреса внутри текущего сегмента памяти. Если подпрограмма находится в другом программном модуле, то генерируется «дальний» (far) адрес, содержащий адрес сегмента и смещения в сегменте. При передаче имени функции в качестве программы необходим «дальний» адрес, но компилятор этого не понимает. Поэтому необходимо использовать директиву компилятора <$F+>. Действие этой директивы распространяется на все подпрограммы, описанные ниже по тексту программы, или до директивы <$F->.
Пример 5. Найти сумму

podprogrammih.

где Ui = F(i). Функция F(i) может быть различной: F1(i) = 1/i; F2(i) = i/(i + 1); F3(i) = Cos (?/i).
При решении этой задачи следует помнить, что передача в качестве параметров предопределенных (стандартных) функций, к которым относится и Cos(X), запрещена. Это ограничение обходится путем переопределения стандартной функции в пользовательскую функцию. Надежный сервис почтовых рассылок выполнит рассылку на электронные почтовые адреса быстро и недорого.

PROGRAM PR5;
TYPE FUN = FUNCTION(A: INTEGER): REAL;
VAR S1: REAL; M, N, K: INTEGER;
<$F+>
FUNCTION F1(I: INTEGER): REAL;
BEGIN Fl := 1/I
END;
FUNCTION F2(I: INTEGER): REAL;
BEGIN F2:= I/(I+1)
END;
FUNCTION F3(I: INTEGER): REAL; < Переопределение функции COS >
BEGIN F3 := COS(PI/I)
END;
FUNCTION SUM(F : FUN): REAL;
VAR I: INTEGER;
S: REAL;
BEGIN
S:=0;
FOR I:=M TO N DO S := S + F(I); SUM:=S END;
<$F->
BEGIN
WRITELN(‘Задайте M, N и номер функции (1, 2, 3)’);
READ(M, N, К);
CASE К OF
1:S1:= SUM(Fl);
2: Sl:= SUM(F2);
3:S1:=SUM(F3)
END;
WRITELN(‘S = ‘,S1:8:5)
END.

Параметры M и N передаются в функцию SUM в качестве глобальных переменных. Фактическим параметром для этой функции является идентификатор одной из трех функций Fl, F2, F3.

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

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

Школа онлайн с государственным аттестатом