Файл: Основы программирования на языке Pascal (ОСНОВНЫЕ ПОНЯТИЯ)).pdf
Добавлен: 23.04.2023
Просмотров: 473
Скачиваний: 1
В качестве индексов могут выступать переменные любых порядковых типов. При указании диапазона начальный индекс не должен превышать конечный. Тип элементов массива может быть любым (стандартным или описанным ранее).
Описать переменную-массив можно и сразу (без предварительного описания типа) в разделе описания переменных:
Var <Переменная-массив> : Array [<Диапазон индексов>] Of <Тип элементов>;
Примеры описания массивов:
Var
S, BB : Array [1..40] Of Real;
N : Array ['A'..'Z'] Of Integer;
R : Array [-20..20] Of Word;
T : Array [1..40] Of Real;
Теперь переменные S, BB и T представляют собой массивы из сорока вещественных чисел; массив N имеет индексы символьного типа и целочисленные элементы; массив R может хранить в себе 41 число типа Word.
Единственным действием, которое возможно произвести с массивом целиком - присваивание. Для данного примера описания впоследствии допустима следующая запись:
S:=BB;
Однако, присваивать можно только массивы одинаковых типов. Даже массиву T присвоить массив S нельзя, хотя, казалось бы, их описания совпадают, произведены они в различных записях раздела описания.
Никаких других операций с массивами целиком произвести невозможно, но с элементами массивов можно работать точно также, как с простыми переменными соответствующего типа. Обращение к отдельному элементу массива производится при помощи указания имени всего массива и в квадратных скобках - индекса конкретного элемента. Например:
R[10] - элемент массива R с индексом 10.
Фундаментальное отличие компонента массива от простой переменной состоит в том, что для элемента массива в квадратных скобках может стоять не только непосредственное значение индекса, но и выражение, приводящее к значению индексного типа. Таким образом реализуется косвенная адресация:
BB[15] - прямая адресация;
BB[K] - косвенная адресация через переменную K, значение которой будет использовано в качестве индекса элемента массива BB.
Такая организация работы с такой структурой данных, как массив, позволяет использовать цикл для заполнения, обработки и распечатки его содержимого.
Если вы помните, с такой формой организации данных мы встречались, когда изучали строковые переменные. Действительно, переменные типа String очень близки по своим свойствам массивам типа Char. Отличия в следующем: строковые переменные можно было вводить с клавиатуры и распечатывать на экране (с обычным массивом это не проходит); длина строковой переменной была ограничена 255 символами (255 B), а для размера массива критическим объемом информации является 64 KB.
Теперь рассмотрим несколько способов заполнения массивов и вывода их содержимого на экран. В основном мы будем пользоваться числовыми типами компонент, но приведенные примеры будут справедливы и для других типов (если они допускают указанные действия).
Program M1;
Var
A : Array [1..20] Of Integer;
Begin
A[1]:=7; {Заполняем массив значениями (отдельно каждый компонент)}
A[2]:=32;
A[3]:=-70;
A[20]:=56;
Writeln(A[1],A[2],A[3], ?,A[20])
End.
Как бы ни был примитивен приведенный пример, он все же иллюстрирует возможность непосредственного обращения к каждому элементу массива отдельно. Правда, никакого преимущества массива перед несколькими простыми переменными здесь не видно. Поэтому - другой способ:
Program M2;
Var
A : Array [1..20] Of Integer;
I : Integer;
Begin
For I:=1 To 20 Do {Организуем цикл с параметром I по всем возможным}
Readln(A[I]); {значениям индексов и вводим A[I] с клавиатуры }
For I:=20 Downto 1 Do {Распечатываем массив в обратном порядке}
Write(A[I],'VVV')
End.
Эта программа вводит с клавиатуры 20 целых чисел, а затем распечатывает их в обратном порядке. Теперь попробуйте написать такую же программу, но без использования структуры массива. Во сколько раз она станет длиннее? Кстати, введение язык Паскаль цикла с параметром было обусловлено во многом необходимостью обработки информационных последовательностей, т. е. массивов.
Следующая программа заполняет массив значениям квадратов индексов элементов:
Program M3;
Const
N=50; {Константа N будет содержать количество элементов массива}
Var
A : Array [1..N] Of Integer;
I : Integer;
Begin
For I:=1 To N Do
A[I]:=I*I
For I:=1 To N Do
Write(A[I],'VVV')
End.
В дальнейшем для учебных целей мы будем использовать массивы, заданные с помощью генератора случайных чисел. В языке Паскаль случайные числа формирует функция Random. Числа получаются дробными, равномерно расположенными в интервале от 0 до 1. Выражение, дающее целое случайное число в интервале [-50,50] будет выглядеть так:
Trunc(Random*101)-50
Зададим и распечатаем случайный массив из сорока целых чисел:
Program M4;
Const
N=40; {Константа N будет содержать количество элементов массива}
Var
A : Array [1..N] Of Integer;
I : Integer;
Begin
For I:=1 To N Do
Begin
A[I]:= Trunc(Random*101)-50
Write(A[I],'VVV')
End
End.
С обработкой линейных массивов связано множество задач. Их мы рассмотрим на практических занятиях.
2.13. Двумерные и многомерные массивы.
Представьте себе таблицу, состоящую из нескольких строк. Каждая строка состоит из нескольких ячеек. Тогда для точного определения положения ячейки нам потребуется знать не одно число (как в случае таблицы линейной), а два: номер строки и номер столбца. Структура данных в языке Паскаль для хранения такой таблицы называется двумерным массивом. Описать такой массив можно двумя способами:
I.
Var
A : Array [1..20] Of Array [1..30] Of Integer;
II.
Var
A : Array [1..20,1..30] Of Integer;
В обоих случаях описан двумерный массив, соответствующий таблице, состоящей из 20 строк и 30 столбцов. Приведенные описания совершенно равноправны.
Отдельный элемент двумерного массива адресуется, естественно, двумя индексами. Например, ячейка, находящаяся в 5-й строке и 6-м столбце будет называться A[5][6] или A[5,6].
Для иллюстрации способов работы с двумерными массивами решим задачу: "Задать и распечатать массив 10X10, состоящий из целых случайных чисел в интервале [1,100]. Найти сумму элементов, лежащих выше главной диагонали."
При отсчете, начиная с левого верхнего угла таблицы, главной будем считать диагональ из левого верхнего угла таблицы в правый нижний. При этом получается, что элементы, лежащие на главной диагонали будут иметь одинаковые индексы, а для элементов выше главной диагонали номер столбца будет всегда превышать номер строки. Договоримся также сначала указывать номер строки, а затем - номер столбца.
Program M5;
Var
A : Array[1..10,1..10] Of Integer;
I, K : Byte;
S : Integer;
Begin
S:=0;
For I:=1 To 10 Do
Begin
For K:=1 To 10 Do
Begin
A[I,K]:=Trunc(Random*100)+1;
Write(A[I,K]:6);
If K>I Then S:=S+A[I,K]
End;
Writeln
End;
Writeln('Сумма элементов выше гл. диагонали равнаV',S)
End.
Если модель данных в какой-либо задаче не может свестись к линейной или плоской таблице, то могут использоваться массивы произвольной размерности. N-мерный массив характеризуется N индексами. Формат описания такого типа данных:
Type
<Имя типа>=Array[<диапазон индекса1>,<диапазон индекса2>,...
<диапазон индекса N>] Of <тип компонент>;
Отдельный элемент именуется так:
<Имя массива>[<Индекс 1>,<Индекс 2>,...,<Индекс N>]
2.14. Процедуры и функции.
При решении сложных объемных задач часто целесообразно разбивать их на более простые. Метод последовательной детализации позволяет составить алгоритм из действий, которые, не являясь простыми, сами представляют собой достаточно самостоятельные алгоритмы. В этом случае говорят о вспомогательных алгоритмах или подпрограммах. Использование подпрограмм позволяет сделать основную программу более наглядной, понятной, а в случае, когда одна и та же последовательность команд встречается в программе несколько раз, даже более короткой и эффективной.
В языке Паскаль существует два вида подпрограмм: процедуры и функции, определяемые программистом. Процедурой в Паскале называется именованная последовательность инструкций, реализующая некоторое действие. Функция отличается от процедуры тем, что она должна обязательно выработать значение определенного типа.
Процедуры и функции, используемые в программе, должны быть соответствующим образом описаны до первого их упоминания. Вызов процедуры или функции производится по их имени.
Подпрограммы в языке Паскаль могут иметь параметры (значения, передаваемые в процедуру или функцию в качестве аргументов). При описании указываются так называемые формальные параметры (имена, под которыми будут фигурировать передаваемые данные внутри подпрограммы) и их типы. При вызове подпрограммы вместе с ее именем должны быть заданы все необходимые параметры в том порядке, в котором они находятся в описании. Значения, указываемые при вызове подпрограммы, называются фактическими параметрами.
Формат описания процедуры:
Procedure <Имя процедуры> (<Имя форм. параметра 1>:<Тип>;
< Имя форм. параметра 2>:<Тип>?);
<Раздел описаний>
Begin
<Тело процедуры>
End;
Раздел описаний может иметь такие же подразделы, как и раздел описаний основной программы (описание процедур и функций - в том числе). Однако все описанные здесь объекты "видимы" лишь в этой процедуре. Они здесь локальны также, как и имена формальных параметров. Объекты, описанные ранее в разделе описаний основной программы и не переопределенные в процедуре, называются глобальными для этой подпрограммы и доступны для использования.
Легко заметить схожесть структуры программы целиком и любой из ее процедур. Действительно, ведь и процедура и основная программа реализуют некий алгоритм, просто процедура не дает решения всей задачи. Отличие в заголовке и в знаке после End.
Формат описания функции:
Function <Имя функции> (<Имя форм. параметра 1>:<Тип>;
< Имя форм. параметра 2>:<Тип>?) : <Тип результата>;
<Раздел описаний>
Begin
<Тело функции>
End;
В теле функции обязательно должна быть хотя бы команда присвоения такого вида: <Имя функции>:=<Выражение>;
Указанное выражение должно приводить к значению того же типа, что и тип результата функции, описанный выше.
Вызов процедуры представляет в программе самостоятельную инструкцию:
<Имя процедуры>(<Фактический параметр 1>, < Фактический параметр 2>?);
Типы фактических параметров должны быть такими же, что и у соответсвующих им формальных.
Вызов функции должен входить в выражение. При вычислении значения такого выражения функция будет вызвана, действия, находящиеся в ее теле, будут выполнены, в выражение будет подставлено значение результата функции.
Приведем простейший пример использования подпрограммы.
Задача: "Найти максимальное из трех введенных чисел". Для решения воспользуемся описанием функции, принимающей значение максимального из двух чисел, которые передаются в нее в виде параметров.
Program Fn;
Var
A,B,C :Real;
Function Max(A,B:Real):Real; {Описываем функцию Max с формальными}
Begin {параметрами A и B, которая принимает }
If A>B Then Max:=A {значение максимального из них }
Else Max:=B {Здесь A и B - локальные переменные }
End;
Begin
Writeln('Введите три числа');
Readln(A,B,C);
Writeln('Максимальным из всех является ', Max(Max(A,B),C))
End.
Обратите внимание на краткость тела основной программы и на прозрачность действий внутри функции. Формальные параметры A и B, используемые в подпрограмме, не имеют никакого отношения переменным A и B, описанным в основной программе.
Существует два способа передачи фактических параметров в подпрограмму: по значению и по ссылке. В первом случае значение переменной-фактического параметра при вызове подпрограммы присваивается локальной переменной, являющейся формальным параметром подпрограммы. Что бы потом ни происходило с локальной переменной, это никак не отразится на соответствующей глобальной. Для одних задач это благо, но иногда требуется произвести в подпрограмме действия над самими переменными, указанными в качестве фактических параметров. На помощь приходит второй способ. Происходит следующее: при обращении к подпрограмме не происходит формирования локальной переменной-формального параметра. Просто на время выполнения подпрограммы имя этой локальной переменной будет указывать на ту же область памяти, что и имя соответствующей глобальной переменной. Если в этом случае изменить локальную переменную, изменятся данные и в глобальной.
Передача параметров по ссылке отличается тем, что при описании подпрограммы перед именем переменной-формального параметра ставится служебное слово Var. Теперь использование в качестве фактических параметров выражений или непосредственных значений уже не допускается - они должны быть именами переменных.
Еще один классический пример. Задача: "Расположить в порядке неубывания три целых числа".