Технические дисциплины - Информатика

20.a) оператор while (пока). Он используется, если число повторений заранее не известно Проверка условия выполнения тела цикла производится в самом начале оператора.
b) оператор repeat (повторять) - until. Он используется, если число повторений заранее не известно, но проверка условия выполнения тела цикла производится в самом конце оператора.
c) Оператор for (для). Он используется, если число повторений заранее известно. Счётчик циклов должен быть типа Integer.

 

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

Этот наиболее часто используемый оператор повторения имеет вид:

WHILE <условие> DO <оператор>;

Здесь

WHILE, DO — резервированные слова (англ.: пока, делать);

<условие> — выражение логического типа;

<оператор> — произвольный (возможно составной) оператор.

 

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

Этот оператор имеет вид:

REPEAT <тело цикла> UNTIL <условие>:

Здесь

REPEAT, UNTIL — резервированные слова (англ.: повторять, пока не);

<условие> — выражение логического типа, если его значение истинно, то происходит выход из цикла.

Следует отметить, что в данной конструкции последовательность операторов, определяющих тело цикла, не заключается в операторные скобки BEGIN ... END, поскольку ими служит пара REPEAT ... UNTIL.

2.3. Оператор цикла со счетчиком

Если необходимо, чтобы фрагмент программы повторился заданное число раз, то используется конструкция:

FOR <имя счетчика цикла> = <начальное значение> ТО <конечное значение> DO <оператор>;

Здесь

FOR, TO, DO — зарезервированные слова (англ.: для, до, выполнить);

<счетчик (параметр) цикла> — переменная типа INTEGER, которая изменяется на отрезке от <начального значения>, увеличиваясь на единицу в конце каждого шага цикла;

<оператор> — любой (чаще составной) оператор.

Существует другая форма этого оператора:

FOR <имя счетчика цикла>:= <начальное значение> DOWNTO <конечное значение> DO <оператор> :

Замена ТО на DOWNTO (англ.: вниз до) означает, что шаг изменения параметра цикла равен - 1 , т. е. происходит пошаговое уменьшение счетчика на единицу.

 

25. 7.11. Что такое вложенные циклы?

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

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

Пример вложенных циклов для

Вычислить сумму элементов заданной матрицы А(5,3).

Матрица А            

 

S := 0;

нц для i от 1 до 5

нц для j от 1 до 3

S:=S+A[i,j]

кц

кц

Пример вложенных циклов пока

Вычислить произведение тех элементов заданной матрицы A(10,10), которые расположены на пересечении четных строк и четных столбцов.

 

i:=2; P:=1

нц пока i <= 10

j:=2

нц пока j <= 10

P:=P*A[i,j]

j:=j+2

кц

i:=i+2

кц

 

 

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

Вы знаете, что компьютер предназначен в основном для облегчения работы человека с большими информационными объемами. Как же, используя только переменные известных вам типов, сохранить в памяти и обработать данные, содержащие десяток, сотню, тысячу чисел или, к примеру, строк? А ведь такие задачи встречаются в любой области знания. Конечно, можно завести столько переменных, сколько данных, можно даже занести в них значения, но только представьте, какой величины будет текст такой программы, сколько времени потребуется для его составления, как много места для возможных ошибок? Естественно, об этом задумывались и авторы языков программирования. Поэтому во всех существующих языках имеются типы переменных, отвечающие за хранение больших массивов данных. В языке Паскаль они так и называются: "массивы".

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

Описание типа линейного массива выглядит так:
Type <Имя типа>=Array [<Диапазон индексов>] Of <Тип элементов>;

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

Описать переменную-массив можно и сразу (без предварительного описания типа) в разделе описания переменных:
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.

С обработкой линейных массивов связано множество задач. Их мы рассмотрим на практических занятиях.

Двумерные и многомерные массивы
Представьте себе таблицу, состоящую из нескольких строк. Каждая строка состоит из нескольких ячеек. Тогда для точного определения положения ячейки нам потребуется знать не одно число (как в случае таблицы линейной), а два: номер строки и номер столбца. Структура данных в языке Паскаль для хранения такой таблицы называется двумерным массивом. Описать такой массив можно двумя способами:
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>]

 

29.Строковый тип данных в языке Pascal

