Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика (начальный курс) - 2 семестр.doc
Скачиваний:
4
Добавлен:
18.11.2019
Размер:
814.08 Кб
Скачать

5. Составной оператор.

Составной оператор объединяет группу операторов в единое целое с помощью слов

begin … end;

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

6. Оператор выбора.

Оператор позволяет выполнить одно из нескольких действий в зависимости от значения переключателя:

case Переключатель of

Список констант1: Оператор1;

Список констант2: Оператор2;

Список константN: ОператорN;

else ОператорЕ

end;

В качестве переключателя используется выражение, результатом которого может быть только значение порядкового типа, общее число элементов которого не превышает число 65535.

7. Оператор цикла с предусловием.

Оператор позволяет многократно выполнять одни и те же действия с зависимости от некоторого условия.

While Условие do Оператор;

Условием может служить выражение, результат которого имеет логический тип.

Сначала при входе в цикл вычисляется Условие. Если оно равно False, то вход в цикл не выполняется и управление передаётся оператору, следующему за телом цикла. Если Условие равно True, то происходит вход в цикл и однократное выполнение Операторов его тела. Как только достигнут конец тела цикла, управление снова передаётся на его заголовок, где снова вычисляется Условие. Если значение Условия всё ещё равно True (что зависит от изменения значений переменных), то тело цикла выполняется ещё один раз, и так далее.

8. Оператор цикла с постусловием.

Структуру этого опреатора можно представить так:

Repeat

Операторы тела цикла;

Until Условие;

Здесь Условие является условием выхода из цикла, то есть после каждого выполнения операторов тела цикла происходит проверка условия окончания цикла.

Поскольку проверка условия происходит в конце цикла, тело цикла хотя бы один раз будет выполнено. Поэтому оператор Repeat является не столь универсальным, как While.

9. Оператор цикла с параметром (со счётчиком).

Этот оператор подходит только для программирования таких циклических фрагментов. для которых заранее известны начальное и конечное значения счётчика повторений цикла. Однако, когда его использование возможно, оператор с параметром имеет несомненное преимущество перед другими операторами цикла. Формат оператора:

for ПеременнаяЦикла:=НачальноеЗначение to КонечноеЗначение do Оператор;

Чтобы оператор выполнился хотя бы один раз, начальное значение должно быть не больше конечного. Переменная цикла должна принадлежать к одному из порядковых типов. С каждым повторением тела цикла переменная наращивает своё значение (принимает значение следующее по порядку). Если слово to заменить на downto, то переменная цикла будет убывать.

Количество повторений равно abs(Ord(Конечное значение)– Ord(начальное значение)) +1.

Массивы.

Описание одномерных массивов.

Массив – это формальное объединение нескольких однотипных объектов (чисел, символов, строк и т.п.), рассматриваемое как единое целое. Описать массив можно либо в разделе переменных, либо с использованием описания нового типа. При описании массива необходимо указать:

  • имя массива,

  • из элементов какого типа он состоит,

  • сколько элементов содержит массив,

  • как нумеруются (или индексируются элементы).

Описание массива в разделе описания переменных выглядит так:

Var

Имя_Массива : array [Тип_индекса] of Тип_Элементов;

Здесь ARRAY, OF – зарезервированные слова (массив, из).

Например:

a,b,c,d : array [Integer] of Integer;

Здесь определено 4 массива с именами a,b,c и d. Все они состоят из элементов типа Integer. Элементы нумеруются целыми числами от -32768 до 32767, так как типом индекса указан тип Integer. Как правило, для типа индекса используют тип диапазон (вырезку из одного из базовых перечислимых типов). Например

x1 : array [1..100] of Real;

Элементы массива х1 имеют тип Real и нумеруются целыми числами от 1 до 100 включительно. Нумеровать элементы массива можно не только числами, но и значениями любого другого перечислимого типа, например, Char:

c1 : array [‘a’..’z’] of Real;

Элементы массива с1 имеют тип Real и индексируются буквами латинского алфавита.

Другой способ описания массивов — описание типа массива в разделе типов. Для перечисленных выше примеров это будет выглядеть так:

Type

TMassiv1 = array [Integer] of Integer;

TMassiv2=array [1..100] of Real;

TMass = array [‘a’..’z’] of Real;

После этого типами TMassiv1, TMassiv2, TMass можно пользоваться как стандартными, то есть в разделе описания переменных описывать переменные этих типов:

Var

