В простых типах данных каждое данное имеет свое название (идентификатор). В этом разделе вводится структурная взаимосвязь между данными, хранимыми в оперативной памяти путем организации массива, состоящего из непрерывно расположенных данных, не снабженных отдельными именами. Эти данные в свою очередь могут быть простыми или сложными и называются элементами массива.
Основное преимущество массива состоит в том, что его элементы не имеют отдельных имен, и нет необходимости описывать каждый элемент по отдельности. Достаточно описать весь массив. Объявление массива содержит следующее описание:
TYPE <имя типа> = ARRAY [тип индекса] OF <тип элементов массива>;
Каждый элемент именуется путем указания имени массива и порядкового номера, определяющего его позицию в массиве, то есть индекса. Если тип данных определен с помощью конструкции ARRAY... OF то он называется регулярным типом.
Паскаль предоставляет пользователю широкие возможности по заданию типа индекса, которым может быть любой порядковый или интервальный типы данных, в том числе и определенные пользователем. Тип элемента массива иногда называется базовым. Он может быть как любым скалярным, так и структурированным типом данных. Правомерно существование массивов-массивов, записей, множеств. Однако не существует массивов файлов. Число компонентов массива неявно определяется через тип индекса при его объявлении и в дальнейшем не меняется.
Одномерные массивы. Вектора.
Если в описании массива типом элемента является простой тип данных, то такой массив называется вектором. Поскольку в таком массиве для идентификации величины используется только один индекс, то он называется одномерным. Такие одномерные массивы представляют собой простейшие структурированные данные. Обращение к элементам одномерного массива осуществляется с помощью индексированных переменных, например X[i]. Здесь X – имя массива, a i — константа, переменная или выражение того же типа, что и тип индекса в объявлении массива.
В Паскале нет средств ввода, вывода массива целиком, поэтому эти действия приходится выполнять как циклические процессы над отдельными элементами массива, используя (в частности, в нашем примере) оператор FOR.
Лекция 8.2. Нестандартные функции. Редактирование программ.
Нестандартные функции.
Процедуры пользователя пишутся самим программистом в соответствии с синтаксисом языка в разделе описания подпрограмм.
Структура процедуры повторяет структуру программы, это "программа в миниатюре" — она также представлена заголовком и телом.
Заголовок состоит из зарезервированного слова procedure, идентификатора (имени) процедуры.
VAR … // раздел описания переменных главной программы
procedure ИмяПроцедуры;
var …
begin
…
end;
begin
//тело главной программы
end.
Вызов процедуры для последующего выполнения записывается в теле главной программы.
При вызове процедуры работа главной программы приостанавливается и начинает выполняться вызванная процедура. Когда процедура выполнит свою задачу, программа продолжится с оператора, следующего за оператором вызова процедуры.
Достоинства подпрограмм:
Программы, написанные с участием подпрограмм, легче тестировать и отлаживать, у них более четкая логическая структура.
Самостоятельный характер подпрограмм позволяет поручать их составление различным программистам. Так осуществляется разделение работы по программированию и, тем самым, ускоряется ее завершение;
Использование подпрограмм позволяет экономить память. Память для хранения переменных, использующихся в подпрограмме, выделяется только на время ее работы и высвобождается, как только ее выполнение заканчивается.
Пример 2. Пользователь вводит две стороны трех прямоугольников. Вывести их площади.
Можно решить задачу так:
for i:=1 to 3 do
begin
writeln(‘Введите a и b:’);
readln(a,b);
writeln(‘Площадь=’,a*b);
end;
Хорошим стилем программирования считается использование процедур. Необходима процедура, которая будет вычислять площадь прямоугольника. Вот как схематично будет выглядеть главная программа:
текст
readln (a,b);
вычисление
текст
readln (a,b);
вычисление
текст
readln (a,b);
вычисление
Процедура текста уже есть (см пример1). Создадим вторую процедуру, которая вычисляет площадь. Но для того чтобы вычислить S, надо знать 2 стороны, поэтому процедуре надо показать какие стороны она должна перемножать.
procedure pl (c,d: integer);
var S:integer;
begin
S:=c*d;
writeln(‘площадь прямоугольника со сторонами ’,c, ‘ ‘,d, ‘=‘,S);
end;
Параметр – это переменная, которой присваивается некоторое значение. Существуют формальные параметры, определенные в заголовке подпрограммы, и фактические параметры – выражения, задающие конкретные значения при обращении к подпрограмме.
Процедура выполнится, если вызвать ее по имени и указать фактические параметры, отделенные друг от друга запятыми и заключенных в круглые скобки:
pl(4,5);
pl(a,b);
Фактические параметры должны совпадать по типу и количеству с формальными.
Итак, главная программа:
for i:=1 to 3 do
begin
tx;
readln(a,b);
pl(a,b);
end;
Замечание. При решении этой задачи необходимо проверять введенные пользователем числа (они не должны быть отрицательными, иначе работа программы прервется).
Составим процедуру проверки:
procedure error (f,g:integer);
begin
if (f<0) or (g<0) then begin
writeln(‘стороны прямоугольника не могут быть отрицательными’);
halt; //прерывание программы
end;
end;
Итоговая программа – Приложение 4
Итак формат процедуры:
Procedure <имя> (формальные параметры);
Const...;
Type...;
Var...;
Begin
<операторы>;
end;
Пример 3. Найти площадь круга с использованием процедуры, которая производит только вычисление, но не отображает результат на экране.
procedure circle (r:real);
var S:real;
begin
S:=pi*r*r;
end;
Процедура должна возвращать результат:
procedure circle (r:real; var S:real);
begin
S:=pi*r*r;
end;
begin
readln(a, e);
writeln(e);
end.
Замечание: Переменная в процедуре S используется для возвращения результатов работы процедуры в основную программу. При ее изменении, изменяется и фактический параметр в вызывающей программе, т.е. переменная e.
Чаще для этого в Паскале вместо процедур используют функции (подпрограммы, которые что-то возвращают).
Функция аналогична процедуре, но имеются два отличия.
Функция передает в программу результат своей работы – единственное значение, носителем которого является имя своей функции.
Имя функции может входить в выражение как операнд. Функция возвращает результат в точку своего вызова.
Например, sqr(x) – возведет в квадрат значение х и возвратит в точку вызова вычисленное значение квадрата числа х: y:=sqr(x);
Функция, определенная пользователем, состоит из заголовка и тела функции. Тело функции по структуре аналогично программе. Описание меток, констант, типов и т.д. действительны только в пределах данной процедуры.
Формат:
Function <имя> (формальные параметры): <тип результата>;
Const...;
Type...;
Var...;
Begin
<операторы>;
end;
В разделе операторов должен находиться хотя бы один оператор, присваивающий имени функции значение. В точку вызова возвращается результат последнего присваивания.
Пример 5. Переделаем задачу о площади круга.
function circle (r:real): real;
begin
circle:=pi*r*r;
end;
вызов:
a:=circle(5); (ОБЯЗАТЕЛЬНО присваиваем)
или
e:=circle(a);
writeln(e);
Пример 6. Найти 1!+2!+…+n!
Используем функцию нахождения факториала, т.к подаем на вход и получаем результат.
function fact (a:integer): integer;
var i: integer;
begin
fact:=1;
for i:=1 to a do
fact:=fact*I;
end;
В строке fact:=fact*I;
компилятор найдет ошибку, т.к fact должна вызываться с параметрами. Поэтому обячно вводят дополнительную переменную, в которую помещают результат. А потом в переменную fact присваивают этот результат:
program factorial;
uses wincrt;
var sum,n,j: integer;
function fact (a: integer): integer;
var i,d: integer;
begin
d:=1;
for i:=1 to a do
d:=d*i;
fact:=d;
end;
begin
sum:=0;
readln(n);
for j:=1 to n do
sum:=sum+fact(j);
writeln(sum);
end.
Редактирование программ.