Далее познакомимся с типом данных, который относится к числу структурированных. Это строковый тип данных (строка). Строка — это последовательность символов. Каждый символ занимает 1 байт памяти (код ASCII). Количество символов в строке называется ее длиной. Длина строки может находиться в диапазоне от 0 до 255. Строковые величины могут быть константами и переменными. Особенностью строки в Turbo Pascal является то, что с ней можно работать как с массивом символов, с одной стороны, и как с единым объектом, — с другой. За счет этого обработка строк достаточно гибка и удобна. Строковая константа есть последовательность символов, заключенная в апострофы. Например: 'это строковая константа', ‘272’. Строковая переменная описывается в разделе описания переменных следующим образом:

Var <идентификатор> : string[<максимальная длина строки>];

Например:

Var Name : string[20].

Параметр длины может и не указываться в описании. В таком случае подразумевается, что он равен максимальной величине — 255. Например: Var slovo : string.

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

Символы внутри строки индексируются (нумеруются) от единицы. Каждый отдельный символ идентифицируется именем строки с индексом, заключенным в квадратные скобки. Например: N[5], S[i], slovo[k+l]. Индекс может быть положительной константой, переменной, выражением целого типа. Значение индекса не должно выходить за границы описания.

Тип string и стандартный тип char совместимы. Строки и символы могут употребляться в одних и тех же выражениях.

Строковые выражения строятся из строковых констант, переменных, функций и знаков операций. Над строковыми данными допустимы операции сцепления и операции отношения.

Операция сцепления (конкатенации) (+) применяется для соединения нескольких строк в одну результирующую строку. Сцеплять можно как строковые константы, так и переменные.

Пример: 'Мама ' + 'мыла ' + 'раму'. В результате получится строка: 'Мама мыла раму'. Длина результирующей строки не должна превышать 255.

Операции отношения: =, <, >, <=, >=, <>. Позволяют произвести сравнение двух строк, в результате чего получается логическое значение (true или false). Операция отношения имеет приоритет более низкий, чем операция сцепления. Сравнение строк производится слева направо до первого несовпадающего символа, и та строка считается больше, в которой первый несовпадающий символ имеет больший номер в таблице символьной кодировки. Если строки имеют различную длину, но в общей части символы совпадают, считается, что более короткая строка меньше, чем более длинная. Строки равны, если они полностью совпадают по длине и содержат одни и те же символы.

Пример:

Выражение

Результат

‘True1’<’True2’

True

‘Mother’>’MOTHER’

True

‘Мама ‘ <> ‘Мама’

True

‘Cat’=’Cat’

True

Функция Copy(S, Pozition, N) выделяет из строки S подстроку длиной N символов, начиная с позиции Pozition. Здесь N и Pozition — целочисленные выражения.

Пример:

Значение S

Выражение

Результат

‘Мама мыла раму’

Copy(S, 6, 4)

‘мыла’

‘Маша ела кашу’

Copy(S, 1, 8)

‘Маша ела’

Функция Concat(S1, S2, …, SN) выполняет сцепление (конкатенацию) строк S1, S2, …, SN в одну строку.

Пример:

Выражение

Результат

Concat('Маша ', 'ела ', 'кашу')

'Маша ела кашу'

Функция Length(S) — определяет текущую длину строки S. Результат — значение целого типа.

Пример:

Значение S

Выражение

Результат

'test-5'

Length(S)

6

'(A+B)*C'

Length(S)

7

Функция Pos(S1, S2) — обнаруживает первое появление в строке S2 подстроки S1. Результат — целое число, равное номеру позиции, где находится первый символ подстроки S1. Если в S2 подстроки S1 не обнаружено, то результат равен 0.

Пример:

Значение S2

Выражение

Результат

'abcdef'

Pos('cd', S2)

3

'abcdcdef'

Pos('cd', S2)

3

'abcdef'

Pos('k', S2)

0

Процедура Delete(S, Poz, N) — удаление N символов из строки S, начиная с позиции Poz.

Пример:

Исходное значение S

Оператор

Конечное значение S

'abcdefg'

Delete(S, 3, 2)

'abefg'

'abcdefg'

Delete(S, 2, 6)

'a'

В результате выполнения процедуры уменьшается текущая длина строки в переменной S.