A,b,c,d : TMassiv1;

x1 : TMassiv2;

c1 : TMass;

Действия над элементами масиивов.

Доступ (обращение) к отдельным элементам массива осуществляется путем указания имени переменной массива, за которым в квадратных скобках помещается значение индекса (порядкового номера) элемента. Примеры задания индекса: M[5] - непосредственно числом; M[k] - косвенно через переменную k; M[k1+5] - косвенно через выражение k1+5; M[Succ(i)] - косвенно через значение функции. Всем элементам одного массива можно присвоить значения элементов другого массива с помощью одного оператора присваивания, в том случае, когда массивы имеют идентичный тип. Так, если заданы следующие массивы:

Var x, y : array [1 . . 10] of integer ;

z : array [1 . . 10] of integer;

то допустим следующий оператор присваивания:

X:=Y;

но недопустим оператор Z:=X; так как массивы X и Z не идентичных типов. В Паскале над массивами не определены операции отношения. Сравнивать массивы можно только поэлементно. К отдельным элементам массива можно применять стандартные процедуры и функции, предусмотренные в языке. Перечень допустимых стандартных подпрограмм зависит от типа элементов массива.

Еще примеры: с помощью оператора

mas[2]:=34;

элементу массива mas с индексом 2 присваивается значение 34. Оператор

Writeln(mas[2]);

выведет на экран значение хранящегося в элементе-ячейке №2 массива mas. Используя в качестве индекса переменную цикла "FOR ... TO ... DO" можно обратиться к каждому элементу массива поочереди. Так с помощью фрагмента программы

For i:=1 to 25 do mas[i]:=0;

всем элементом массива присваивается значение "0".

Использование массивов вместо одиночных переменных позволяет благодаря применению циклов "FOR ... TO ... DO" существенно сэкономить время и объём программы. Это демонстрируется следующим примером.

Пример. Дана последовательность вещественных чисел s1 ... s30. Организовать массив для хранения этих чисел. Определить сумму этих чисел.

Program Primer1;

var

m: array[1..30] of real; {описание массива}

i: integer; {параметр цикла for}

s: real; {сумма элементов}

begin

for i:=1 to 30 do {заполнение массива}

begin

write('введите элемент последовательности n ',i);

readln(m[i]);

end;

s:=0; {обнуление счётчика суммы}

for i:=1 to 30 do s:=s+m[i]; {вычисление суммы}

write('сумма элементов последовательности равна ',s);

readln; { пауза }

end.

Заполнение массивов.

При работе с массивами необходимо заполнить их, то есть присвоить значение каждому элементу массива. Для заполнения массива x1 можно, например, использовать ввод с клавиатуры:

WriteLn(‘Введите значение для элементов массива:’);

For i:=1 to 100 do

begin

Write(‘x1[’,i,’]=’);

ReadLn(x1[i]);

end;

При отладке программы приходится вводить с клавиатуры много элементов массива. Чтобы избавиться от этой утомительной работы целесообразно заполнять массивы случайными числами. Для этого в начале программы один раз запускается датчик случайных чисел процедурой Randomize. Затем каждому элементу массива присваивается случайное значение с помощью функции Random. Использование функции Random может быть разнообразным. Если ее использовать с аргументом, например x1[i]:=Random(M); то она генерирует целое равномерно распределенное случайное число из отрезка [0,M-1], где М — целое положительное число. Если Random использована без аргументов x1[i]:=Random; генерируется вещественное равномерно распределенное случайное число из отрезка [0,1). Таким образом, заполнение массива случайными числами из отрезка [150,200) будет выглядеть так:

Randomize; {Инициализируем датчик}

For i:=1 to 100 do {Для каждого элемента}

x1[i]:=150+50*Random; {Присваиваем случайное}

Поиск элементов, удовлетворяющих заданному условию.

Зачастую приходится искать в неупорядоченном массиве элементы, которые удовлетворяют заданному условию. Например, условию положительности. Подсчитаем число положительных элементов массива

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

Program Primer2;

var

m: array[1..30] of Integer; {Описание массива}

i: integer; {параметр цикла for}

n: integer; {счётчик положительных эл-ов}

begin

Randomize; {Инициализация датчика}

for i:=1 to 30 do {заполнение массива}

m[i]:=Random(201)-100;

n:=0; {обнуление счётчика п. эл-ов}

for i:=1 to 30 do

if m[i]>=0 {Условие положительности}

then n:=n+1; {Наращиваем на 1 счетчик}