Процедура Insert(S1, S2, Poz) — вставка строки S1 в строку S2, начиная с позиции Poz.

Пример:

Исходное значение S2

Оператор

Конечное значение S2

'ЭВМ РС'

Insert('IBM-', S2, 5)

'ЭВМ IBM-PC'

'Рис. 2'

Insert('N', S2, 6)

'Рис. N 2'

 

 

30.Строковые операции

До сих пор мы с вами рассматривали программы, реализующие алгоритмы обработки числовых данных. Однако хоть ЭВМ изначально и были созданы только для этой цели, по мере развития аппаратной части появилась возможность оцифровывать данные других типов, хранить их в памяти машины, перерабатывать, выводить во внешний по отношению к компьютеру мир. Проще всего можно было так поступить с текстовой информацией. Если не ставить перед машиной задачу "понимания" смысла текста, то задача оцифровки сводится к установлению правил замены символов (литер) при вводе в компьютер на их коды и обратной замены при выводе информации на экран или принтер. Такие правила, конечно же, были составлены. Как водится, сначала их было множество (вспомните разнообразие таблиц кодировки), затем весь мир остановился на ASCII.

Все языки программирования высокого уровня имеют средства работы с литерными величинами. Паскаль - не исключение. Как вам уже известно, в стандарте языка описаны два типа переменных для литерных величин. Это - String и Char. Напомню - переменная типа Char может содержать в себе только один единственный символ, тип String предназначен для хранения строковых величин до 255 символов длиною. Кстати, вы знаете не все о типе String. При описании переменной этого типа вы можете сами указать максимальное число символов, которое можно занести в нее. Конечно же, это число не должно превышать 255. Делается это так:

Var
S : String[30];

Для чего это нужно?

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

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

Также, новым для вас явится то, что при использовании строковой переменной, к каждому ее символу можно обратиться отдельно. Необходимо только знать номер нужного символа от начала строки. Его достаточно поставить после имени переменной типа String в квадратных скобках.

Пример: S[5] - пятый символ строки S.

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

Обратите внимание на то, что нумерация символов в строке начинается с единицы. Внутри квадратных скобок вместо числа может находиться выражение, результатом которого является целое число. Главное чтобы символ с таким номером в строке существовал. Но как же узнать, сколько символов в данный момент находится в строковой переменной? Для этого существует специальная функция, которая возвращает длину строковой переменной в символах. Это функция Length. Ее формат: Length(S)

Здесь S - либо строковая величина, либо строковая переменная.

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

Program Str1;
Var
S : String;
Begin

Writeln('Введите последовательность символов');
Readln(S);
Writeln('Вы ввели строку из ',Length(S), ' символов')

End.

Другой пример:
Решим задачу: "Введенную строку вывести на экран по одному символу в строке экрана".

Program Str2;
Var

S : String;
I : Byte;

Begin

Writeln('Введите строку');
Readln(S);
For I:=1 to Length(S) do {организуем цикл, начиная с первого символа}
Writeln(S[I]) {строки, до последнего (номер последнего}
{совпадает с количеством символов строки S) }

End.

Какие же еще действия можно выполнять с переменными строкового типа?

Две строковые величины можно состыковывать. Эта операция называется конкатенацией и обозначается знаком "+".

Например, результатом выполнения следующих команд:
R:= 'kadabra';
H:= 'abra';
S:=H+R;
в переменной S будет значение 'abrakadabra'.

Для конкатенации результат зависит от порядка операндов (в отличие от операции сложения). Следует помнить о том, какой максимальной длины может быть результирующая переменная, так как в случае превышения значением выражения числа, указанного после String в описании переменной, "лишние" символы в переменную не попадут.

Строковые величины можно сравнивать между собой. Это относится также и к строковым переменным. Но как же компьютер определяет, какая строка больше:

  • та, которая длиннее?
  • та, которая содержит больше заглавных букв?

На самом деле такая проверка проходит довольно сложно: компьютер сравнивает сначала первые символы строк. Большим из двух считается тот, код которого больше (вспомните, что такое код символа). Если равны первые символы, то так же анализируется следующая пара до тех пор, пока не будет найдено различие. Если начало строк совпадает, а одна из них кончается раньше, то вторая автоматически называется большей.

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

Ее формат: Ord(C), где С - либо непосредственно указанный символ, либо переменная символьного типа, либо один символ строковой переменной. Вообще, функция Ord имеет более глубокий смысл, но об этом - позже. Есть и обратная функция, которая возвращает символ по известному коду. Это функция Chr(N), где N - выражение, приводящее к целому числу в интервале от 0 до 255 (возможные значения кода символа). Очевидно, что Chr(Ord(C))=C, Ord(Chr(N))=N.

Следующая маленькая программа выводит на экран кодовую таблицу:

Program Str3;
Var
I : Byte;
Begin

For I:=32 to 255 do
Write('VV',I:4, '-',Chr(I))

End.

Цикл в программе начинается с 32 потому, что символы с кодами от 0 до 31 являются управляющими и не имеют соответствующего графического представления.

Задача: "Определить, является ли введенная строка "перевертышем". Перевертышем называется такая строка, которая одинаково читается с начала и с конца. Например, "казак" и "потоп" - перевертыши, "канат" - не перевертыш".

Поступим следующим образом: из введенной строки сформируем другую строку из символов первой, записанных в обратном порядке, затем сравним первую строку со второй; если они окажутся равны, то ответ положительный, иначе - отрицательный. Естественно, предложенный способ решения не является единственно возможным.

Program Str4;
Var
S,B : String;
I : Byte;
Begin

Writeln('Введите строку');
Readln(S);
B:=''; {Переменной B присваиваем значение "пустая строка"}
For I:=1 to Length(S) do
B:=S[I]+B; {Конкатенация. Символы строки S пристыковываются к}
{переменной B слева. Самым левым окажется последний.}
If B=S Then Writeln('Перевертыш') Else Writeln('Не перевертыш')

End.

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

Его формат:
Val(S,X,C);

Здесь S - строка, содержащая число, X - числовая переменная, в которую будет помещен результат, С - переменная целочисленного типа, в которую помещается первого встреченного в S отличного от цифры символа. Если после выполнения оператора Val переменная С имеет значение 0, то это означает, что преобразование типа прошло совершенно успешно и в строке нецифровых символов не встретилось.

Противоположное действие осуществляет оператор Str. Формат оператора:
Str(X,S);
X - число (либо арифметическое выражение), S - строковая переменная.

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

Для иллюстрации рассмотрим такую задачу: "Найти сумму цифр введенного натурального числа". Используя только числовые переменные, решить ее можно, но предлагаемое здесь решение, по-моему, проще.

Program Str5;
Var

S : String;
I,X,A,C : Integer;

Begin

Writeln('Введите натуральное число');
Readln(S); {Число вводится в строковую переменную}
A:=0;
For I:=1 To Length(S) Do
Begin

Val(S[I],X,C); {Цифровой символ превращается в число}
A:=A+X {Цифры суммируются}

End;
Writeln('Сумма цифр равна ',A)

End.

Теперь рассмотрим еще несколько действий над строками:

  • оператор DELETE(S,I,C) из строковой переменной S удаляет C символов, начиная с I-того;
  • оператор INSERT(SN,S,I) вставляет подстроку SN в строковую переменную S перед символом с номером I;
  • функция COPY(S,I,C) возвращает подстроку строки S из C символов, начиная с символа с номером I;
  • функция Pos(SN,S) возвращает номер символа, с которого в строке S начинается подстрока SN (позицию первого вхождения подстроки в строку). Если такой подстроки нет, то возвращается ноль.

Пример их использования:
"Во введенной строке заменить все вхождения подстроки 'ABC' на подстроки 'KLMNO'".

Program Str6;
Var

S : String;
A : Byte;

Begin

Writeln('Введите строку');
Readln(S);
While Pos('ABC',S)<>0 Do
Begin

A:= Pos('ABC',S);
Delete(S,A,3);
Insert('KLMNO',S,A)

End;
Writeln(S)

End.

 

31-35. Структура программы на языке Паскаль.

Синтаксически программа на языке Паскаль делится на 2 части: заголовок и программный блок.

Общий вид заголовка:

PROGRAM <имя программы>[(<список файлов>)];

Заголовок программы может отсутствовать. Стандартные файлы INPUT (входной) и OUTPUT (выходной) также могут опускаться, т.к. принимаются по умолчанию.

Блок программы состоит из следующих разделов:

LABEL <описание меток>; - раздел описания меток
CONST <описание констант>; - раздел описания констант
TYPE <описание типов>; - раздел описания типов
VAR <описание переменных>; - раздел описания переменных
PROCEDURE <описание процедуры>; - раздел описания
FUNCTION <описание функции>; процедур и функций

BEGIN

<исполнительная часть программы> - раздел операторов

END.

Текст программы записывается произвольно в виде строк длиной не более 127 символов. В Турбо Паскале порядок следования разделов описаний произвольный и каждый из разделов может появляться произвольное число раз или отсутствовать. Раздел операторов - это выполняемая часть программы, состоящая из операторов, разделенных точкой с запятой. Начинается BEGIN и заканчивается END. Исполняемая часть программы всегда должна присутствовать и может быть единственной частью программы.

Видом работы компилятора можно управлять директивами. Их включают в исходный текст в виде комментариев со специальным син-таксисом. Если описание процедуры или функции хранится в виде отдельного файла, то для включения их в исходный текст программы компилятору задается директива INCLUDE следующего вида:

{$I <имя файла>},

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

Например,

PROGRAM A1;
VAR ...
{$I B1.PAS}
BEGIN
...
END.
Файл B1.PAS может иметь вид:
PROCEDURE PP;
VAR ...
BEGIN
...
END;

наверх

4.2. Описание и вызов процедур.

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

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

Процедура или функция (общее название - подпрограмма) определяется в разделе описаний основной программы или другой процедуры(функции). Процедура(функция) имеет ту же структуру, что и основная программа, т.е. состоит из заголовка, описательной части и выполняемой части.

Синтаксис заголовка процедуры:

PROCEDURE < имя процедуры > [( <список формальных параметров >)];

Например :

PROCEDURE PR1 ( A,B,C : INTEGER; VAR S: REAL);

Здесь PR1 - имя процедуры, а А,В,С,S - имена переменных, являющих-ся параметрами.

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

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

Вызов осуществляется в следующей форме:

<имя процедуры > [(<список фактических параметров>)];

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

PR1 (A,B,C,S);

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

наверх

4.3. Описание функции.

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

Синтаксис заголовка функции:

FUNCTION < имя функции >[(<список формальных параметров>)]: <тип результата>;

Например:

FUNCTION PRF (A,B,C: INTEGER) : REAL;

Отличие описания функции от процедуры:

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

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

S:=PRF ( A,B,C);
Writeln ( PRF ( A,B,C));
If PRF ( A,B,C)>20 then K=K+1;

наверх

4.4. Формальные и фактические параметры.

При описании процедуры (функции) в ее заголовке могут быть указаны параметры следующих видов:

  • параметры-значения;
  • параметры-переменные;
  • параметры-константы;
  • параметры-процедуры;
  • параметры-функции.

При записи параметров необходимо помнить:

  • число формальных и фактических параметров должно быть одинаково;
  • порядок следования и тип фактических параметров должен совпадать с порядком и типом соответствующих формальных параметров;
  • идентификаторы формальных и фактических параметров могут совпадать;
  • формальные параметры в языке Турбо Паскаль в заголовке находятся вместе с описаниями и объявлять их в разделе описаний процедуры(функции) не требуется;
  • формальные параметры должны иметь простые или ранее определенные типы.

При передаче в подпрограмму массива его тип объявляют предва-рительно в разделе описания типов TYPE. Например.

TYPE TV=ARRAY [1..30] OF INTEGER;
TM=ARRAY [1..20,1..20] OF REAL;
...
PROCEDURE TOP ( A:TM; VAR B: TV ; N: INTEGER);
...

Здесь описаны два типа массивов. TV - для одномерного массива и TM для двумерного массива. Затем в списке формальных параметров для переменных А и В используются эти ранее определенные типы при описании соответственно матрицы и вектора.

Список параметров, задаваемых в заголовке процедуры или функции обеспечивает связь подпрограммы с вызывающей программой. Через него в подпрограмму передаются исходные данные и возвращается результат (в процедуре). В языке Турбо Паскаль предусмотрены два принципиально отличающихся механизма передачи параметров : по значению и по ссылке.

Параметры-значения.

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

Параметры-переменные.

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