write('в массиве ',n,' положительных эл-ов');

readln; { пауза }

end.

Определение максимального элемента и его положения в массиве.

Рассмотрим пример программы, которая заполняет вещественный массив случайными числами и определяет значение и индекс (номер) максимального элемента этого массива

Programm Primer3;

var

m: array[1..30] of real; {Описание массива}

i: integer; {параметр цикла for}

max: real; {значение максимального элемента}

t: integer; {индекс (номер) макс. элемента}

begin

Randomize;

for i:=1 to 30 do

m[i]:=10*Random; {заполнение массива}

max:=m[1]; {допустим, что 1-й элемент - максимален}

t:=1;

for i:=2 to 30 do {Для всех остальных элементов}

if m[i]>max then {Сравниваем с максимальным}

begin

max:=m[i];

t:=i;

end;

writeln('максимальный элемент = ',max);

writeln('номер максимального элемента ',t);

readln; { пауза }

end.

Упорядочивание (сортировка) массивов.

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

Базы и банки данных, в свою очередь, необходимы не только для того, чтобы "складывать" в них информацию, но и для того, чтобы в любой момент была возможность удобного и быстрого доступа к ней. В обычном "неотсортированном" массиве информацию найти можно, но только способом последовательного перебора-просмотра всех его элементов, до тех пор, пока нужный элемент не будет обнаружен. Этот самый простой метод обладает только одним но очень существенным недостатком - на поиск одного элемента уходит много времени. Все остальные методы поиска информации намного эффективнее, быстрее, но применяются только в упорядоченных, отсортированных массивах. Поэтому часто возникает задача об упорядочивании массива.

Рассмотрим простой случай такой задачи: дан числовой массив x1, x2, ... xn, элементы которого попарно различны; требуется переставить элементы массива так, чтобы после перестановки они были упорядочены в порядке возрастания: x1 < x2 < ... < xn.

Существует несколько алгоритмов решения этой задачи.

Алгоритм сортировки перебором.

Очевидно, что первое место в массиве должен занять минимальный элемент массива, второе - наименьший из всех остальных, третий - наименьший из оставшихся и т.д. Для этого необходимо выполнить следующую последовательность действий:

1. Определить минимальный элемент массива;

2. Поменять его местами с первым элементом;

3. Определить минимальный элемент среди оставшихся;

4. Поменять его местами со вторым элементом и т.д.;

Эта последовательность действий должна выполняться до тех пор, пока не будет определён последний минимальный элемент.

Всю операцию по упорядочиванию массива можно разбить на более простые задачи.

Первая — поиск минимального элемента среди элементов с номерами i..n. Величина i должна быть равна сначала 1, затем 2, 3 и т.д до n-1.

Вторая — замена местами минимального элемента с номером t и элемента номером i. Поменять местами две переменные x и y можно двумя способвми:

  1. с использованием вспомогательной переменной v:=x; x:=y; y:=v;

  2. без использования вспомогательной переменной x:=x+y; y:=x-y; x:=x-y;

Блок-схема алгоритма сортировки перебором:

Алгоритм сортировки методом пузырька.

Если два соседних элемента расположены не в нужной последовательности, то меняем их местами. Так повторяем до тех пор, пока в очередном проходе не сделаем ни одного обмена, т.е. массив будет упорядоченным. Ниже показана блок-схема алгоритма сортировки по возрастанию методом пузырька (m - массив для сортировки с начальным индексом 1, n - размерность массива).

Алгоритм быстрой сортировки.

Метод "быстрой" сортировки, предложенный К.Хоаром (C. Hoare), основан на разделении массива на два непустых непересекающихся подмножества элементов. При этом в одной части массива должны оказаться все элементы, которые не превосходят по значению некоторый предварительно выбранный элемент массива, а в другой части - все элементы, не меньшие его. Аналогично следует поступить с каждой из полученных групп (при этом элемент для разделения можно выбирать просто из "середины" группы). На определенном этапе массив окажется полностью отсортированным.

В подавляющем большинстве реальных случаев использование "быстрой" сортировки дает лучшие результаты по времени, чем все прочие методы.

Алгоритм разделения массива на две части показан на следующей блок-схеме. Исходными данными для этого алгоритма являются величины Left — номер элемента, который считается левой границей массива и Right — номер элемента, который считается правой границей массива. Они нужны для того, чтобы тот же алгоритм мог обработать как весь массив целиком, так и его части. Имя массива — m. В качестве разделяющего элемента выбран элемент из середины массива.