В качестве параметров-переменных могут быть использованы массивы и строки открытого типа, у которых не задаются размеры. Открытый массив представляет собой формальный параметр подпрограммы, описывающий базовый тип элементов, но не определяющий его размерность и границы. Индексация элементов в этом случае начинается с нуля. Верхняя граница открытого массива возвращается функцией HIGH . Такое описание возможно только для одномерных массивов. Для открытого массива в стеке создается его копия, что может вызвать переполнение стека.

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

FUNCTION SUM (VAR A: ARRAY OF INTEGER):INTEGER;

VAR S,I : INTEGER;
BEGIN

 

S:=0;
FOR I:=0 TO HIGH(A) DO
S:=S+A[I];
SUM:=S;

 

END;

В основной программе такой массив может быть описан даже как Var A: array [ -2 .. 3] of integer; Фактические границы массива здесь значения не имеют. Важно только то, что количество элементов массива в данном случае равно 6.

Открытая строка может задаваться с помощью стандартного типа OPENSTRING и стандартного типа STRING с использованием дирек-тивы компилятора {$P+}.

Например,

PROCEDURE ZAP ( VAR ST : OPENSTRING; R: INTEGER );
или

{$P+}

PROCEDURE ZAP ( VAR ST : STRING; R: INTEGER );

В языке Турбо Паскаль можно устанавливать режим компиляции, при котором отключается контроль за совпадением длины формального и фактического параметра строки {$V- }. При передаче строки меньшего размера формальный параметр будет иметь ту же длину, что и параметр обращения; при передаче строки большего размера происходит усечение до максимального размера формального параметра. Контроль включает-ся только при передаче параметров-переменных , для параметров - значений длина не контролируется.

Рассмотрим пример, в котором используются процедура и функция. Требуется написать процедуру, в которой для матрицы, содержащей M столбцов и N строк, необходимо составить вектор номеров столбцов, все элементы которых упорядочены по возрастанию или убы-ванию и являются простыми числами. В главной программе вводятся все входные данные, производится обращение к процедуре и осуществляетcя вывод полученных результатов.

USES CRT;
TYPE TMAS=ARRAY[1..100,1..100] OF WORD;

TVECT=ARRAY[1..100] OF WORD;

VAR A:TMAS;

V:TVECT;
N,M,K:BYTE;
I,J:BYTE;

PROCEDURE FORM(VAR X:TMAS;) {матрица}

N,M:BYTE; {количество строк и столбцов}
VAR R:TVECT; {результат - вектор}
VAR K:BYTE); {длина полученного вектора}


VAR I,J,Z,S:BYTE;

F:BOOLEAN;


FUNCTION PROS(B:WORD):BOOLEAN;
{функция
проверки простого числа}
VAR I:WORD;
BEGIN

IF B<>1 THEN PROS:=TRUE

ELSE PROS:=FALSE;

FOR I:=2 TO B DIV 2 DO

IF B MOD I = 0 THEN PROS:=FALSE;


END;
BEGIN

K:=0;
FOR J:=1 TO M DO
BEGIN

Z:=0;
S:=0;
F:=TRUE;
FOR I:=1 TO N-1 DO
BEGIN

IF X[I,J]>X[I+1,J] THEN Z:=Z+1;
IF X[I,J]< X[I+1,J] THEN S:=S+1

END;
IF (Z = N-1) OR (S = N-1) THEN
BEGIN

FOR I:=1 TO N DO

IF NOT(PROS(X[I,J])) THEN F:=FALSE;

IF F THEN
BEGIN

K:=K+1; R[K]:=J

END;

END;

END;
END;
BEGIN

WRITELN('Введите N и M:');
READLN(N,M);
WRITELN('Введите
матрицу:');
FOR I:=1 TO N DO

FOR J:=1 TO M DO

READLN(A[I,J]);

FORM(A,N,M,V,K);
WRITELN('Результат
:');
FOR I:=1 TO K DO

WRITE(V[I],' ');

READKEY

END.

В этом примере в процедуру передаются входные данные: двумерный массив и его размерность. Массив передается как параметр-переменная, чтобы в процедуре не выделялась память для его копии. Результаты: вектор и его размерность обязательно передаются как параметры-переменные. Функция проверки простого числа является внутренней для процедуры и недоступна из главной программы.

 

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


Защитный код
Обновить