I:=Left;

J:=Right;

Y:=m[(I+J) div 2]

Пока m[I]>Y

Inc(I)

Пока Y>m[J]

Dec(J)

Нет

Да

I<=J

Обмен

местами

m[I] и m[J]

Inc(I)

Dec(J)

Да

I>J

Нет

Left<J

Sort(Left,J)

Да

Нет

Да

I<Right

Sort(I,Right)

Нет

Удаление элементов из массива и вставка элементов в массив.

К сожалению, Turbo Pascal не имеет средств для создания массивов переменной длины. Длина массива указывается на этапе создания программы при описании массива. В ходе выполнения программы. Длина массива меняться не может. Поэтому при необходимости работы с массивами переменной длины описывают массив заведомо большего размера. Вместе с тем описывают целую переменную, смысл которой — фактическая длине массива, то есть размер используемой части массива. Хотя этот путь и нерационален, мы будем использовать его для работы с массивами переменной длины, чтобы отработать алгоритмы удаления и вставки элементов.

Чтобы удалить элемент с номером g из массива mas, необходимо каждый элемент, начиная с g+1 и до последнего, переместить на место предыдущего элемента и уменьшить на 1 размер массива. Описанный алгоритм реализуется следующим фрагментом программы:

…………………………

var

mas: array[1..100] of real; {Описание массива}

i: integer; {параметр цикла for}

n: integer; {Фактический размер массива}

…………………………

for i:=g to n-1 do mas[i]:=mas[i+1];

Dec(n); {Уменьшение n на 1}

…………………………

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

…………………………

for i:=n downto g do mas[i+1]:=mas[i];

mas[g]:=…

Inc(n); {Увеличение n на 1}

…………………………

Многомерные массивы.

Элементы многомерных массивов нумеруются не одним, а несколькими (как минимум двумя) индексами. Например, массив

x2 : array [1..10,1..20] of Real;

представляет собой двумерный массив, который можно интерпретировать как матрицу из 10 строк и 20 столбцов. Элементы этого массива могут принимать вещественные значения. Массив

x3 : array [1..10,1..20,1..5] of Real;

представляет собой трёхмерный массив из 1000 элементов.

Чаще всего в программах не используют массивов размерностью больше 2. Поскольку двумерные массивы по смыслу являются матрицами им следует уделить больше внимания.

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

Var a: array [1..10] of array [1.. 20] of real;

Var a: array [1..10, 1..20] of real;

Чаще всего при описании двумерного массива используют второй способ. Доступ к каждому отдельному элементу осуществляется обращением к имени массива с указанием индексов (первый индекс – номер строки, второй индекс – номер столбца). Все действия над элементами двумерного массива идентичны действиям над элементами одномерного массива. Только для инициализации двумерного массива используется вложенный цикл for.

Например,

For i:= 1 to 10 do

For j:= 1 to 20 do

A[i, j] := 0;

Для иллюстрации принципов работы с двумерными массивами разберем несколько примеров.

Пример. Сформировать таблицу Пифагора (таблица умножения) и вывести ее на экран.

Program Pifagor;

Uses crt;

Var p: array[1..9, 1..9] of integer;

i, j:integer;

Begin

Clrscr; {Очистка экрана}

for i:=1 to 9 do {Цикл по строкам}

for j:= 1 to 9 do {Цикл по столбцам}

p[i,j]:= i*j;

for i:=1 to 9 do

begin

for j:=1 to 9 do write(p[i,j],’ ’);

writeln; {Перевод курсора на сл. строку}

end;

end.

Пример. Задан двумерный массив В(10, 10), заполненный случайными числами из отрезка [-10,10]. Найти и вывести на экран те элементы массива, которые больше заданного числа k.

Program massiv;

Var

b: array[1..10, 1..10] of integer;

i, j, k :integer;

Begin

for i:=1 to 10 do

begin

for j:= 1 to 10 do

begin

b [i,j]:= random(20)-10;

write(b[i,j], ‘ ‘);

end;

writeln;

end;

write(‘Введите число k’);

readln (k);

For i:=1 to 10 do

For j:=1 to 10 do

If b[i,j]>k then write (b[i, j],’ ’);

End.

Пример. Задать и распечатать массив 10 на 10, состоящий из целых случайных чисел в интервале [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('Сумма элементов выше гл. диагонали равна',S)

End.