ЛекцииP

advertisement
Конспект лекций
Содержание
1. Введение
1.1 Основные особенности языка Паскаль
1.2 Алфавит языка
1.3 Лексическая структура языка
1.4 Общая структура программы
1.5 Стандартные процедуры и функции
1.6 Процедуры ввода/вывода
Задачи для самоконтроля
2. Простые типы данных
2.1 Целые типы
2.2 Вещественные типы
2.3 Cимвольный тип данных
2.4 Логический тип данных.
2.5 Ограниченные типы
2.6 Перечислимые типы
2.7 Описание типов
2.8 Преобразование типов
2.9 Порядок вычисления выражений
Задачи для самоконтроля
3. Операторы языка Паскаль
3.1 Оператор присваивания
3.2 Составной оператор
3.3 Условный оператор
3.4 Оператор выбора CASE
3.5 Оператор цикла с параметром (цикл FOR)
3.6 Оператор цикла с предусловием (цикл WHILE)
3.7 Оператор цикла с постусловием (цикл REPEAT)
3.8 Вложенные циклы
3.9 Оператор перехода GOTO
Задачи для самоконтроля
4. Массивы
4.1 Одномерные массивы
4.2 Сортировка элементов массива
4.3 Многомерные массивы
Задачи для самоконтроля
5. Подпрограммы (процедуры и функции)
5.1 Процедуры
5.2 Функции
5.3 Области действия имен
5.4 Параметры процедур и функций
5.5 Побочные эффекты при использовании подпрограмм
5.6 Передача массивов в подпрограммы
5.7 Параметры-костанты
5.8 Массивы открытого типа
5.9 Рекурсия в подпрограммах
Задачи для самоконтроля
6. Строковый тип данных
6.1 Описание строк
6.2 Операции со строками
6.3 Процедуры и функции для работы со строками
Задачи для самоконтроля
7. Стандартные модули Турбо-Паскаля
7.1 Модули ТУРБО3 и GRAPH3
7.2 Модуль OVERLAY
1
7.3 Модуль DOS
7.4 Модуль SYSTEM
7.5 Модуль PRINTER
7.6 Модуль CRT
7.7 Модуль GRAPH
8. Записи
8.1 Определение записи
8.2 Оператор над записями
8.3 Вложенные записи
8.4 Массив записей
8.5 Записи с вариантами
9. Файлы
9.1 Определение файла
9.2 Процедуры и функции для работы с файлами
9.3 Нетипизированные файлы
10. Интегрированная среда Турбо Паскаля
10.1 Как начать работу с Турбо Паскалем
10.2 Ваша первая программа
ПРИЛОЖЕНИЕ 1. Ответы к задачам для самоконтроля
Рекомендуемая литература
1. Введение
Язык программирования Паскаль был разработан в начале 70-х годов швейцарским ученым
Никлаусом Виртом. Язык Паскаль эффективен в самых разных приложениях и широко используется как
для решения небольших задач, так и для разработки сложных программных систем-компиляторов, баз
данных, операционных систем и т.п.
1.1 Основные особенности языка Паскаль, обусловившие его выдающийся успех, заключаются в
следующем:
1. Это традиционный язык программирования, продолжающий линию algol-60;
2. Содержит удобные средства для представления данных и развитую систему типов. Типы
переменных фиксируются при описании, что позволяет осуществлять строгий контроль доступа к
данным;
3. Набор операторов языка отражает принципы структурного программирования и позволяет писать
компактные и понятные программы;
4. Синтаксис языка не сложен, программы записываются в свободном формате, что делает их
наглядными и удобными для отладки.
Мы будем изучать широко известную реализацию языка Паскаль фирмы Borland для IBMсовместимых компьютеров – систему Турбо-Паскаль (версии 6.0, 7.0).
Система Турбо-Паскаль имеет интегрированную среду программирования, т.е. совокупность
программ, объединенных в общую систему, которая позволяет писать и редактировать программы,
компилировать их, компоновать, отлаживать и запускать на выполнение, не выходя из среды. Включает
в себя:
1) универсальный текстовый многооконный редактор для создания и корректировки текстов;
2) компилятор – программу, переводящую текст программы в машинные коды;
3) компоновщик, позволяющий компоновать программу из отдельных частей;
4) отладчик, служащий для выполнения программы по шагам и устранения ошибок;
5) систему контекстной информационной помощи.
1.2 Алфавит языка – совокупность допустимых в языке символов. Состоит из следующих символов:
1) заглавные и строчные латинские буквы и знак «подчерк»: A…Z, a…z, _
2) цифры 0…9
3) 22 специальных символа: +, -, *, /, >, <, (, ), [, ], @, #, $, ….
1.3 Лексическая структура языка включает следующие элементы:
1) служебные (зарезервированные, ключевые) слова (52 слова): begin, end, if,while,for… . Это группа
слов, смысл которых фиксирован в языке, их нельзя использовать в качестве имен, вводимых
программистом,
2
2) идентификаторы (имена) - для обозначения переменных, констант, типов… Образуются из букв
и цифр, начинаются всегда обязательно с буквы, длина произвольная, но компилятор
воспринимает первые 63 символа. Не существует различия между прописными и строчными
буквами: Например, index, INDEX, Index – одна переменная.
Пример:
Верная запись:
lab1, name_a, g255
Неверная запись:
1lab, name a, g*255
3) в тексте программы допускаются фрагменты пояснительного текста – комментарии, которые
располагаются между фигурными скобками или знаками (* *) и компилятором игнорируются.
Пример:
{комментарий}
{ тоже комментарий, но
на двух строках }
1.4 Общая структура программы
Программа на Паскале представляет собой формальную запись алгоритма, приводящую к решению
некоторых задач. Программа состоит из заголовка и двух разделов: Раздел описания данных и Раздел
описания действий. Действия представляются операторами языка, данные вводятся посредством
описаний и определений. Описание данных предшествует описанию действий и должно содержать все
объекты, используемые в действиях.
Итак, рассмотрим структуру программы подробнее.
Заголовок программы
Program Pr1;
В Турбо-Паскале заголовок программы необязателен и компилятором (см. п.1.1.) игнорируется;
Кроме того, в Турбо-Паскале существует еще один раздел – раздел объявления используемых модулей:
Uses Crt, Graph;
который описывается в самом начале текста программы, после заголовка, если таковой имеется.
Раздел описания данных может включать пять подразделов:
1) описание меток
Label M1, Met;
- используются для передачи управления внутри программы,
2) описание констант
Const a=2; c=3.5;
константы – элементы программы, значения которых не меняются в процессе ее выполнения.
В результате приведенного примера описания констант, система отведет две ячейки памяти с
именами a и c и занесет в них значения 2 и 3,5 соответственно. При попытке записать в эти ячейки
памяти какие-либо значения во время работы программы – система выдаст сообщение об ошибке.
Константы могут быть целыми, вещественными, символьными и строковыми.
Пример:
Const a=5;
- целая десятичная.
b=$F;
- целая шестнадцатеричная (~15)
c=-0.5; d=7.5E-5;
- вещественные (Е или е – показатель степени; 7.5Е–5 = 7.510-5 ).
Обратите внимание: целая часть отделяется от дробной – точкой (а не запятой).
e=’*’;
- символьная.
f=’Турбо’;
- строковая.
Бывают Типизированные константы – переменные, которым при описании присваивается начальное
значение. Могут использоваться как обычные переменные (о типах и переменных см. далее)
Пример:
Const max: integer = 92;
R: real = 2.7;
В результате данного примера описания констант, система отведет две ячейки памяти с именами max и
R и занесет в них значения 92 и 2.7 соответственно. Во время работы программы разрешается заносить
в такие ячейки новые значения соответствующего типа. В приведенном примере: в ячейку max – целые
числа; в ячейку R – вещественные числа.
3) описание типов
Type Mas = array [1..10] of integer;
tp = 1..6;
int = integer;
Под типом данных понимается множество допустимых значений этих данных и совокупность операций
над ними. В языке определены несколько стандартных типов данных: integer, real, char, Boolean,… (о
стандартных типах Паскаля см. далее в разделе 2). Кроме того, можно описывать и собственные типы в
разделе Type (см. также п.2.7).
4) описание переменных
Var x: real; y,z: integer;
p:Boolean;
3
Переменные – элементы программы, значения которых могут изменяться в процессе ее выполнения. С
каждой переменной при ее описании связывается ее тип.
В результате данного примера описания переменных, система отведет четыре пустых ячейки памяти. Во
время работы программы:
- в ячейку x можно записывать только вещественные числа из диапазона значений,
соответствующего типу Real; {о типах и соответствующих диапазонах см. в разделе 2}
- в ячейки y,z можно записывать только целые числа из диапазона от -32768 до +32767.
При попытке записать в эти переменные значение, например, 32768, система выдаст сообщение об
ошибке: выход за границы диапазона типа.
- в ячейку p можно записывать только значения True (истина) или False (ложь).
5) описание подпрограмм: функций
Function F(x: real): real;
и (или) процедур
Procedure Alfa;
Процедуры и функции – самостоятельные части программы, имеющие свое имя и выполняющие
определенные действия (см. раздел 5).
В программе могут использоваться не все подразделы, а только необходимые для конкретной задачи.
Порядок размещения разделов произвольный, можно создавать несколько одинаковых разделов. В
любом месте программы можно использовать элементы, описанные ранее по тексту.
Раздел описания данных может вообще отсутствовать.
Раздел описания действий (еще его называют выполняемая часть программы или тело программы)
начинается со слова begin и заканчивается словом end с точкой. Между этими словами записывается
последовательность операторов, реализующая алгоритм решения задачи. Операторами называют
команды, действия. Выполняемые операторы в языке Паскаль отделяются друг от друга точкой с
запятой. Порядок выполнения операторов программы: слева направо сверху вниз.
Пример:
Begin
Write(‘*****’);
End.
Данная программа содержит только одну команду – оператор вывода на экран. В результате ее работы
на экране мы увидим строку из 5-ти звездочек: ***** . Раздел описания данных для этой задачи не
требуется.
Пример: Программа вычисляет сумму двух заданных чисел и выводит результат на экран.
Несколько забегая вперед скажу, что знак := (присвоить) - это обозначение оператора присваивания,
который заносит значение, полученное справа от знака, в ячейку памяти с именем, указанным слева от
знака (см. п. 3.1.)
1 вариант:
const a=3.5; b=2;
var sum: real;
Begin
sum:=a+b; {складывается содержимое ячеек a и b, результат записывается в ячейку sum }
write(a,’ + ’,b,’ = ’,sum); {на экран выводится: 3.5 + 2 = 5.5}
End.
2 вариант:
var a,b,sum: real;
Begin
a:=3.5; b:=2; {в ячейку a заносится число 3.5, в b – число2}
sum:=a+b; {складывается содержимое ячеек a и b, результат записывается в ячейку sum }
write(a,’ + ’,b,’ = ’,sum); {на экран выводится: 3.5 + 2 = 5.5}
End.
3 вариант:
var a,b: real;
Begin
a:=3.5; b:=2; {в ячейку a заносится число 3.5, в b – число2}
a:=a+b; {складывается содержимое ячеек a и b, результат записывается в ячейку sum }
write(’ сумма = ’,a); {на экран выводится: сумма = 5.5}
End.
В 3-м варианте к моменту выполнения команды write в ячейке a содержится уже не слагаемое (3.5), а
результат (5.5), поэтому вывод слагаемых как в первых двух вариантах невозможен. Таким образом,
если слагаемые еще необходимо далее использовать в программе, то для хранения результата надо
выделять отдельную ячейку памяти, как в вариантах1 и 2.
Надо понимать, что в каждый момент времени в одной ячейке памяти хранится одно число. Если
записать в нее другое число, то предыдущее удаляется.
1.5 Стандартные процедуры и функции
4
В Паскале существует ряд заранее разработанных подпрограмм, которые можно использовать в
своих программах.
1) Арифметические функции
y := abs(x);
y = |x|
y := sin(x);
y = sin x
y := cos(x);
y = cos x
y := arctan(x);
y = arctg x
y := exp(x);
y = ex
y := ln(x);
y = ln x
y := sqr(x);
y = x2
y := sqrt(x);
y = √x
y := pi ;
y=π
y := frac(x);
дробная часть числа frac(3.9)=0.9
y := int(x);
целая часть числа int(3.9)=3.0
Арифметические функции можно использовать только с величинами целого или вещественного
типа. Результат арифметических функций (кроме sqr и abs) – вещественный. У sqr и abs тип
результата совпадает с типом аргумента.
В Паскале нет функции возведения в степень, эта функция вычисляется с использованием
функций exp и ln следующим образом:
yx = exp(x*ln(y));
2) Некоторые другие функции и процедуры
y := round(x);
округление вещественного числа до ближайшего целого:
round(4.7)=5; round(3.2)=3; round(2.5)=2
y := trunc(x);
целая часть вещественного числа: trunc(4.7)=4
y := odd(x);
проверка величины х на нечетность: true, если х нечетный, иначе false
Например, odd(3) = True; odd(2) = False;
write(x);
вывод значения х на экран
writeln(x);
вывод значения х на экран с последующим переводом курсора на новую
строку
read(x);
ввод значения х с клавиатуры
readln(x);
ввод значения х с клавиатуры с последующим переводом строки
clrscr;
очистка экрана, перевод курсора в его левый верхний угол
Чтобы использовать эту процедуру, надо подключить к программе модуль
CRT: uses crt;
delay(msec);
задержка экрана, msec – число в микросекундах
Random(n);
генератор случайных целых чисел - в каждый момент времени выдает одно
случайное целое число из диапазона от 0 до n-1 включительно.
Random;
генератор случайных чисел без параметра - генерирует вещественное число
из диапазона от 0 до 1.
Randomize;
процедура инициализации (первоначальная настройка) генератора
случайных чисел. Всегда вызывается до использования random. Если не использовать Randomize, то
при каждом новом запуске программы на выполнение, генератор случайных чисел будет выдавать одну
и ту же первоначально выданную последовательность случайных чисел.
Пример:
x:=random(10);
{случайное целое число из диапазона от 0 до 9}
x:=random(100)-50;
{ random(100) - случайное целое число из диапазона от 0 до 99,
минимально возможное значение x = 0 – 50 = -50;
максимально возможное значение x = 99 – 50 = 49; }
y:=random*10;
{ случайное вещественное число из диапазона от 0 до 9}
z:=random*10-10;
{ случайное вещественное отрицательное число из диапазона от 0 до 9}
Пример: программа вычисления площади круга S= πr2.
Uses Crt; {подключение модуля Crt - в нем описана процедура Clrscr – очистка экрана }
Var s,r: real; {раздел описания переменных–описаны 2 переменные вещественного типа}
Begin
Clrscr;
{ очистка экрана }
Write(‘Введите радиус r = ’); {выведет на экран текст: Введите радиус r = }
Readln(r); {приостановит работу программы до ввода какого-либо (одного) числа: надо
набрать на клавиатуре число и нажать клавишу Enter. После этого введенное число
автоматически запишется в переменную, указанную в скобках }
s:=pi*r*r; {вычислит значения выражения и запишет результат в s; pi ≈ 3,14…}
writeln(‘Площадь круга S =’, s:10:5); {выведет на экран текст из апострофов и значение s}
delay(10000); {задержит результат на экране в течении 10 секунд, затем вернется к
5
исходному тексту программы}
End.
При работе с целыми числами могут оказаться полезными две процедуры (в квадратных скобках
указываются необязательные параметры):
dec (x [, N]) - уменьшает содержимое переменной x на значение выражения N (если N не задано,
то на 1); тип переменной x и выражения N - INTEGER (точнее, любой целый тип: см.п.2.1);
inc (x [, N]) - увеличивает значение x на N (если N не задано, то на 1).
Например, a:=6; b:=4; x:=7; y:=0;
dec(a,3); inc(b,3); dec(x); inc(y);
write(‘a=’,a,’ b=’,b,’ x=’,x,’ y=’,y);
В результате выполнения данного фрагмента программы, на экране увидим следующее:
a=3 b=7 x=6 y=1
1.6 Процедуры ввода/вывода
1) Для вывода используются процедуры write и writeln (окончание ln означает перевод курсора на
следующую строка после вывода).
Форма записи: write (<список параметров>); - выводит параметры на экран; курсор вывода
остается на этой же строке.
writeln (<список параметров>); - выводит параметры на экран; переводит курсор
вывода на следующую строка после вывода.
В список параметров могут входить переменные и строки, возможно с указанием формата:
Переменные: а, в, х1…
- выводятся значения переменных;
Строки: ‘a = ’, ‘сумма = ’
- заключаются в апострофы, выводится то, что в апострофах.
Форматы вывода:
1) для целых чисел и строк: х:М, где М – ширина поля вывода (количество
позиций, выделяемых под запись числа х)
2) для вещественных чисел: у:M:N, где N – количество цифр после десятичной
точки.
Пример 1:
S:=2.71828;
Writeln(‘_sum=’, S:7:3, ‘ ’:3, ‘p=’, 2+4);
№ позиции экрана:
На экране:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
_sum=
2 . 7 1 8
p = 6
Пример 2:
I:=’+’;
Writeln(i);
Writeln(i);
Write(i);
Writeln(i);
Write(i);
№ позиции:
1 2
На экране увидим: +
+
++
+
Замечание: оператор writeln; без параметров переводит курсор на следующую строку.
2) Для ввода данных используются процедуры read и readln.
Форма записи: read(<список параметров>);
readln(<список параметров>);
приостановит работу программы до ввода какого-либо (одного) числа: надо
набрать на клавиатуре число и нажать клавишу Enter. После этого введенное число
автоматически запишется в переменную, указанную в скобках
В качестве параметров указываются имена переменных, значения которых будут вводиться с
клавиатуры.
Выполняется процедура ввода следующим образом: приостанавливается работа программы и
ожидается ввод с клавиатуры стольких значений, сколько переменных указано в скобках.
Значения вводятся так:
1 способ: после каждого введенного значения нажимать клавишу Enter.
2 способ: после каждого введенного значения нажимать клавишу Пробел, а после
последнего введенного значения - клавишу Enter.
После окончания ввода одним из указанных способов, значения присваиваются переменным,
указанным в скобках, в соответствующем порядке.
6
Пример:
на экране:
Readln(a,b,c);
Read(x);
1 5 7.5
3.28
Замечания:
1. Отличие операторов read(<список параметров>); и readln(<список параметров>); заключается
в следующем: после read экранный курсор вывода остается на прежней строке, а после readln –
перемещается на следующую строку.
2. Оператор readln; без параметров осуществляет задержку выполнения программы до тех пор,
пока не будет нажата какая-либо клавиша. Например, в примере вычисления площади круга (см.
п.1.4) можно вместо команды delay(10000); применить readln. Отличие будет в том, что
delay(10000); задержит результат на экране в течении 10 секунд, затем вернется к исходному тексту
программы, а readln - задержит результат на экране до нажатия пользователем какой-либо клавиши,
затем так же вернется к исходному тексту программы.
Задачи для самоконтроля
1.1 Какой оператор является ошибочным?
const a =7.5;
b:rea =4.6;
var
c:real;
Begin
a:=3.4;
b:=5.2;
c:=8.5;
1.2 Вычислить значения выражений
а) trunc(6.9); б) round(6.9);
в) trunc(-1.8); г) round(-1.8).
1.3 Что увидим на экране после выполнения данного фрагмента программы:
a:=4;
write(a);
writeln; writeln(a);
write(a);
writeln(a);
writeln;
write(a);
1.4 Определите диапазон возможных значений числа X:
а) X:=random(56);
б) X:=random(25) – 32;
в) X:= 67 - random(43);
г) X:=random(98) – 32;
2. Простые типы данных
2.1 Целые типы
Эти типы обозначают множества целых чисел в различных диапазонах. Значения целого типа
могут задаваться в десятичном, например, 5; -10, или шестнадцатеричном виде (шестнадцатеричном
константы начинаются со знака $), например, $1A; $FFFF.
Тип
Shortint
Integer
Longint
Byte
Word
Размер в байтах
1
2
4
1
2
Диапазон допустимых значений
-128…127 (-27…27-1)
-32768…32767 (-215…215-1)
-231…231-1
0…255 (0…28-1)
0…65535 (0…216-1)
Над целыми числами допустимы следующие операции:
1) 4 арифметических операции:
+ сложение
* умножение
b:=a*b;
- вычитание / деление
c:=10/2-b;
7
2) 2 дополнительных операции:
div – деление нацело
b:=10 div 3 -> b=3; p:=32 div 5 -> p=6
mod – остаток от деления
b:=10 mod 3 -> b=1; p:=32 mod 5 -> p=2
3) операции сравнения:
<, >, <=, >=, =, <>
2.2 Вещественные типы
Группа вещественных типов обозначает множества вещественных значений в различных
диапазонах. Вещественные числа могут задаваться в форме с фиксированной точкой (например,
3.14159265; –10.2) или с плавающей точкой (например, 1.2Е–2 = 1.210-2; 2.1234Е15 = 2.12341015).
Тип
Real
Single
Double
Размер в байтах
6
4
8
Число значащих цифр
11-12
7-8
15-16
Диапазон
10-39…1038
10-45…1038
10-324…10308
Операции над переменными вещественного типа:
1) 4 арифметических операции: +, *, -, /
2) операции сравнения:
<, >, <=, >=, =, <>
Типы результатов операций
Операция
+, *, /
div, mod
<, >, =, <>, <=, >=
Типы операндов
Целые.
Хотя бы один вещественный
Целые, вещественные
Целые
Целые, вещественные
Тип результата
Целый.
Вещественный
Вещественный
Целые
Логический (п.2.4.)
2.3 Cимвольный тип данных
Char 1 байт
256 значений
Значениями этого типа являются символы из набора ASCII – американского стандартного кода для
обмена информацией.
Каждый символ имеет свой код от 0 до 255. Символы с кодами 0-127 – стандартные символы
ASCII:
0-31 – управляющие символы;
32-47 – знаки препинания;
48-57 – цифры;
58-127 – латинские буквы.
Расширение кода ASCII: 128-255 – русские буквы, псевдографика (│, ┌, ┐, └, ┘…).
Символы, имеющие графическое представление, заключаются в кавычки: С=’*’. Для символов, не
имеющих графического представления, используется знак #, после которого записывается код символа:
Пример:
#10
перевод строки
Var
c: char;
#13
переход к началу строки
x: integer;
#7
звуковой сигнал
begin
#8
возврат на символ
c:=’*’; x:=10;
Writeln(#7,a);
writeln (#7,c,x,c);
Writeln(#10,x);
end.
Для переменных символьного типа допустимы операции сравнения, при этом сравниваются коды
символов:
‘ ’<’10’
‘0’<’9’
‘a’>’A’
‘A’<’Z’
‘a’>’Z’
‘a’<’z’
Коды прописных латинских букв: A - 65; B – 66; C – 67 и т.д.
Коды строчных латинских букв: a - 97; b – 98; c – 99 и т.д.
8
Для преобразования символа в число, равное коду символа, и наоборот, используются следующие
функции:
chr(x) – преобразование ASCII-кода в символ; аргумент – целый 0-255;
ord(x) – преобразование символа в целое число.
Пример:
Var
n1,n2: integer;
c1,c2: char;
begin
c1:=’D’; n1:=ord(c1); writeln(‘n1 = ’, n1);
n2:=66; c2:=chr(n2); writeln(‘c2 = ’, c2);
end.
на экране:
n1 = 68
n2 = B
2.4 Логический тип данных.
Описание:
var
n: boolean;
Данные логического типа boolean могут принимать только два значения: true (истина) и false (ложь).
Для значений логического типа допустимы операции сравнения, причем true>false.Также применяются 4
логических операции:
and
логическое умножение
or
логическое сложение
xor
исключающее «или»
not
отрицание
Правила выполнения логических операций определяются с помощью следующих таблиц истинности:
X
true
false
Not X
false
true
X
true
true
false
false
Y
true
false
true
false
X and Y
true
false
false
false
X or Y
true
true
true
false
X xor Y
false
true
true
false
Пример 1:
not (5>2) = false
(5>2) and (3<10) = true
(8<>9) or (4>5) = true
not (5=2) xor (3>2) = false
Пример 2:
var
test: boolean;
a, b: integer;
begin
writeln (‘Введите а и b’);
readln (a,b);
test:=a>b;
writeln (‘а > b - ’, test);
end.
Пусть, например, введены числа:
5 16
тогда test:=5>16;
на экране: а > b - False
При сравнении данных типа BOOLEAN учитывается внутреннее соглашение Турбо Паскаля, в
соответствии с которым FALSE есть нулевой байт, a TRUE - байт с единицей в младшем разряде.
Заметим, что функция ORD преобразует к целому не только символы, но и логические величины,
поэтому
ord(false) = 0,
ord(true) = 1.
2.5 Ограниченные типы
На основе стандартных типов можно строить собственные типы, ограничивая диапазон возможных
значений: 1..10, -100..10, ‘a’..’z’ и т.п.
Пример:
var a: 2..5;
9
b: ‘a’..’z’;
begin
a:=3;
b:=0; {ошибка: несоответствие типов – переменной символьного типа присваивается целое число}
a:=0; {ошибка: выход за границы диапазона 2..5}
end.
2.6 Перечислимые типы
Образуются путем явного перечисления всех возможных значений, задаваемых именами.
Например, для программы управления светофором, может быть определен следующий тип:
var
svet: (red, yellow,green);
oper: (plus, minus);
Тип boolean – частный случай перечислимого типа.
2.7 Описание типов
Новые типы данных в Паскаль определяются посредством описаний, начинающихся со слова
TYPE. Описание состоит из имени типа и значения типа, между которыми ставится знак «=».
Пример:
Type dec=1..10;
abc=’A’..’z’;
int=integer;
var
a: dec;
{в разделе описания переменных var можно использовать не
b: abc;
только стандартные типы данных, но и новые типы, описанные
c: int;
программистом в разделе Type }
2.8 Преобразование типов
Как уже говорилось, тип переменной позволяет не только устанавливать длину ее внутреннего
представления, но и контролировать те действия, которые выполняются над ней в программе. Контроль
над использованием переменных еще на этапе компиляции программы - важное преимущество Турбо
Паскаля перед другими языками программирования, в которых допускается автоматическое
преобразование типов. В Турбо Паскале почти невозможны неявные (автоматические) преобразования
типов. Исключение сделано только в отношении констант и переменных типа INTEGER (целые), которые
разрешается использовать в выражениях типа REAL (вещественные). Если, например, переменные X и
Y описаны следующим образом:
var х: integer;
у: Real;
то оператор
у:=х + 2;
будет синтаксически правильным: хотя справа от знака присваивания стоит целочисленное выражение,
а слева - вещественная переменная, компилятор сделает необходимые преобразования автоматически.
В то же время оператор
х:=2.0;
будет неверным, так как автоматическое преобразование типа REAL (константа 2.0 содержит
десятичную точку и, следовательно, принадлежит к типу REAL) в тип INTEGER в Турбо Паскале
запрещено.
Таким образом, переменным можно присваивать значения только своего типа; единственное
исключение: переменная вещественного типа, а значение – целого (в этом случае целое число будет
преобразовано в вещественное с дробной частью, равной 0).
Разумеется, запрет на автоматическое преобразование типов еще не означает, что в Турбо Паскале нет
средств преобразования данных. Они, конечно же, есть, но их нужно использовать явно. Для
преобразования данных в языке существуют встроенные функции, которые получают в качестве
10
параметра значение одного типа, а возвращают результат в виде значения другого типа. В частности,
для преобразования REAL в INTEGER имеются даже две встроенные функции такого рода: ROUND
округляет REAL до ближайшего целого, a TRUNC усекает REAL путем отбрасывания дробной части (см.
п.1.5).
Например, ошибочным будет оператор
х := у/х;
но правильным
х := round(у/х);
(объявления переменных см. выше).
Например, для преобразования данных типа CHAR (символ) в целое число предназначена функция
ORD, обратное преобразование INTEGER в CHAR осуществляет функция CHR.
Наличие двух операций деления есть еще одно проявление основополагающего принципа Турбо
Паскаля: программист должен явно подтверждать компилятору, что он готов к возможным последствиям
преобразования типов. Если, например, в языке Фортран используется выражение 1/2 , то результат
этого выражения будет зависеть от того, переменной какого типа он будет присвоен: если N есть
переменная целого типа, а Х- вещественного, то в программе на Фортране присваивания
N = 1/2
X = 1/2
дадут значения 0 для N и 0.5 для X. В Турбо Паскале такой двусмысленности нет: выражение 1/2 всегда
имеет значение 0.5 и поэтому оператор
var N :integer;
begin
N := 1/2;
просто недопустим. В то же время допустимые в Турбо Паскале операторы:
var X : Real;
N: integer;
begin
N := 1 div 2;
X := 1 div 2;
И, наконец, об операциях отношения и логических операциях.
Над данными типа REAL, INTEGER, CHAR, STRING определены следующие операции отношения
(сравнения):
= - равно;
<> - не равно;
< - меньше;
> - больше;
<= - меньше или равно,
11
>= - больше или равно.
В операциях сравнения должны участвовать однотипные операнды. Исключение сделано опять-таки в
отношении REAL и INTEGER, которые могут сравниваться друг с другом. Результат применения
операции отношения к любым операндам имеет тип BOOLEAN.
2.9 Порядок вычисления выражений
Порядок выполнения операций, входящих в выражения, определяется приоритетом операций. Для
изменения порядка вычисления используются круглые скобки.
Приоритет операций:
1) вычисления в круглых скобках ( )
2) вычисления значений функций
3) унарные операции not
4) операции типа умножение *, /, div, mod, and
5) операции типа сложение +, -, or, xor
6) операции сравнения >, <, <=, >=, =, <>
Следует учесть, что в отличие от многих других языков программирования в Турбо Паскале логические
операции имеют более высокий приоритет, чем операции отношения. В связи с этим, в сложных
логических выражениях обычно необходимо расставлять скобки. Если, например, b и с имеют тип
INTEGER , то выражение
а = b and с < d
вызовет сообщение о синтаксической ошибке, так как сначала выполнится операция b and с.
Правильным будет выражение:
(а = b) and (с < d)
Задачи для самоконтроля
2.1 Вычислить значения выражений
а) 20 div 6; б) 20 mod 6;
в) 2 div 5; г) 2 mod 5;
д) 4 div 0; е) 2.0 mod 2.
2.2. а) Преобразовать арифметическое выражение в линейную форму записи, пригодную для ввода в
компьютер. Использовать следующие обозначения операций: умножение *, деление /, возведение в
степень ^, т.е. x3 = x^3.
A
5
( x  y )  7 ,5 y 
2 xy
2
2x
y

6yz
 x5
3 y
3x
б) Преобразовать линейную форму записи арифметического выражения в «многоэтажное»
представление, обычно используемое в математике:
B:=(x/(y+3*(x–y))^2–(y+9)^3/4)/(x^2*y)+9.5*y^2+y*(8+x/(2*y)).
2.3 Какие операторы являются ошибочными?
var
x:integer;
y:real;
Begin
x:=3.4; y:=5;
x:=6; y:=2.5;
x:=y;
y:=x;
x:= 6/3;
x:= 6 div 3; y:= 6 div 2;
2.4 Вычислить значения выражений
а) not (6>=4) and (2<8)
б) ((5>=9) or (4>2)) and (6<12)
12
3. Операторы языка Паскаль
Описывают некоторые действия, которые необходимо выполнить для решения задачи. Тело
программы представляет собой последовательность операторов (команд), которые разделяются «;».
Напомним порядок выполнения операторов программы: слева направо сверху вниз.
3.1 Оператор присваивания
Обозначается := . Вызывает вычисление выражения стоящего справа от него, и присваивание
вычисленного значения переменной, стоящей слева. Таким образом, с помощью этого оператора в
ячейку памяти, имя которой указано слева от знака := , заносится значение, находящееся справа от
знака := .
Фрагмент программы:
Содержимое ячеек памяти (имя указано слева)
после выполнения соответствующей команды присвоения:
y:=7;
y
7
x:=y;
x
7
a:=3; b:=25
a
3
z:=a+b;
z
i:=4; j:=8;
i
4
res:=(i>0) and (i<100);
res
True
k:=sqr(a)+i*j;
k
41
b
25
28
j
8
3.2 Составной оператор
Представляет собой совокупность последовательно выполняемых операторов, заключенных в
операторные скобки begin … end. Структура оператора следующая:
begin
<оператор 1>;
<оператор 2>;
…
<оператор 3>;
end;
Используется, когда необходимо выполнить несколько действий, а синтаксисом языка допускается
только один оператор. Само тело программы тоже можно считать составным оператором.
3.3 Условный оператор
Реализует алгоритмическую конструкцию «развилка».
Условный оператор позволяет выполнить один из двух возможных операторов в зависимости от
некоторого условия. Структура условного оператора следующая:
if <условие> then <оператор 1> else <оператор 2>;
Условие должно иметь логический тип. Если значение условия равно true, то выполняется
Оператор 1, если условие равно false, то Оператор 2. Перед else точка с запятой не ставится.
if a>b then max:=a else max:=b;
Например, если a=3, b=7, то выполнится оператор max:=a; в противном случае, т.е.
если a=7, b=3, то выполнится оператор max:=b; .
Часть условного оператора, начинающаяся со слова else, может отсутствовать. Тогда, если
условие истинно, выполняется оператор1, если ложно, то выполняется оператор, следующий за
условным.
if x=0 then writeln(‘ошибка’);
Если при выполнении или невыполнении условия необходимо выполнить несколько действий, то
организуется составной оператор.
13
if a>b then
begin max:=a; min:=b; end
else begin min:=a; max:=b; end;
Например, если a=3, b=7, то выполнятся операторы max:=a; min:=b; в противном случае, т.е.
если a=7, b=3, то выполнятся операторы min:=a; max:=b; .
Для схематической записи алгоритмов решения задач существует язык блок-схем. Приведем
основные элементы блок-схемы:
Действие
Блок
Начало
Начало процесса
x, y
Ввод данных
Присваивание
Проверка условия
Заголовок цикла
x:=y
нет
a>b
да
i=1,k
Вывод результатов
x, y
Конец процесса
конец
Блок-схема нахождения корней квадратного уравнения
14
начало
a, b, c
d=b2-4ac
нет
d>=0
да
нет
Нет корней
x1 
b d
2a
x2 
b d
2a
d=0
да
x=-b/2a
x1, x2
x
конец
Схемы условного оператора:
полного
сокращенного
if
then
условие
оператор1
if
else
условие
оператор2
then
оператор1
вложенного:
if
then
условие1
if
else
then
if
then
оператор1
оператор2
else
условие2
условие2
оператор3
if <условие 1> then <оператор 1>
else if <условие 2> then <оператор 2>
else <оператор 3>
условие1
else
if
then
оператор1
оператор2
if <условие 1> then
if <условие 2> then <оператор 1>
else <оператор 2>;
Условные операторы могут быть вложенными друг в друга. В этом случае else связывается с
ближайшим к нему if:
if (a>b) and (a>c) then max:=a
else if (b>c) then max:=b
else max:=c;
15
Например, если a=7, b=2, c=4, то выполнится оператор max:=a; , т.к. (a>b) and (a>c)=True (истина);
в противном случае, т.е. если (a>b) and (a>c)=False (ложь), выполнится оператор
if (b>c) then max:=b
else max:=c;
если, например, a=2, b=7, c=4, то выполнится оператор max:=b;
если, например, a=2, b=4, c=7, то выполнится оператор max:=с;.
Пример:
var
i,j: integer;
ok: boolean;
begin
writeln(‘Введите i и j > 0’);
readln(i,j);
ok:=(i>0) and (j>0);
if (not ok) then begin
writeln(‘Неверный ввод’);
halt;
end;
end.
3.4 Оператор выбора CASE
С помощью этого оператора можно выбрать вариант из любого количества вариантов.
Структура оператора:
case <ключ выбора> of
константа1: оператор1;
константа2: оператор2;
…
константаN: операторN;
else оператор;
end;
<ключ выбора> - переменная или выражение, значение которого вычисляется. Далее выполняется
оператор, которому предшествует константа, равная вычисленному значению. Если константы,
соответствующей значению ключа выбора не найдено, то выполняется оператор после else (эта часть
может отсутствовать).
В качестве ключа выбора может использоваться выражение порядкового типа, константа должна
быть того же типа. В качестве констант можно использовать диапазоны или списки значений через
запятую.
case i of
0,2,4,6,8: writeln(‘четная цифра’);
1,3,5,7,9: writeln(‘нечетная цифра’);
10..100: writeln(‘число от 0 до 100’);
else writeln(‘отрицательное число или >100’);
end;
Пример: программа-калькулятор
var
op: char;
x,y,r: real;
err: boolean;
begin
err:=false;
write(‘Введите х, у’); readln(x,y);
write(‘Определите операцию’); readln(ор);
case op of
‘+’: r:=x+y;
‘-’: r:=x-y;
‘*’: r:=x*y;
‘/’: r:=x/y;
else err:=true;
end;
if err then writeln(‘Неверно заданная операция’)
else writeln(х, ор, у, ‘=’, r);
end.
3.5 Оператор цикла с параметром (цикл FOR)
Циклом называется последовательность действий, выполняемая более одного раза. В Паскаль есть три
различных типа операторов, позволяющих запрограммировать циклический процесс: оператор цикла с
16
параметром (цикл FOR); оператор цикла с предусловием (цикл WHILE) и оператор цикла с постусловием
(цикл REPEAT).
Рассмотрим работу оператора цикла с параметром (цикл FOR). Начнем с примера. Пусть требуется
вывести на экран строку из пяти звездочек через пробел. Рассмотрим три варианта решения:
1 вариант:
Begin
Write(‘* * * * *’);
End.
2 вариант:
Begin
Write(‘* ’);
Write(‘* ’);
Write(‘* ’);
Write(‘* ’);
Write(‘* ’);
End.
3 вариант:
var i: integer;
Begin
for i:=1 to 5 do
Write(‘* ’);
End.
Команду for i:=1 to 5 do Write(‘* ’); можно прочитать так: “Для i от 1 до 5 делай команду вывода звездочки”.
Переменная i изменит автоматически свое значение 5 раз (от 1 до 5 с шагом 1), а, следовательно, и
оператор, записанный после слова do, повторится 5 раз.
В данном примере самым простым является первый вариант решения, однако если потребовалось бы
вывести на экран 100 звездочек, то сразу стало бы понятно преимущество третьего варианта.
Теперь перейдем к теоретической части.
Оператор цикла с параметром имеет следующую структуру:
заголовок цикла for <параметр>:=<начальное значение> to <конечное значение> do
тело цикла <оператор>;
Этот оператор используется, когда число повторений заранее известно.
Работает: В заголовке параметр цикла автоматически изменяется от начального значения до
конечного с шагом 1 и каждый раз выполняется тело цикла - оператор после do.
for i:= 0 to 9 do write(i); На экране: 0123456789
T.e. сколько раз параметр цикла изменит свой значение от начального до конечного включительно с
шагом один, столько раз выполнится тело цикла.
Схема оператора FOR:
k=1,10
оператор1
Параметр цикла – переменная целого, порядкового или символьного типа, начальное и конечное
значения – переменные или выражения того же типа, причем выражения вычисляются один раз, до
начала выполнения цикла. Если начальное значение параметра сразу превышает конечное, то тело
цикла не выполнится ни разу.
Пример 1.
var
k,x: integer;
begin
x:=2;
for k:=x-2 to sqr(x) do
x:=k;
end.
Этапы работы данной программы:
1. x:=2
2. начальное значение параметра k = 0
конечное значение параметра k = 4
3. k:=0
Пример 4.
var
p, h: integer;
begin
h:=5;
for p:=1 to 3 do
h:=h+p;
writeln(‘h=’,h);
end.
Этапы вычисления:
h + p →h :
5 + 1 →6
17
4. проверка: если к<=4 то на п.5
если к>4 то на п.
5. выполнение тела цикла:
x:=k;
Замечание: изменение значения x в теле цикла
уже не влияет на начальное и конечное
значения параметра цикла.
6. возврат на заголовок цикла.
В заголовке: k:=k+1 (автоматически) и п.4
7. Переход к следующему оператору программы
после цикла For .
Пример 2.
var
c: char;
begin
for c:= ‘A’ to ‘D’ do
write(c);
end.
6 + 2 →8
На экране:
ABCD
Пример 3.
var
p, h: integer;
begin
h:=5;
for p:=3 to 1 do
h:=h+p;
writeln(‘h=’,h);
end.
Этапы работы:
h + p →h :
На экране:
h=5
В результате на экране:
h=6
h=8
h=11
(см. пояснения ниже)
8 + 3 →11
На экране:
h=11
Пример 5.
Внесем в программу примера 4 некоторые
изменения:
var
p, h: integer;
begin
h:=5;
for p:=1 to 3 do
begin
h:=h+p;
writeln(‘h=’,h);
end;
end.
5 + 1 →6
вывод на экран: h=6
6 + 2 →8
вывод на экран: h=8
8 + 3 →11
вывод на экран: h=11
Если тело цикла состоит из нескольких операторов, то организуется составной оператор begin..end;
Пример: Вычислить и вывести на экран 100 значений функции y=sin x. Начальное значение x=0; x
изменяется с заданным шагом H.
var
x,y,H: real;
i: integer;
begin
x:=0; H:=0,1;
for i:= 1 to 100 do
begin
y:=sin(x);
writeln(‘y = ’, y);
x:=x+H;
end;
end.
Таким образом, если необходимо повторить заданное количество раз не одну команду, а
последовательность команд, то эта последовательность заключается в так называемые операторные
скобки begin..end; . Если после слова do нет слова begin, то система считает телом цикла только одну
команду, записанную после слова do. Если после слова do есть слово begin, то система считает телом
цикла все команды, записанные между словами begin и end. А работает оператор цикла и в том и в
другом случаях одинаково: тело цикла повторяется столько раз, сколько раз меняет свое значение
параметр цикла от начального до конечного включительно с шагом 1.
Замечания:
1) Переменная-параметр цикла должна быть обязательно описана в разделе описания переменных
var. Имя параметра – любое.
2) В теле цикла можно использовать параметр, но запрещается его явное изменение (например,
присваиванием i:=… или вводом с клавиатуры read(i)).
3) По окончании цикла переменная-параметр цикла считается неопределенной, хотя на практике
последнее значение этой переменной сохраняется.
18
Пример:
var
k,p: integer;
begin
x:=5;
for k:=x+1 to x+5 do
begin
x:=x-2;
p:=sqr(k);
writeln(x,’ ‘,p);
end;
end.
k=6
7
8
9 10
x = 3 1 -1 -3 -5
p = 36 49 64 81 100
В результате работы программы на экране увидим:
3 36
1 49
-1 64
-3 81
-5 100
Второй вариант оператора FOR:
заголовок цикла for <параметр>:=<начальное значение> downto <конечное значение> do
тело цикла <оператор>;
В этом операторе параметр изменяется от начального значения до конечного с шагом -1, т.е.
уменьшается на 1 при каждом выполнении цикла. Если начальное значение сразу меньше конечного, то
тело цикла не выполняется ни разу.
Пример: отсчет при запуске ракеты.
uses crt;
var
i: integer;
begin
for i:= 9 downto 1 do
begin
write(#8,i);
delay(2000);
end;
write(#8,’Пуск’);
end.
Еще некоторые примеры программ.
Пример 1: Вычисление суммы чисел S=1+2+3+…+N.
var
n, p, s: integer;
begin
s:=0;
write(‘Введите n’); readln(n);
for p:= 1 to n do
s:=s+p;
writeln(‘S = ’, s);
end.
Пример 2: Вычисление суммы чисел S=0,2+ 0,4+ 0,6+…+2.
const n=10;
var
p, s, x: integer;
begin
s:=0; x:=0.2;
for p:= 1 to n do
begin
s:=s+ x;
x:=x+ 0.2;
end;
writeln(‘S = ’, s);
end.
В данном примере использование оператора цикла For нецелеобразно, т.к. в задании явно не указано
число повторений суммирования. В таких случаях применяют циклы с условиями: While или Repeat (см.
пп. 3.6, 3.7)
19
Пример 3: Вычисление факториала n!=1*2*3*…*N.
var
n,i: integer;
f: longint;
begin
write(‘Введите n’); readln(n);
f:=1;
for i:= 1 to n do
f:=f*i;
writeln(‘Факториал f = ’, f);
end.
3.6 Оператор цикла с предусловием (цикл WHILE)
Обычно используется, когда число повторений заранее неизвестно.
Структура оператора:
заголовок цикла - while <условие> do
тело цикла <оператор>;
(при условии истинном выполняется оператор)
Условие – логическое выражение, определяющее момент окончания циклических вычислений (цикл
выполняется, пока условие истинно). Проверка условия производится перед каждым выполнением тела
цикла. Если условие ложно сразу, тело цикла не выполняется ни разу.
Обычно в теле цикла требуется выполнить несколько операторов, поэтому используется составной
оператор begin…end.
Схема оператора:
while
условие
false
true
оператор
Пример:
var x:integer;
Begin
x:=4;
while x>0 do
begin
x:=x-2;
writeln(x);
end;
End.
На экране:
2
0
В теле цикла должны изменяться переменные, входящие в условие, с тем, чтобы условие, в конце
концов, стало ложным, и цикл завершился. В противном случае возникает так называемый бесконечный
цикл. Прервать выполнение бесконечного цикла можно с помощью клавиш ctrl-break.
Пример 1: while y<0 do writeln (y);
бесконечные циклы (в примере1 – если y:=-1;)
Пример 2: while true do begin…end;
Пример 3: Вычисление суммы чисел S=0,2+ 0,4+ 0,6+…+2.
const n=2;
var
s, x: integer;
begin
s:=0; x:=0.2;
while x<=n do
begin
s:=s+ x;
x:=x+ 0.2;
end;
writeln(‘S = ’, s);
end.
Пример 4: Программа вычисления суммы S=1+1/2+1/3+…+1/1000
20
var
i: integer;
s: real;
begin
i:=1; s:=0;
while i<=1000 do
begin
s:=s+1/i;
i:=i+1;
end;
writeln(‘S’, s:7:3);
end.
или for i:= 1 to 1000 do s:=s+1/i;
Пример 5: Программа вычисления суммы S=1-1/4+1/9-1/16… с точностью ε = 0,001
(считается, что требуемая точность достигнута, если очередное слагаемое по модулю меньше ε, т.е. все
последующие слагаемые можно не учитывать).
1 вариант:
var
i, zn: integer;
s: real;
begin
i:=1; s:=0; zn:=1
while 1/sqr(i) > = 0.001 do
begin
s:=s+1/sqr(i)*zn;
i:=i+1;
zn:=-zn;
end;
writeln(‘S = ’, s);
end.
2 вариант:
var
i: integer;
s: real;
begin
i:=1; s:=0;
while 1/sqr(i) > = 0.001 do
begin
if Odd(i) then s:=s+1/sqr(i)
else s:=s -1/sqr(i);
i:=i+1;
end;
writeln(‘S = ’, s);
end.
3 вариант:
var
i: integer;
s: real;
begin
i:=1; s:=0;
while 1/sqr(i) > = 0.001 do
begin
if (i mod 2=0) then s:=s-1/sqr(i)
else s:=s+-1/sqr(i);
i:=i+1;
end;
writeln(‘S = ’, s);
end.
3.7 Оператор цикла с постусловием (цикл REPEAT)
Обычно используется, когда число повторений заранее неизвестно.
Структура оператора:
repeat < операторы > until < условие >;
(операторы повторяются до тех пор, пока не выполнится условие)
Условие – логическое выражение, определяющее момент окончания циклических вычислений (цикл
выполняется, пока условие ложно). Когда условие становится истинным, осуществляется выход из
21
цикла. Проверка условия производится в конце тела цикла, поэтому он всегда выполняется хотя бы
один раз.
Под телом цикла понимается последовательность операторов между словами repeat и until.
Операторов может быть один и более. В любом случае операторные скобки begin…end не требуются.
Пример:
var i:integer;
Begin
i:=4;
repeat
i:=i-1;
writeln(i);
until i<0;
(выполнится 4 раза: i=3,2,1,0)
End.
Схема оператора:
repeat
оператор
false
условие
true
В теле цикла должны изменяться переменные, входящие в условие, чтобы не получился бесконечный
цикл.
Пример 1: repeat … until false;
бесконечный цикл
Пример 2: repeat until keypressed;
цикл до нажатия любой клавиши
keypressed – стандартная логическая функция, принимает значение true, если была нажата
клавиша.
Пример 3: Вычисление суммы чисел S=0,2+ 0,4+ 0,6+…+2.
const n=2;
var s, x: integer;
begin
s:=0; x:=0.2;
repeat
s:=s+ x;
x:=x+ 0.2;
until x>2;
writeln(‘S = ’, s);
end.
Пример 4: Вычисление квадратного корня числа, введенного с клавиатуры.
var
a,b: real;
begin
repeat
writeln(‘Введите а>0’);
readln(a);
until a>0;
b:=sqrt(a);
writeln(‘b=’,b);
end.
Пример 5: Программа, считывающая с клавиатуры символ и печатающая его код
var
k: integer;
ch: char;
begin
repeat
writeln(‘Введите символ’);
readln(ch);
k:=ord(ch);
writeln(‘Код символа’, ch, ‘ = ’,k);
until k=13; {13 – код пробела}
end.
Основные отличия операторов цикла:
22
1. Цикл FOR используется, когда число повторений заранее известно, циклы WHILE и REPEAT –
когда неизвестно.
2. В цикле FOR параметр цикла изменяется с шагом 1, в циклах WHILE и REPEAT необходимо
изменять переменные, входящие в условие.
3. В циклах FOR и WHILE несколько операторов объединяются операторными скобками begin…end,
в цикле REPEAT это не требуется.
4. В циклах FOR и WHILE проверка условия выполняется перед очередным выполнением тела
цикла, в цикле REPEAT – после выполнения тела цикла.
3.8 Вложенные циклы
Тело цикла может содержать любые операторы языка Паскаль, в т.ч. и операторы циклов. Когда один
цикл находиться внутри другого, то его называют вложенным циклом.
Примеры вложенного цикла For:
1.
var a,b:integer;
begin
for i:= 1 to 2 do
for j:= 1 to 3 do
writeln(i, ‘ ’, j);
{выполнится 6 раз}
end.
На экране увидим:
11
12
13
21
22
23
2.
var a,b:integer;
begin
for i:= 1 to 2 do
begin
for j:= 1 to 3 do writeln(i, ‘ ’, j); {выполнится 6 раз}
writeln(‘******’);
end;
end.
На экране увидим:
11
12
13
******
21
22
23
Правило выполнения:
на каждом шаге внешнего цикла полностью выполняются все шаги внутреннего цикла.
Пример 1: Программа вычисления и вывода на экран таблицы умножения (Пифагора).
var
i,j: integer;
begin
for i:=1 to 9 do
begin
for j:=1 to 9 do
write(i*j:4);
writeln;
end;
end.
Пример 2: Программа вычисления значений функции f(x,y)=sin(x)*cos(y), где х=0..π с шагом π/5 и у=0..1 с
шагом 0,1.
var
x,y,f: real;
begin
x:=0;
repeat
y:=0;
while y<=1 do
23
begin
f:=sin(x)*cos(y);
write(f:6:3);
y:=y+0,1;
end;
x:=x+pi/5;
writeln;
until x>pi;
end.
3.9 Оператор перехода GOTO
Оператор перехода позволяет изменить обычный последовательный порядок выполнения
операторов в программе. Он вызывает переход к выполнению оператора, которому предшествует метка.
Структура оператора:
GOTO <метка>;
…
…
< метка >: <оператор>;
Метка – это число от 0 до 9999, или идентификатор. Метки, используемые в программе, должны быть
описаны:
LABEL 1, 2, Met;
Нельзя использовать оператор GOTO для перехода в подпрограммы, а также внутрь операторов цикла,
условного и составного операторов.
Использование оператора перехода в Паскаль считается избыточным, поэтому следует избегать его
использования в программах. В крайнем случае можно применять GOTO для перехода вниз по тексту
программы (вперед) .
Пример: Частное от деления целых чисел.
Label
M1;
var
x,y,res: integer;
begin
write(‘Введите x,y’);
readln(x,y);
if y=0 then
begin
writeln(‘Деление на ноль!’);
goto M1;
end;
res:=x div y;
writeln(‘Частное = ’, res);
M1: writeln(‘Конец программы’);
end.
Задачи для самоконтроля
3.1 Определить, какие значения x, y, z будут напечатаны после выполнения программы.
var
x,y,z: real;
begin
x:=-2; y:=3; z:=3.5;
z:=x-2.5;
y:=x-y+2*z;
x:=x+y-2*z;
x:=y-2*x;
y:=x+2*y+z;
z:=(x+y)*2;
writeln(‘x=’,x,’ y=’,y,’ z=’,z);
end.
3.2
а) Определить значение переменной x после работы следующего фрагмента программы:
a = 8; b = 3 * a – 4; x = 0; y = 2 * b;
if ( 2 * a > b ) or (4 * a < y ) then begin x = 7; y = –15 end;
if ( x > 0 ) and ( 2 * a + b < y ) then begin x = 5; y = –7 end;
24
б) Определить значение переменной x после работы следующего фрагмента программы:
a = –3; b = –4 * a –2; x = 1; y = b/2 – 1;
if ( 5 * a > b ) or ( y > a ) then begin x = x + 2; y = x – 3 end;
if ( 2 * a + 8 > y ) and ( y < x ) then begin x = y + 5; y = 6 end;
3.3 Определить значение переменной x после работы следующих фрагментов программы:
а)
x:=5;
for i:=2 to 4 do x:= x – 2;
б)
x:=4; y:=2;
While y<= 4 do begin
x:=x - 2;
y:=y+1;
end;
в)
x:=4; y:=2;
Repeat
x:=x - 2;
y:=y+1;
until y>=4 ;
4. Массивы
Массивы относятся к структурированным типам данных. В отличие
структурированные типы определяют наборы однотипных или разнотипных компонент.
В Паскале существуют следующие структурированные типы:
1) Массивы
2) Записи
3) Множества
4) файлы
от
простых,
4.1 Одномерные массивы
Массив представляет собой фиксированное количество элементов одного и того же типа. Такой
способ организации позволяет обозначать все значения этого типа одним именем, а для доступа к
отдельным элементам массива использовать это имя и индекс (порядковый номер) необходимого
элемента.
Например, пусть для решения какой-либо задачи требуется в программе выделить 7 ячеек памяти и
занести в них начальные значения, равные нулю.
Как бы вы это сделали,
используя простые переменные:
используя массив:
Var a, b, c, d, e, g, h: integer;
Begin
a:=0;
b:=0;
c:=0
d:=0;
e:=0;
g:=0;
h:=0;
…
Var a: array [1..7] of integer;
p:integer;
Begin
for p:=1 to 7 do a[p]:=0;
…
В памяти наш массив можно представить следующим образом:
a1, a2, a3, a4, a5, a6, a7
Описание массива
var <имя>: array [n1..n2] of <тип элементов>;
- одномерный массив, имеет один размер – количество элементов:
n1 – начальный индекс массива (порядковый номер 1-го элемента),
25
n2 – конечный индекс массива (порядковый номер последнего элемента),
<тип> - тип элементов массива.
Индексы задаются константами, обычно целого или символьного типа. Тип элементов массива может
быть любой.
Пример 1:
var
var
a: array [-2..5] of integer; {8 элементов целого типа}
b: array [0..3] of integer; {4 элемента целого типа }
Доступ к элементам массива осуществляется указанием имени массива, за которым в квадратных
скобках указывается значение индекса элемента: имя[индекс]
В качестве индекса можно использовать:
 константы: а[5], b[38]
 переменные: a[i], b[k]
 выражения: a[i+1], b[2*i]
Элементы массива можно использовать везде, где допустимо использование простых переменных.
Обычно при работе с массивами используют операторы цикла.
Необходимо следить за тем, чтобы индекс массива не выходил за диапазон, указанный при описании
(типичная ошибка).
Пример 1.
var
mas: array [1..10] of real;
i: integer;
begin
mas[11]:=0; {ошибка трансляции}
mas[1]:=1;
for i:=1 to 10 do
mas [i+1]:=mas[i]*2;
{ошибка выполнения}
при i=1 mas[2]: = mas[1]*2
при i=2 mas[3] := mas[2]*2
………………………
при i=10 mas[11] := mas[10]*2
end.
Пример 2. Ввести с клавиатуры массив из 10 элементов и вычислить сумму элементов.
var
a: array [0..9] of real;
s:real;
i:integer;
begin
writeln (‘Введите 10 элементов массива’);
for i:=0 to 9 do readln (a[i]);
s:=0;
for i:=0 to 9 do s:=s+a[i];
writeln (‘сумма=’, s);
end.
Пример 3: Ввести с клавиатуры массив положительных чисел (ввод закончить отрицательным числом).
Определить максимальный элемент массива.
var
m: array [1..1000] of real;
p, max: real;
i,n: integer;
begin
i:=1;
repeat
write(‘Введите ’,i,’ элемент’);
readln(p);
if p>0 then m[i]:=p;
i:=i+1;
until p<0;
n:=i-1;
max:=m[1];
for i:=1 to n do
if m[i]>max then max:=m[i];
writeln(‘max = ’, max);
end.
Пример 4: Сформировать массив из 50 случайных целых чисел, распечатать его и определить номер
элемента, ближайшего к среднему арифметическому.
26
var
b: array [1..50] of integer;
ras, s: real;
num, i: integer;
begin
randomize;
for i:= 1 to 50 do b[i]:=random(100);
for i:= 1 to 50 do write(b[i], ‘ ’);
s:=0;
for i:= 1 to 50 do s:=s+b[i];
s:=s/50;
num:=1;
ras:=abs(s-b[1]);
for i:=2 to 50 do
if abs(s-b[i])<ras then
begin
ras:=abs(s-b[i]);
num:=i;
end;
writeln(‘Среднее = ’,s,’ ближайший элемент b[’,num,’]=’,b[num]);
end.
Пример 5: Использование стандартных процедур BREAK и CONTINUE в операторах циклов. В массиве
целых чисел найти первое отрицательное число и вывести его на экран.
const
n=10;
var
a: array [1..n] of integer;
i: integer;
yes: boolean;
begin
writeln(‘Введите элементы массива’);
for i:=1 to n do
begin
write(‘a[’,i,’]=’);
readln(a[i]);
end;
yes:=false;
for i:=1 to n do
begin
if a[i]>=0 then continue; { continue – возврат на заголовок цикла}
writeln(‘первое отрицательно число = ’, a[i]);
yes:=true;
break; { break – окончание выполнения цикла и переход к следующему оператору
программы, в данном примере – к условному оператору if }
end;
if not yes then writeln(‘Отрицательных чисел нет’);
end.
4.2 Сортировка элементов массива
Сортировкой массива называется расстановка элементов массива в возрастающем или убывающем
порядке.
Существует множество методов сортировки, рассмотрим два наиболее простых и распространенных
метода: метод прямого выбора и метод «пузырька».
Метод прямого выбора (через поиск максимального и минимального элемента).
Алгоритм сортировки по возрастанию (через поиск минимального элемента):
1. Определяется минимальный элемент массива и помещается на 1-е место
2. Среди оставшихся элементов (начиная со 2-го) определяется минимальный элемент и
помещается на 2-е место.
3. Среди оставшихся элементов (начиная со 3-го) определяется минимальный элемент и
помещается на 3-е место.
4. И т.д. до конца массива.
Пример:
35871
1|5 8 7 3
27
1 3|8 7 5
13578
Программа:
var
a: array [1..10] of real;
i,j: integer;
t: real;
begin
randomize;
for i:= 1 to 10 do
begin
a[i]:=random;
write(a[i]:6:3);
end;
writeln;
for i:= 1 to 9 do
for j:=i+1 to 10 do
if a[i]>a[j] then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
end;
for i:= 1 to 10 do write (a[i]:6:3);
end.
Для обмена значениями двух переменных обычно используют дополнительную переменную
(дополнительную ячейку памяти), в приведенной выше программе – это переменная t.
Метод «пузырька» (перестановок).
Алгоритм сортировки по возрастанию:
1. Сравниваются попарно соседние элементы: 1-й со 2-м, 2-й с 3-м, 3-й с 4-м и т.д. до конца
массива. Если соседние элементы расположены не по возрастанию, то они меняются местами.
Таким образом, максимальный элемент массива «всплывает» на последнее место.
2. Снова сравниваются попарно соседние элементы и меняются местами, если не по возрастанию.
Всплывает элемент, меньший максимального, на предпоследнее место.
3. И т.д. до тех пор, пока будут перестановки.
Пример:
358 7 1
35718
35178
31578
13578
Программа:
var
a: array [1..10] of real;
i: integer;
t: real;
b: boolean;
begin
randomize;
for i:= 1 to 10 do
begin
a[i]:=random;
write(a[i]:6:3);
end;
writeln;
repeat
b:=false;
for i:= 1 to 9 do
if a[i]>a[i+1] then
begin
28
t:=a[i];
a[i]:=a[i+1];
a[i+1]:=t;
b:=true;
end;
until b=false; {Если b=false – это значит, что не было ни одной перестановки. Следовательно,
массив отсортирован, переходим к выводу отсортированного массива на экран: }
for i:= 1 to 10 do write(a[i]:6:3);
end.
4.3 Многомерные массивы
В качестве элементов массива могут быть значения любого типа, в том числе и массивы, например:
var
a: array [N1..N2] of array [N3..N4] of real;
Обычно используют более короткую форму записи:
var
a: array [N1..N2, N3..N4] of real;
- двумерный массив (матрица), имеет два размера:
N1..N2 – диапазон изменения первого индекса (номер строки)
N3..N4 – диапазон изменения второго индекса (номер столбца)
Пример 1:
var
a: array [1..3, 1..4] of integer;
a11 a12 a13 a14
a21 a22 a23 a24
a31 a32 a33 a34
Пример 2:
var
b: array [1..5, 1..5, 1..5] of real; - трехмерный массив
Мы будем использовать только одномерные и двумерные массивы.
Обращение к элементам:
a[1,3]:=0;
a[3,2]:=5;
В памяти:
1
1
2
3
2
3
4
0
5
Замечание: Размер любого массива не должен превышать 64 кбайта.
Как вычислить размер массива рассмотрим на примере 1. Массив a имеет размер 3x4, т.е. состоит из 12ти элементов. Элементы массива a целого типа, т.е. каждый элемент занимает 2 байта памяти.
Следовательно, весь массив занимает 24 байта памяти.
При обработке матрицы внешний цикл может быть по номеру строки, а внутренний цикл – по номеру
столбца матрицы:
for str:= 1 to 3 do
for stb:= 1 to 4 do
write (a[i,j]);
либо наоборот: внешний цикл - по номеру столбца, а внутренний цикл – по номеру строки матрицы:
for stb:= 1 to 4 do
for str:= 1 to 3 do
write (a[i,j]);
В результате выполнения 1-го фрагмента программы увидим на экране содержимое элементов массива
в следующем порядке: a11 a12 a13 a14 a21 a22 a23 a24 a31 a32 a33 a34
В результате выполнения 2-го фрагмента программы - в другом порядке:
a11 a21 a31 a12 a22 a32 a13 a23 a33 a14 a24 a34
Пример 3: Заполнить матрицу размерностью 5х10 целыми случайными числами в диапазоне от 0 до 99 и
найти минимальный элемент матрицы и сумму элементов.
var
m: array [1..5,1..10] of integer;
29
i,j,s, min: integer;
begin
randomize;
for i:=1 to 5 do
begin
for j:=1 to 10 do
begin
m[i,j]:=random(100);
write(m[i,j]:4);
end;
writeln;
end;
s:=0; min:=m[1,1];
for i:=1 to 5 do
for j:=1 to 10 do
begin
s:=s+m[i,j];
if m[i,j]<min then min:=m[i,j];
end;
writeln(‘S = ’,s,’ min = ’,min);
end.
Пример 4: Сформировать матрицу размерностью 5х5, где aij=i*j , и вывести ее на экран;
определить сумму элементов каждого столбца матрицы и вывести полученные значения на экран.
var
a: array [1..5,1..3] of integer;
sum,i,j: integer;
begin
for i:=1 to 5 do
begin
for j:=1 to 3 do
begin
a[i,j]:=i*j;
write(a[i,j]:4);
end;
writeln;
end;
for j:=1 to 3 do
begin
sum:=0;
for i:=1 to 5 do
sum:=sum+ a[i,j];
writeln(‘сумма ’,,j,’-го столбца = ’,sum);
end;
end.
Задачи для самоконтроля
4.1 Какой оператор является ошибочным?
var a: array [0..5] of integer;
p: integer;
Begin
a[1]:=8;
p:=5;
a[p+1]:=7;
4.2 Определите значение sum после выполнения программы:
var a: array [1..2,1..3] of integer;
p, sum: integer;
Begin
a[1,1]:= 8; a[1,2]:= - 6; a[1,3]:= 2;
a[2,1]:= 4; a[2,2]:= 9; a[2,3]:= - 5;
for p:=1 to 2 do
sum:= sum + a[p,p];
end.
30
5. Подпрограммы (процедуры и функции)
Подпрограмма – относительно самостоятельная часть программы, имеющая свое имя и выполняющая
определенные действия.
Подпрограммы повышают надежность и наглядность программ, т.к. позволяют разрабатывать и
отлаживать каждый блок программы независимо (например, разными людьми).
Структура подпрограммы почти полностью повторяет структуру всей программы и состоит из следующих
частей:
 заголовок подпрограммы
 раздел описаний
 тело подпрограммы
В Паскаль имеются два вида подпрограмм – процедуры и функции. Они отличаются назначеием и
способом их использования. Процедуры служат для выполнения определенной последовательности
действий, направленных на изменение программной обстановки (изменение значений переменных,
ввод/вывод данных и т.п.). Функции для вычисления значения выражения.
5.1 Процедуры
procedure <имя> (список формальных параметров);
<раздел описаний>;
begin
<тело процедуры>;
end;
Пример 1: Процедура вычисления и вывода на экран куба числа.
procedure cub(x: real);
var
y: real;
begin
y:=x*x*x;
writeln(y);
end;
Указание имени процедуры в программе приводит к активизации процедуры и называется ее вызовом.
Сразу после активизации процедуры начинают выполняться входящие в нее операторы. После
выполнения последнего оператора процедуры управление передается в основную программу и далее
выполняются операторы, следующие за вызовом процедуры. Процедура может вызываться в основной
программе неоднократно.
Например:
cub(5);
…
readln(z);
cub(z);
Основная пограмма
Вызов
процедуры
процедура
Для обмена информацией между основной программой и процедурой используются параметры, которые
придают процедуре универсальность.
Пример 2: Программа, выводящая на экран следующее:
*********
a=1
b=1
*********
a=2
b=4
*********
a=3
b=9
*********
31
a=4
b=16
*********
var
a,b: integer;
procedure Stars;
{без параметров}
var
i: integer;
begin
for i:=1 to 9 do write(‘*’);
writeln;
end;
begin
Stars;
for a:=1 to 4 do
begin
b:=sqr(a);
writeln(‘a=’,a,’ b=’,b);
Stars;
{вызов процедуры Stars }
end;
end.
Пример 3:
var
a,b: integer;
procedure Stroka(ch: char, n: integer);
var
i: integer;
begin
for i:=1 to n do write(ch);
writeln;
end;
begin
Stroka(‘+’,4);
for a:=1 to 3 do
begin
b:=sqr(a);
writeln(‘a=’,a,’ b=’,b);
Stroka(‘*’,8);
end;
end.
Разберем вызов процедуры Stroka(‘*’,8): ‘*’ и 8 – фактические параметры (т.е. те, которые указаны
в скобках после имени процедуры при ее вызове), они присваиваются при вызове формальным
параметрам ch и n (т.е. тем, которые указаны в скобках после имени процедуры при ее описании).
Замечание: количество, порядок и тип параметров при вызове процедуры должны совпадать с
количеством, порядком и типом параметров, заданным при описании процедуры.
Результат на экране:
++++
a=1
b=1
********
a=2
b=4
********
a=3
b=9
********
5.2 Функции
Функция отличается от процедуры тем, что результат работы функции возвращается в виде значения
через ее имя. Вызов процедуры – это отдельный оператор, а вызов функции может быть использован в
выражениях вместе с другими операторами (в правой части оператора присваивания или в операторе
write/writeln).
Пример:
стандартные процедуры:
write, writeln, read, readln, delay, clrscr…
стандартные функции:
sqr, sqrt, abs, odd, exp, ln, sin, cos…
32
Описание функции:
function <имя> (список формальных параметров): <тип>;
<раздел описаний>;
begin
<тело функции>;
end;
Пример 1: f(x,y)=
x2  y2 ;
function f (x,y: integer): real;
begin
f:=sqrt(sqr(x)+sqr(y));
end;
begin
……
z:=f(2,3);
writeln(‘f=’, f(6,8));
end.
n
Пример 2:
S 
i 1
var
1
i!(i  1)!(i  2)!
s:real;
i,n: integer;
function fact(k: integer): longint;
var
f: longint;
j: integer;
begin
f:=1;
for j:=1 to k do f:=f*j;
fact:=f;
end;
begin
write(‘Введите n’);
readln(n);
S:=0;
for i:=1 to n do s:=(s+1)/(fact(i)+fact(i+1)+fact(i+2));
writeln(‘S = ’,s:6:4);
end.
5.3 Области действия имен
1) Имена переменных, описанных в основной программе, называются глобальными и доступны в
основной программе и во всех подпрограммах.
2) Имена переменных, описанных в подпрограмме, называются локальными и доступны в этой
подпрограмме и во всех вложенных в нее подпрограммах (это же относится и к именам
формальных параметров!)
3) Имена локальных переменных перекрывают имена глобальных, то есть если имена переменных
в основной программе и подпрограмме совпадают, то в подпрограмме недоступна переменная,
описанная в основной программе.
А – основная порграмма, все переменные доступны везде
A
B, E – подпрограммы, вложенные в А
C, D – подпрограммы, вложенные в В
C
D
E
5.4 Параметры процедур и функций
33
Формальные параметры – это параметры, используемые при описании процедур и функций
Фактические параметры – это параметры, используемые при вызове процедур и функций.
При вызове подпрограммы формальные параметры заменяются на соответствующие фактические
параметры основной программы (!).
Пример:
var
c: integer;
procedure p(b: integer);
begin
…
end;
begin
p(c);
end.
b – формальный параметр
с – фактический параметр
По способу описания и передачи значения формальные параметры делятся на параметры-значения и
параметры-переменные.
 Параметры-значения (имя: тип)
Изменение значения таких параметров в подпрограмме не приводит к изменениям
соответствующих фактических параметров основной программы. В подпрограмму передается
копия фактического параметра (его значение). Поэтому фактические параметры,
соответствующие параметрам-значениям, могут быть константами, переменными или
выражениями. Другими словами, параметр-значение считается обычной локальной переменной.
При вызове подпрограммы начальное значение параметра автоматически устанавливается
равным значению соответствующего фактического параметра, заданного при вызове. Внутри
подпрограммы возможны любые действия с формальными параметрами, но эти изменения никак
не отражаются на значениях переменных основной программы.
Пример1:
var
a: integer;
Основная пограмма
procedure proc(x: integer);
begin
a 10
x:=x+2;
Proc
end;
begin
x 12
a:=10;
proc(a); writeln(a);
10
proc(a*a); writeln(a);
10
proc(25); writeln(a);
10
end.
 Параметры-переменные ( (var имя: тип); )
Изменение формальных параметров в подпрограмме приводит к аналогичному изменению
фактических параметров, используемых при вызове подпрограммы. Эти параметры
используются для возврата значений из процедур (в функциях обычно не используются, т.к.
функция возвращает значение через свое имя).
В подпрограмму передается адрес фактического параметра, а не его копия. (Формальный
параметр считается синонимом соответствующего фактического параметра). Поэтому
фактический параметр, соответствующий параметру-переменной, должен быть переменной того
же типа, что и формальный параметр (константы или выражения не допускаются).
Пример 1:
var
a,b: integer;
procedure proc(x: integer; var y: integer);
begin
y:=x+y;
end;
begin
a:=10; b:=10;
proc(a,b);
writeln(‘a = ’,a,’ b= ‘,b);
a = 10 b = 20
end.
Основная пограмма
a 10
b 20
Proc
x
10
y
~
b
Пример2: Программа вычисления объема шара V=4/3πR3
С использованием функции:
С использованием процедуры:
var
r,v: real;
begin
function vol (r:real): real;
vol:=4/3*pi*r*r*r;
34
end;
begin
write(‘Введите радиус шара’);
readln(r);
v:=vol(r);
writeln(‘Объем шара = ’, v);
end.
Основная пограмма
5
r
v
vol
r
v:=vol(r)
5
begin
v:=4/3*pi*r*r*r;
end;
begin
write(‘Введите радиус шара’);
readln(r);
vol(r,v);
writeln(‘Объем шара = ’, v);
end.
Основная пограмма
5
r
v
vol
r
5
var
3
v ~ V v:=4/3πr
r,v: real;
procedure vol(r: real; var v:real);
5.5 Побочные эффекты при использовании подпрограмм
Побочные эффекты возникают, когда изменение переменных в подпрограмме приводит к их
нежелательным изменениям в основной программе
Пример: программа с побочным эффектом
var
s,p: integer;
procedure Sum(n: integer, var f: integer);
var i: integer;
begin
s:=0;
for i:=1 to n do s:=s+i;
f:=s;
end;
begin
s:=2;
sum(3,p);
writeln(s,p);
66
end.
Основная пограмма
s 2 6p 6
sum
n
3
f
~
p
Процедура изменяет значение глобальной переменной S (!). Надо добавить в нее описание локальной S:
procedure Sum(n: integer, var f: integer);
var i: integer;
s: integer;
begin
…
5.6 Передача массивов в подпрограммы
Типом формального параметра подпрограммы может быть стандартный или заранее определенный
тип, заданный в виде идентификатора (!). Поэтому описание процедуры следующего вида является
недопустимым:
procedure S(a: array [1..10] of real);
В связи с этим, если в качестве параметра необходимо использовать массив, то делается
предварительное описание типа массива:
type
mas=array [1..10] of real;
…
procedure s(a: mas);
begin
…
end;
var
b: mas;
c: array [1..10] of real;
begin
S(b);
35
S(c); - нельзя!
…
Массив может передаваться как параметр-значение, и как параметр-переменная. Если параметр
массив описан со словом var, то изменение массива в подпрограмме приводит к изменению
соответствующего массива в основной программе.
Пример:
type
mas=array [1..10] of integer;
var
c,d: mas;
i: integer;
procedure S(a: mas, var b: mas);
var
i: integer;
begin
for i:=1 to 10 do
begin
a[i]:=a[i]*5;
b[i]:=b[i]*5;
end;
end;
begin
for i:=1 to 10 do
begin
c[i]:=1;
d[i]:=1;
end;
s(c,d);
for i:=1 to 10 do write (c[i]:3);
111111…
writeln;
for i:=1 to 10 do write (d[i]:3);
555555…
end.
Следующие три пункта 5.7, 5.8 и 5.9 являются необязательными для изучения, хотя
рассмотренный в них материал достаточно широко используется в программировании.
5.7 Параметры-костанты
В Турбо-Паскаль 7.0 существует еще один вид параметров – параметры-константы.
(const имя: тип)
В этом случае в подпрограмму передается адрес фактического параметра, но он защищен от изменений.
Чаще всего используется для передачи в подпрограмму массивов, которые не должны изменяться. В
этом случае нельзя использовать параметр-переменную, а использование параметра-значения не
эффективно, т.к. на копию массива требуется много памяти и может быть переполнение стека.
type
mas=array [1..10] of real;
var
a: mas;
function Summa (const x:mas): integer;
var
s,i: integer;
begin
s:=0;
for i:=1 to 10 do s:=s+x[i];
summa:=s;
end;
begin
randomize;
for i:=1 to 10 do a[i]:=random(20);
writeln(‘сумма элементов массива: ’,summa(a));
end.
5.8 Массивы открытого типа
В Турбо-Паскаль 7.0 в качестве параметров-переменных можно использовать массивы открытого
типа, у которых не задаются размеры. В этом случае подпрограмма может обрабатывать массив любого
размера. Фактический размер массива может быть определен с помощью функции High. При описании
не указывается тип индекса массива. Индексация элементов открытого массива всегда от 0 до значения
функции High ( 0..high(x) , где x – имя массива).
function Summa (var x: array of real): real;
var
i: integer;
36
s: real;
begin
s:=0;
for i:=1 to high(x) do s:=s+x[i];
summa:=s;
end;
5.9 Рекурсия в подпрограммах
В теле подпрограммы доступны все объекты, описанные в основной программе, в том числе и имя
самой подпрограммы. Таким образом, внутри тела подпрограммы возможен вызов самой подпрограммы.
Процедуры и функции, использующие вызовы «самих себя», называются рекурсивными.
Многие математические алгоритмы имеют рекурсивную природу, поэтому рекурсия широко
используется в программировании. В качестве примера приведем известный алгоритм вычисления
факториала неотрицательного целого числа:
(0!=1)
1!=1
N!=1*2*3*…*(N-1)*N
алгоритм основан на соотношении N!=(N-1)!*N
Пример:
function fact(N: word): longint;
begin
if (n=0) or (n=1) then fact:=1
else fact:=n*fact(n-1);
end;
При каждом новом обращении к подпрограмме параметры, которые она использует, заносятся в
стек, причем параметры предыдущего обращения тоже сохраняются.
Рекурсивное оформление программы более компактно и эффективно, но не следует забывать об
опасности переполнения стека (!).
Схема вызовов при вычислении 5!:
fact(5);
1*2*3*4*5
fact(4);
1*2*3*4
fact(3);
1*2*3
fact(2);
1*2
fact(1);
1
Задачи для самоконтроля
5.1 Определите значение переменных a, b после выполнения следующих программ:
а)
var
a,b: integer;
procedure proc(x: integer; y: integer);
begin
y:= y+2; x:= x+2;
end;
begin
a:=15; b:=15;
proc(a,b);
writeln(‘a = ’,a,’ b= ‘,b);
end.
б)
var
a,b: integer;
procedure proc(x: integer; var y: integer);
begin
y:= y+2; x:= x+2;
end;
begin
a:=15; b:=15;
proc(a,b);
writeln(‘a = ’,a,’ b= ‘,b);
end.
в)
var
a,b: integer;
procedure proc(var x: integer; y: integer);
begin
y:= y+2; x:= x+2;
end;
begin
a:=15; b:=15;
proc(a,b);
writeln(‘a = ’,a,’ b= ‘,b);
end.
г)
var
a,b: integer;
procedure proc(x: integer; var y: integer);
begin
y:= y+2; x:= x+2;
end;
begin
a:=15; b:=15;
proc(a,b);
writeln(‘a = ’,a,’ b= ‘,b);
end.
~
~
37
6. Строковый тип данных
6.1 Описание строк
Строка – это последовательность символов произвольной длины (до 255 символов). Строку
можно рассматривать, как массив символов переменной длины. Максимальное количество символов в
строке указывается при ее описании в квадратных скобках:
var
str1: string[80];
str2: string;
Если в квадратных скобках не указан максимальный размер строки, то он считается равным 255.
Строка может быть описана как типизированная константа:
const str10: string[10]=’январь’;
В памяти для строки длины N отводится N+1 байт, пронумерованных от 0 до N. В нулевом байте
хранится текущее значение длины строки.
0 1 2 3 4 5 6
… 10
6
я
н
в
а
р
ь
Когда изменяется содержание строки, автоматически пересчитывается ее текущая длина и меняется
значение 0-го байта. Всегда можно определить текущую длину строки:
l:=ord(str10[0]);
writeln(l);
Допустимо обращение к отдельным символам строки:
var
s: string;
begin
s:=’стол’;
writeln(s);
стол
s[3]:=’у’;
writeln(s);
стул
end.
6.2 Операции со строками
Сцепление строк (конкатенация) «+»
Эта операция добавляет к первой строке вторую.
Пример 1:
var
st1, st2, st3: string[20];
begin
st1:=’Турбо’;
st2:=’Паскаль’;
st3:=st1+’ ’+st2;
writeln(st3);
Турбо Паскаль
end.
Пример 2:
var
st1, st2: string[7];
begin
st1:=’student’;
st2:=’123’;
st1:=st2+st1;
end.
student
123
123stud
Сравнение строк (>, <, >=, <=, =, <>)
Сравнение двух строк осуществляется следующим образом. Символы строк сравниваются попарно друг
с другом так, что первый символ первой строки сравнивается с первым символом второй строки, второй
символ первой строки - со вторым символом второй и т.д. Символы сравниваются путем сравнения их
кодов во внутреннем представлении. Если одна строка короче другой, недостающие символы
заменяются нулем. Отношение первой несовпадающей друг с другом пары символов и принимается за
отношение двух строк.
38
‘abc’=’abc’
‘ab’<’abc’
‘ABC’<’ab’
‘Abc’<’abc’
‘Abc’<’1ab’
6.3 Процедуры и функции для работы со строками
length (s: string): integer; - функция возвращает текущий размер строки (т.е. количество символов в
строке; пробел тоже считается символом).
var
n: integer;
str: string[15];
begin
str:=’Turbo Pascal’;
n:=length(str);
write(‘n=’,n);
n=12
end.
copy (s: string; n1, n2: integer): string; - функция копирует из сроки S n2 символов, начиная с символа
n1.
st1:=’abcdef’;
st2:=copy(st1,2,3);
bcd
delete (var s: string; n1, n2: integer); - процедура удаляет из строки S n2 символов, начиная с символа
n1.
st1:=’abcdef’;
delete(st1,1,3);
def
insert (s1: string; var s2: string; n1: integer); - процедура вставляет строку s1 в строку s2, начиная с
символа n1.
st1:=’abcdef’;
insert(‘++’,st1,4);
abc++def
pos (s1,s2: string): byte; - функция возвращает номер позиции первого вхождения строки s1 в строку s2.
Если строка s1 не входит в строку s2, то возвращает 0.
st:=’abcdef’;
n:=pos(‘d’,st);
n=4
k:=pos(‘dc’,st);
k=0
str (x[:M[:N]]; var s: string); - процедура преобразует число х в строку символов S; M,N –
необязательные форматы вывода числа, аналогичные write.
var
x: real;
n: integer;
st: string;
begin
x:=3.141592;
n:=5;
str(x,st);
st=’3.141592’;
str(n,st);
st=’5’;
str(x:4:2,st);
st=’3.14’;
end.
val (s: string; var x, cod: integer); - процедура преобразует строку s в целое или вещественное число х.
Если преобразование прошло успешно, то cod=0, иначе cod=номер символа, вызвавшего ошибку.
var
x: real;
n, cod: integer;
st: string;
begin
st:=’3.14’;
val(st,x,cod);
cod=0
val(st,n,cod);
cod=2
end.
upcase (c: char): char; - функция преобразует строчную латинскую букву в заглавную
1) var st: string;
begin
st:=’a bc’;
st[3]:= upcase(st[3]);
39
write(st);
end.
a Bc
2) repeat
…
write(‘Завершить? (Y/N)’);
readln(c);
until (upcase(c)=’Y’);
Пример 1: Удалить из строки все точки.
var
st: string;
n: integer;
begin
write(‘введите строку’);
readln(st);
repeat
n:=pos(‘.’,st);
delete(st,n,1);
until n=0;
writeln(st);
end.
Пример 2: Удалить из строки все цифры.
var
st: string;
n: integer;
c: char;
begin
write(‘введите строку’);
readln(st);
for c:=’0’ to ‘9’ do
repeat
n:=pos(c,st);
delete(st,n,1);
until n=0;
writeln(st);
end.
Пример 3: Поменять в строке порядок символов на обратный (abcd на dcba).
var
st: string;
n: integer;
c: char;
begin
write(‘введите строку’);
readln(st);
for i:=1 to length(st) div 2 do
begin
c:=st[i];
st[i]:=st[length(st)-i+1];
st[length(st)-i+1]:=c;
end;
writeln(st);
end.
Задачи для самоконтроля
6.1 Определите значение переменной n после выполнения следующей программы:
var
n: integer;
str: string[25];
begin
str:=Лев Толстой’;
n:=length(str);
write(‘n=’,n);
end.
40
6.2 Определите значение переменной st2 после выполнения следующих фрагментов программ:
а) st1:=’abc def’;
st2:=copy(st1,5,2);
б) st2:=’abcdef’;
delete(st2,3,2);
в) st2:=’abcd’;
insert(‘***’,st2,2);
7. Стандартные модули Турбо-Паскаля
Модуль представляет собой совокупность программных ресурсов, предназначенных для использования
другими программами. Стандартные модули включают в себя стандартные константы, переменные,
процедуры и функции Турбо-Паскаля. Стандартный модуль можно рассматривать как библиотеку
подпрограмм.
В составе Турбо-Паскаль 6.0 имеются 8 стандартных модулей:
 system
 dos
 crt
 printer
 overlay
 graph
 Турбо3
 graph3
 strings
модули Турбо-Паскаль 7.0. используются для совместимости с другими
 windows
языками и средой Windows
Для использования процедур или функций данного модуля необходимо подключить его с помощью
оператора
uses имя модуля1 [, имя модуля2, …];
Модуль system подключается автоматически.
7.1 Модули ТУРБО3 и GRAPH3
Обеспечивают совместимость с программами, разработанными ранее для ТР 3.0
7.2 Модуль OVERLAY
Предоставляет средства для разработки оверлейных программ (размер которых превышает объем
доступной оперативной памяти, и которые загружаются в память по частям)
7.3 Модуль DOS
Содержит средства доступа к операционной системе DOS (процедуры и функции для работы с дисками,
файлами, системной датой, временем).
7.4 Модуль SYSTEM
Содержит процедуры и функции стандартного Паскаля и некоторые другие основные процедуры и
функции.
inc (x[,n]) – увеличение значения переменной x на n единиц (инкремент).
dec (x[,n]) – уменьшение значения переменной x на n единиц (декремент).
Пример:
x:=x+1; inc(x);
x:=x+5;
inc(x,5);
y:=y-1; dec(y);
y:=y-6; dec(y,6);
high(x) – получение максимального значения величины х; если х – массив, то максимального значения
индекса.
Пример:
var
y: word;
…
writeln(high(y));
65535
low(x) – получение минимального значения величины х; если х – массив, то минимального значения
индекса.
Пример:
41
var
y: integer;
…
writeln(low(y));
-32768
exit – немедленный выход из подпрограммы.
halt – прекращение выполнения программы и передача управления операционной системе.
Пример:
writeln(‘Введите x>0’);
readln(x);
if x<=0 then halt;
7.5 Модуль PRINTER
Делает доступным вывод результатов работы программы на печатающее устройство, связывая
стандартную переменную LST с принтером.
Пример:
uses printer;
var
a: integer;
begin
a:=20;
writeln(lst,’a=’,a); {вывод на принтер a=20}
end.
7.6 Модуль CRT
Содержит процедуры и функции управления экраном в текстовом режиме, управления звуком и работы с
клавиатурой.
При работе в текстовом режиме весь экран разбивается на позиции (25 строк по 80 позиций в каждой).
Для каждой позиции можно задать цвет фона и цвет символа, символ можно сделать мерцающим.
Координаты 1 позиции (верхний левый угол) – (1,1), последней позиции (нижний правый угол) – (80,25).
На экране можно создать текстовое окно, которое задается
1 2 3
80
координатами верхнего левого и нижнего правого углов. При работе
1
внутри окна координаты отсчитываются от верхнего левого угла.
2
Процедуры и функции модуля CRT (управление звуком и
клавиатурой)
20,10
40,20
keypressed: boolean; - возвращает true, если была нажата любая
клавиша (кроме ^, shift, alt…) и false в противном случае. Не
останавливает программу в ожидании нажатия клавиши, поэтому можно repeat…until keypressed; (вместо
readln;)
25
readkey: char; - считывает символ нажатой клавиши (без отображения на экране). Приостанавливает
выполнение программы до нажатия любой клавиши, кроме служебных (ctrl, alt, shift…)
if keypressed then ch:=readkey:
Код обычных клавиш (цифры, алфавит) хранится в 1 байте, коды функциональных клавиш (F1…F12) – в
двух байтах: первый = 0, второй – код клавиши. Поэтому, чтобы считать код функциональной клавиши,
надо 2 раза вызвать функцию readkey: при первом вызове она считает 0, при втором – непосредственно
код клавиши.
Пример:
uses Crt;
var ch:char;
begin
writeln(‘Нажмите клавишу’);
ch:=readkey;
if ch<>#0 then writeln(‘Клавиша ’, ch)
else begin
ch:=readkey;
writeln(‘функциональная клавиша ’, ord(ch));
end;
end.
delay (t); - приостанавливает работу программы на время t (милисекунд).
sound (f); - включает звук заданной частоты (в Гц).
nosound; - выключает звук
Пример:
sound(440); delay(500); nosound;
Пример: Имитация музыкального инструмента.
42
uses crt;
const
m: array [1..8] of integer = (262,294,330,350,392,440,494,523);
var
i: integer;
ch: char;
begin
writeln(‘Играйте на клавишах 1-8; 0 - выход’);
while true do
begin
ch:=readkey;
case ch of
#49: i:=1;
#50: i:=2;
…
#56: i:=8;
#48: halt;
end;
sound(m[i]);
delay(1000);
nosound;
end;
end.
Константы модуля CRT (коды цветов и режимов)
Коды режимов:
Имя
BW40
CO40
BW80
CO80
Font8x8
Mono
Значение
0
1
2
3
256
7
Коды цветов:
Назначение
25x40 черно-белый
25x40 цветной
25x80 черно-белый
25x80 цветной
50x80цветной(EGA/VGA)
25x80 для ч/б адаптера
Имя
Black
Blue
Green
Cyan
Red
Magenta
Brown
LightGrey
DarkGrey
Lightblue
Lightgreen
Lightcyan
Lightred
Lightmagenta
Yellow
White
Blink
Значение
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
128
Процедуры и функции управления экраном
clrscr; - очистка активного окна и перевод курсора в верхний левый угол.
clreol; - очистка строки активного окна от текущей позиции курсора до конца строки.
Цвет
черный
синий
зеленый
голубой
красный
фиолетовый
коричневый
светло-серый
темно-серый
светло-синий
светло-зеленый
светло-голубой
розовый
светло-фиолетовый
желтый
белый
мерцание символа
insline; - вставляет новую пустую строку в позицию курсора, заполняет ее цветом фона.
delline; - удаляет строку, на которой стоит курсор. Остальные строки сдвигаются (↑ или ↓).
highvideo; - переход к более яркому цвету символов (0→8, 1→9,…, 7→15).
lowvideo; - переход к менее яркому цвету символов (8→0, 9→1,…, 15→7).
normvideo; - переход к стандартному цвету символов (7)
textmode (m); - установка текстового режима. По умолчанию - СО80.
textbackground (col); - установка цвета фона (col = 0-7).
textcolor (col); - установка цвета символов (col = 0-15).
window (x1,y1,x2,y2); - определяет текстовое окно на экране.
gotoxy (x,y); - переводит курсор в заданную позицию окна. (х,у) – координаты нового положения курсора.
whereX: byte; - возвращает координату х текущей позиции курсора.
whereY: byte; - возвращает координату у текущей позиции курсора.
43
Пример 1: Сформировать на экране текстовое окно другого цвета и напечатать в середине окна
приветствие.
uses crt;
begin
textmode(3);
textbackground(2);
clrscr;
textcolor(14);
window(20,10,60,15);
textbackground(6);
clrscr;
gotoxy(15,3);
writeln(‘Hello’);
delay(1000);
textmode(3);
end.
Пример 2: Программа выводит на экран последовательность цифр 0..9, стрелками ← → выбирает и
подсвечивает любую цифру.
25
13
0
1
2
3
4
5
6
7
8
9
uses crt;
var
x,y,i: integer;
ch: char;
procedure Put(x,y,i,col: integer);
begin
textbackground(col);
gotoxy(x+i*3,y);
write(‘ ’,i,’ ’);
gotoxy(x+i*3+1,y);
end;
begin
textmode(3);
clrscr;
y:=13; x:=25;
for i:=0 to 9 do put(x,y,i,1);
i:=0; put(x,y,i,2);
repeat
ch:=readkey;
put(x,y,i,1);
if ch = #75 then dec(i);
if ch = #77 then inc(i);
if i<0 then i:=9;
if i>9 then i:=0;
put(x,y,i,2);
until ch=#27; {esc}
textmode(3);
end.
Вариант без процедуры:
uses crt;
var
x,y,i: integer;
ch: char;
44
procedure Put(x,y,i,col: integer);
begin
gotoxy(x+i*3,y);
write(‘ ’,i,’ ’);
gotoxy(x+i*3+1,y);
end;
begin
textmode(3);
clrscr;
y:=13; x:=25;
textbackground(1);
for i:=0 to 9 do
begin
gotoxy(x+i*3,y);
write(‘ ’,i,’ ’);
end;
i:=0;
textbackground(2);
gotoxy(x+i*3,y);
write(‘ ’,i,’ ’);
gotoxy(x+i*3+1,y);
repeat
ch:=readkey;
if ch = #0 then
begin
ch:=readkey;
textbackground(1);
gotoxy(x+i*3,y);
write(‘ ’,i,’ ’);
if ch = #75 then dec(i);
if ch = #77 then inc(i);
if i<0 then i:=9;
if i>9 then i:=0;
textbackground(2);
gotoxy(x+i*3,y);
write(‘ ’,i,’ ’);
gotoxy(x+i*3+1,y);
end;
until ch=#27; {esc}
textmode(3);
end.
стирает подсветку
подсвечивает другую цифру
7.7 Модуль GRAPH
Cодержит процедуры и функции, обеспечивающие работу с экраном в графическом режиме (создание
изображений).
1) В графическом режиме весь экран разбивается на точки (пиксели – от англ. pixel). Каждую точку
можно закрасить в любой цвет, таким образом из различных комбинаций точек создается
изображение.
2) Каждая точка имеет координаты (х, у), х увеличивается по горизонтали слева направо, у – по
вертикали сверху вниз. Верхний левый угол имеет координаты (0, 0), количество пикселей
зависит от типа видеоадаптера и режима его работы. Для адаптера VGA – 640х480 (стандартный
режим). Чем больше пикселей (точек), тем выше качество изображения.
{Драйвер устройства – программа управления устройством.
Видеоадаптер – системное устройство, непосредственно управляющее монитором и выводом
информации на экран. Основные части – видеоконтроллер, видеоBIOS, видеопамять и т.д.}
3) В графическом режиме можно выделить на экране графическое окно, тогда
координаты
отсчитываются внутри окна, верхний левый угол считается точкой (0,0).
4) В графическом режиме, в отличие от текстового, курсор невидим на экране, но также можно
переместить его в любую точку экрана, получить его текущие координаты.
Процедуры и функции управления графическими режимами.
initgraph (gd, gm, path); - процедура инициализации графического режима.
gd – код драйвер графического адаптера:
45
для CGA gd=1 или CGA
для EGA gd=3 или EGA
для VGA gd=9 или VGA
для автоматического определения драйвера gd=0 или Detect;
gm – код графического режима, устанавливается процедурой.
gd, gm – переменные целого типа!
path – строка, содержащая путь к драйверу: ‘c:\tp6\bgi’, т.е. вам надо сначала найти файл GRAPH.TPU и
здесь указать путь до этого файла.
closegraph; - процедура завершения графического режима и перехода в текстовый режим.
graphresult: integer; - возвращает код ошибки последней графической операции (0 – успешное
выполнение).
grapherrormsg (cool: intrger):string; - возвращает сообщение об ошибке для заданного кода ошибки.
restorecrtmode; - процедура восстановления текстового режима.
setgraphmode (gm); - процедура установления графического режима.
Пример 1.
uses crt, graph;
var
gd, gm: integer;
begin
gd:=detect;
initgraph (gd, gm, ‘c:\tp6\bgi’); {укажите правильный путь до bgi}
if graphresult <> 0 then
begin
write (‘ошибка графики:’, grapherrormsg (graphresult));
halt;
end;
…
closegraph;
end.
Процедуры управления экраном и окном.
cleardevice; - процедура очистки графического экрана, заполнения его цветом фона, установления
курсора в (0,0).
setviewport (x1, y1, x2, y2: integer; clip: boolean); - процедура установки графического окна.
x1, y1 – верхний левый угол,
x2, y2 – нижний правый угол,
clip – ограничитель фигур. Если clip=true, то построение фигур происходит только в пределах окна, в
противном случае фигуры могут выходить за пределы окна.
clearviewport; - процедура очистки графического окна (заполняет цаетом фона, курсор в (0,0)).
Процедуры и функции работы с точками.
GetmaxX: integer; - возвращает максимальное значение координаты x экрана.
GetmaxY: integer; - возвращает максимальное значение координаты y экрана.
GetX: integer; - возвращает координату x текущей позиции на экране.
GetY: integer; - возвращает координату y текущей позиции на экране.
GetPixel (x,y): word; - возвращает цвет точки с заданными координатами.
PutPixel (x,y,color); - процедура закрашивает точки с координатами (x,y) в цвет color.
Процедуры работы с линиями
line (x1, y1, x2, y2); - проводит прямую между точками (x1,y1) и (x2,y2).
moveto (x,y); - перемещает курсор в точку (х,у).
lineto (x,y); - проводит прямую из текущей точки в точку с координатами (x,y).
linerel (dx,dy); - проводят прямую из текущей точки в точку, сдвинутую на dx и dy: (x+dx, y+dy).
moverel (dx,dy); - перемещает курсор в точку, сдвинутую на dx, dy.
Процедуры построения фигур из линий.
bar (x1, y1, x2, y2); - построение закрашенного прямоугольника
(x1,y1)
(x2,y2)
bar3d (x1, y1, x2, y2, gr, top); - построение закрашенного параллелепипеда, gr – ширина боковой грани
(отсчитывается по горизонтали), top = true – рисовать верхнюю грань
gr
(x1, y1)
46
(x2, y2)
rectangle (x1, y1, x2, y2); - построение контура прямоугольника
arc (x, y, st, end, r); - построение дуги окружности, (х,у) – координаты центра, st – угол начала, end – угол
конца дуги, r – радиус. Отсчет идет против часовой стрелки от горизонтальной оси справа от центра.
circle (x, y, r); - построение окружности, (х,у) – центр, r – радиус.
ellipse (x, y, st, end, xr, yr); - построение дуги эллипса, (x,y) – центр, st, end – углы начала и конца, xr, yr
– радиусы по оси х и у.
fillellipse (x, y, xr, yr); - построение закрашенного эллипса.
pieslice (x, y, st, end, r); - построение закрашенного сектора круга.
sector (x, y, st, end, xr, yr); - построение закрашенного сектора эллипса.
Пример:
x1:=10; y1:=10; x2:=100; y2:=50; dx:=40; dy:=20;
for i:=1 to 10 do
begin
bar(x1, y1, x2, y2);
x1:=x1+dx; x2:=x2+dx;
y1:=y1+dy; y2:=y2+dy;
end;
Процедуры установки цветов и стилей.
setcolor (color); - устанавливает текущий цвет рисования (для линий и текста).
setbkcolor (color); - устанавливает цвет фона экрана.
setlinestyle (sl, p,t); - установка стиля и толщины линии (sl – стиль, p – шаблон при sl=4, t – толщина
линии).
sl = 0 – сплошная
t = 1 – нормальная
sl = 1 – пунктирная
t = 3 – толстая
sl = 2 – штрихпунктирная
sl = 3 – штриховая
sl = 4 – задается пользователем (р – шаблон из 11100110101…) p: word;
setfillstyle (sl, color); - установка стиля и цвета заполнения фигур.
sl = 0 – цвет фона (нет заполнения)
sl = 7 – клетка
sl = 1 – заполнение цветом
sl = 8 – косая клетка
sl = 2 – заполнение пунктиром
sl = 9 – частая сетка
sl = 3 –
sl = 10 – редкие точки
sl = 4 –
толстые
sl = 11 – частые точки
sl = 5 –
толстые
sl = 12 – задается пользователем
sl = 6 –
floodfill (x, y, colline); - закрашивает замкнутую область, ограниченную непрерывной линией. (х,у) –
координаты любой точки внутри области, colline – цвет линии, до которой закрашивается.
Пример: Построить спираль с начальной точкой (хс,ус), n витками и начальным углом α.
uses
crt, graph;
const
n=10; alf=pi; dt=pi/45;
var
gd, gm, x, y, xc, yc, i, j: integer;
procedure Spi(xc,yc,n: integer; dt,alf: real);
begin
moveto(xc,yc);
t:=alf;
for i:=1 to n do
for j:=1 to 90 do
begin
t:=t+dt; r:=2*t;
x:=round(r*cos(t)+xc);
x=r*cos(t)
окружность, t-угол.
y:=round(r*sin(t)+yc);
y=r*sin(t)
r увеличиваем, получаем
lineto(x,y);
спираль.
end;
end;
begin
gd:=detect;
initgraph (gd, gm, ‘L:\tp6\bgi’);
if graphresult <> 0 then
begin
47
write (‘ошибка графики:’, grapherrormsg (graphresult));
halt;
end;
xc:=getmxx div 2;
yc:=getmaxy div 2;
spi(xc,yc,n,dt,alf);
readln;
closegraph;
end.
Процедуры работы с текстом.
outtext (text: string); - выводит на экран текстовую строку, начиная с текущей позиции.
outtext(‘hello’);
outtextxy (x, y, text); - выводит на экран текстовую строку, начиная с заданных координат (х,у).
outtextxy(100,100,‘hello’);
settextstyle (font, dir, size); - устанавливает стиль текста
font – шрифт
dir – направление
size – размер символов
0 – стандартный
0 – слева направо
(0-30)
1 – утроенный 1 – сверху вниз
2 – маленький
3 – прямой
4 – готический
settextjustify (horiz, vert); - устанавливает выравнивание текста на экране (horiz-горизонтальное, vertвертикальное).
0 – слева (снизу)
1 – по центру
2 – справа (сверху)
Процедуры обмена с памятью
getimage (x1, y1, x2, y2, M); - копирует в массив М прямоугольную область экрана, заданную
координатами (х1,у1) и (х2,у2).
putimage (x, y, M, bit); - выводит изображение из массива М на экран. (х,у) – координаты точки, в
которой будет левый верхний угол изображения, М – массив, в котором было сохранено изображение, bit
– операция объединения выводимого изображения с имеющимся на экране.
0 – mov
экран
+ массив
→
- старое изображение исчезает
1 – xor
+
→
- стираются точки пересечения
2 – or
+
→
- оба изображения
3 – and
+
→
- остаются точки пересечения
Пример1: Программа перемещения по экрану графического объекта
uses
crt, graph;
var
gd, gm, x, y: integer;
m: array [1..1500] of byte;
begin
gd:=detect;
initgraph (gd, gm, ‘c:\tp6\bgi’);
if graphresult <> 0 then
begin
write (‘ошибка графики:’, grapherrormsg (graphresult));
halt;
end;
circle(20,20,20);
getimage(0,0,40,40,m);
x:=0; y:=0;
readln;
while x<600 do
begin
putimage(x,y,m,1);
x:=x+2; y:=y+1;
putimage(x,y,m,1);
delay(100);
end;
closegraph;
48
end.
8. Записи
8.1 Определение записи
Относится к структурированным типам данных (как и массив, файл, множество). Запись состоит
из фиксированного числа компонентов, называемых полями записи. В отличие от массива, поля записи
могут быть различных типов.
Описание записи обычно осуществляют с использованием оператора TYPE, т.е. сначала
определяют тип-запись, а затем в разделе var описывают конкретную запись. Тип-запись описывается
следующим образом:
type <имя типа> = record
<поле1>: тип;
<поле2>: тип;
…
<полеN>: тип;
end;
Пример1:
type date = record
day: 1..31;
month: 1..12;
year: integer;
end;
type person = record
name: string[20];
age: integer;
adres: string[50];
end;
day
month
year
var
birthday: date;
10
5
1980
student: person;
name
age
adres
Доступ к полям записи осуществляется указанием имени записи и имени поля через точку:
birthday.day:=10;
birthday.month:=5;
birthday.year:=1980;
Пример 2:
type detal = record
name: string[20];
kod: integer;
weight: real;
end;
var
d: detal;
Begin
…
d.name:=’гайка’;
d.kod:=155;
d.weight:=0.057;
…
write(‘Деталь: ’,d.name,’ Код: ’, d.kod,’ Вес: ‘,d.weight);
End.
8.2 Оператор над записями
Для того, чтобы не писать каждый раз имя записи при обращении к ее полям можно использовать
оператор над записями WITH.
Структура оператора:
with <имя записи> do <оператор>;
обычно требуется begin…end;
В этом случае можно указывать только поле записи:
49
with birthday do
begin
day:=10;
month:=5;
year:=1980;
end;
8.3 Вложенные записи
Поля записи могут быть любого типа, в том числе поле записи может быть тоже записью. В этом
случае образуются вложенные записи.
Пример:
type data = record
day: byte;
month: byte;
year: word;
end;
type stud = record
name: string[15];
fam: string[30];
pol: char;
adres: string[80];
birthday: data;
name
stud
fam
pol
adres
day
var
stud: person;
begin
stud.name:=’Денис’;
stud.fam:=’Иванов’;
stud.pol:=’м’;
stud.adres:=’
’;
stud.birthday.day:=21;
stud.birthday.month:=3;
stud.birthday.year:=1980;
end.
end;
birthday
month
year
begin
with stud do begin
name:=’Денис’;
fam:=’Иванов’;
pol:=’м’;
with birthday do begin
day:=21;
month:=3;
year:=1980;
end;
end;
end.
8.4 Массив записей
На практике часто используются не отдельные записи, а массивы записей. Рассмотрим
использование массива записей на примере.
x
y
color
p[1]
p[2]
p[3]
p[4]
...
...
p[5000]
Пример 1: Программа, заполняющая экран точками различного цвета и стирающая их.
uses
crt, graph;
type
point = record
x,y: integer;
color: byte;
end;
var
gd,gm,i: integer;
p: array [1..5000] of point;
50
begin
gd:=detect;
initgraph (gd, gm, ‘c:\tp6\bgi’);
if graphresult <> 0 then
begin
write (‘ошибка графики:’, grapherrormsg (graphresult));
halt;
end;
randomize;
for i:=1 to 5000 do
with p[i] do begin
x:=random(640);
y:= random(350);
color:= random(15)+1;
putpixel (x,y,color);
delay(50);
end;
for i:=1 to 5000 do
begin
putpixel(p[i].x, p[i].y,0);
delay(50);
end;
end.
Пример 2: Программа создания библиотечного каталога и вывод на экран списка всех книг, изданных в
указанном году.
uses
crt;
type
book = record
name: string;
autor: string;
year: string;
str: string;
end;
var
i, n, god: integer;
ch: char;
b: array [1..1000] of book;
begin
i:=0;
repeat
inc(i);
with b[i] do begin
write(‘название:’); readln(name);
write(‘автор:’); readln(autor);
write(‘год:’); readln(year);
write(‘количество страниц:’); readln(str);
end;
write(‘Еще вводить? Y/N’); readln(ch);
writeln; n:=i;
until (upcase(ch)=’N’);
repeat {поиск в каталоге}
write(‘Введите год’); readln(god);
for i:=1 to n do
if b[i].year=god then writeln(b[i].name, b[i].autor, b[i].year, b[i].str);
writeln(‘Продолжить поиск? Y/N’); readln(ch);
until (upcase(ch)=’N’);
end.
8.5 Записи с вариантами
Кроме фиксированного списка полей, запись может содержать вариантную часть, определяющую
несколько вариантов структуры записи. Различие может касаться количества полей и их типов.
Вариантная часть содержит несколько альтернатив, для каждой из которых в скобках
указывается список полей, присущих данному варианту.
Например, в библиотечном каталоге хранятся не только книги, но и журналы. Кроме названия, для
книг хранится автор, год издания и количество страниц, а для журналов – номер и год выпуска.
b.name:=’Введение в Паскаль’;
51
b.autor:=’Абрамов В.И.’;
b.year:=1980;
b.str:=253;
или
b.name:=’Мир ПК’;
b.nomer:=2;
b.god:=1998;
Вариантная часть может быть только одна и должна располагаться в конце записи. Она
начинается со слова CASE, за которым следует переменная выбора варианта с указанием типа. Затем
перечисляются варианты записи с указанием их полей.
В стандарте Паскаля перед тем, как использовать один из вариантов записи, переменной выбора
варианта необходимо присвоить соответствующее значение. В Турбо-Паскале это делать
необязательно (!).
case <переменная выбора>: тип of
вариант1:
(поле1: тип;
поле2: тип;
…
полеN: тип);
вариант2:
(поле1: тип;
поле2: тип;
…
полеK: тип);
Пример:
type
izdanie = (book, magazine);
zap = record
name: string;
case tip: izdanie of
book:
(autor: string;
year: integer;
str: integer);
magazine: (nomer: byte;
god: integer);
end;
b: zap;
var
begin
if tip = book then writeln (b.name, b.autor, b.year, b.str)
else writeln (b.name, b.nomer, b.god);
end.
name
autor
year
nomer
god
str
В запись с вариантами можно не вводить переменную выбора, перечислить только разные
варианты.
type
dostup = record
case integer of
word
1: (one_word: word);
2: (byte1: byte;
byte2: byte);
byte1
byte2
end;
9. Файлы
9.1 Определение файла
В Паскале файл относится к структурированным типам данных, как массив и запись. Файл
представляет собой последовательность компонентов одного типа, расположенных на внешнем
устройстве (например, магнитный диск). Тип компонентов файла может быть любым, кроме файлового.
52
Количество компонентов в файле не оговаривается и ограничивается только объемом памяти на
внешнем устройстве.
В Турбо-Паскале выделяют 3 типа файлов:
1. Текстовые файлы – используются для хранения текстовой информации в виде символов,
объединенных в строки.
Описание: var <файловая переменная>: text;
Например, var f1: text;
2. Типизированные файлы – используются для хранения данных определенного типа.
Описание: var <файловая переменная>: file of <тип>;
Например, var f1: integer;
var f2: real;
var f3: ‘A’..’z’;
3. Нетипизированные файлы – используются для организации доступа к любым данным,
независимо от их структуры (тип компонентов не указывается).
Описание: var <файловая переменная>: file;
Например, var f: file;
9.2 Процедуры и функции для работы с файлами
assign (<файловая переменная>, <имя.расширение>); - устанавливает связь между файловой
переменной и именем файла на диске. Имя файла состоит из двух частей: имя (не более 8 символов) и
расширение (не более 3 символов). Расширение может отсутствовать.
Например, assign(f1,’res.txt’);
Далее в программе, где будет упоминаться переменная f1 - подразумевается, что работа
ведется с реальным файлом res.txt .
reset (<файловая переменная >); - открывает существующий файл для чтения.
Например, reset(f1);
rewrite (<файловая переменная >); - открывает файл для записи. Если файла нет на диске, то он
создается. Если есть такой файл, то он создается заново пустым, вся старая информация стирается.
Например, rewrite(f1);
append (<файловая переменная >); - открывает файл для добавления в него новой информации
(старая не стирается). Только для текстовых файлов (!).
Например, append(f1);
read (<файловая переменная >, <переменная>); - чтение одного элемента из файла,
соответствующего файловой переменной, и помещение его в переменную программы. Чтение
осуществляется последовательно, после чтения каждого значения, указатель в файле перемещается на
следующую позицию.
Пример:
Пусть на диске есть символьный файл mebel. Задача: написать программу, которая
последовательно считывает из этого файла первые 4 символа и выводит их на экран.
Изобразим файл следующим образом:
1-ый байт памяти
2-ой байт памяти
…
с
т
о
Mebel
Программа:
var
л
…
F1: file of char;
x: char; i:integer;
Begin
assign(F1,’mebel’);
reset(F1);
for i:=1 to 4 do
begin
read(F1,x);
write(x);
end;
close(F1);
End.
На экране увидим:
стол
Для текстового файла может использоваться процедура readln, которая читает значение из
файла и пропускает непрочитанную часть строки и признак конца строки.
write (<файловая переменная >, <переменная>); - запись в файл данных из переменных программы.
Вывод информации осуществляется последовательно.
53
var
f1: file of char;
y: array [1..100] of integer;
…
for i:=1 to 100 do write(f1,y[i]);
2б
2б
y[1]
y[2]
f1
eof (var f): boolean; - функция проверки конца файла. Возвращает true, если достигнут конец файла,
иначе возвращает false.
while not eof(f) do read(f,x);
{команда читается так: пока не конец файла делай команду: чтение очередного элемента из файла,
соответствующего файловой переменной f, в переменную x}
close (<файловая переменная >); - процедура закрытия файла, завершает действия с файлом. После
процедуры close файловую переменную можно связать с другим файлом или снова открыть этот же
файл.
assign(f2,’MyFile.txt’);
rewrite (f2);
…
close(f2);
reset(f2);
…
close(f2);
assign(f2,’OtherFile.txt’);
reset(f2);
…
Пример 1: Программа, переписывающая из файла a.txt в файл b.txt все символы, кроме цифр.
var
ch: char:
f1,f2: text:
begin
assign(f1, ‘a.txt’);
assign(f2, ‘b.txt’);
reset(f1);
rewrite(f2);
repeat
read(f1,ch);
if (ch<=’0’) or (ch>=’9’) then write(f2,ch);
until eof(f1);
close(f1); close(f2);
end.
Пример 2: Программа для вычисления и вывода в файл таблицы Пифагора (таблицы умножения).
Var
i, j, n : Integer;
f : Text;
Begin
Assign(f, ‘tab_pif.txt’);
Rewrite(f);
For i := 1 to 9 do begin
For j := 1 to 9 do begin
n := i*j;
Write(n:4); {вывод результата на экран}
Write(f, n:4); {вывод результата в файл; т.е., если в процедуре Write первым параметром
указана файловая переменная, то вывод осуществляется не на экран, а в файл,
с которым связана эта переменная в процедуре Assign }
end;
WriteLn;
{перевод строки на экране}
WriteLn(f);
{перевод строки в файле}
end;
Close(f);
End.
54
rename(<файловая переменная>,<новое имя файла>); - переименование файла на диске. Перед
использованием этой поцедуры необходимо связать файловую переменную со старым именем файла.
Если файл был открыт, то необходимо его закрыть.
Пример:
var
f1,f2: text;
i: integer;
begin
assign(f1, ‘res.txt’);
rename(f1, ‘res.old’);
assign(f2, ‘res.old’);
rewrite(f2);
for i:=1 to 20 do writeln(f2,i);
close(f2);
end.
erase (<файловая переменная>); - удаление файла с диска. Если файл был открыт, то закрыть,
связать с файловой переменной.
assign(f,’res.old’);
erase(f);
seek (<файловая переменная>, N); - перемещение в заданную позицию файла, нумерация позиций с
нуля, N – номер позиции. Не используется для текстовых файлов (!).
0
1
2
3
4
5
2
5
3
8
8
6
a.dat
Пример:
var
f: file of integer;
i: integer;
begin
assign(f,’a.dat’);
reset(f);
N=0
read(f,i);
i=2
seek(f,4);
N=4
read(f,i);
i=8
end.
filesize(<файловая переменная>): longint; - функция, возвращает текущий размер файла (количество
компонентов!).
Пример 3: Программа, меняющая порядок символов в файле на обратный.
var
f1.f2: file of char;
i,n: integer;
ch: char;
begin
assign(f1,’a.txt’);
assign(f2,’b.txt’);
reset(f1);
rewrite(f2);
h:=filesize(f1);
for i:=h-1 downto 0 do
begin
seek(f1,i);
read(f1,ch);
write(f2,ch);
end;
close(f1);
close(f2);
end.
9.3 Нетипизированные файлы
При описании нетипизированных файлов не указывается тип компонентов файла, что позволяет
обеспечить доступ к данным любого типа. Использование нетипизированных файлов дает возможность
организовать высокоскоростной обмен данных (т.е. чтение и запись на диск).
В процедурах открытия таких файлов указывается размер записи (в байтах), считываемой или
записываемой на диск.
reset(f, size);
rewrite(f, size);
55
Для обеспечения максимальной скорости обмена длина блока должна быть кратна размеру сектора
магнитного диска (512 байт). Но размер файла может быть не кратен размеру записи, поэтому для
полного чтения всего файла размер записи устанавливается равным 1 байту.
Для чтения и записи в Нетипизированные файлы используются процедуры чтения и записи блоками:
blockread (f, buf, n, res); - чтение из файла f в переменную buf (обычно массив), n – число записей,
запрашиваемых на чтение, res – число реально считанных записей.
blockwrite (f, buf, n, res); - запись из переменной buf в файл f.
Пример:
var
f1,f2: file;
r1,r2: integer;
a: array [1..4096] of byte;
st1, st2: string;
begin
write(‘Введите имя исходного файла’); readln(st1);
write(‘Введите имя нового файла’); readln(st2);
assign(f1,st1); assign(f2,st2);
reset (f1,1); rewrite(f2,1);
repeat
blockread(f1,a,4096,r1);
blockwrite(f2,a,r1,r2);
until r1<4096;
close(f1); close(f2);
end.
10. Интегрированная среда Турбо Паскаля
Система программирования Турбо Паскаль представляет собой интегрированную среду разработки,
включающую в себя:
1) экранный редактор
2) компилятор
3) редактор связей
4) отладчик
5) справочную подсистему
10.1 Как начать работу с Турбо Паскалем
Система Турбо Паскаль довольно значительна по объему. Она поставляется на нескольких
дистрибутивных дискетах и устанавливается на жесткий диск. При развертывании системы на жестком
диске обычно создается каталог с именем ТР (или PAS, TURBOPAS, PASCAL и т.п.), в который
помещаются все файлы с дистрибутивных дискет. Для вызова Турбо Паскаля необходимо отыскать в
древовидной структуре каталогов ПК этот каталог и в нем файл TURBO.EXE. Этот файл содержит
готовую к работе диалоговую систему программирования Турбо Паскаль. В него входят минимально
необходимые части Турбо Паскаля (текстовый редактор, компилятор, компоновщик, загрузчик). Для
нормальной работы в диалоговой среде понадобятся также основная библиотека, располагающаяся в
файле TURBO. TPL, и справочная служба (файл TURBO.HLP). В принципе, этих файлов достаточно для
написания, компиляции и исполнения большинства примеров, содержащихся в этой книге.
Пусть перечисленные файлы располагаются в каталоге ТР на диске D. Тогда для вызова Турбо Паскаля
следует дать команду:
D:\TP\TURBO
По этой команде операционная система MS-DOS поставит на исполнение программу из файла
TURBO.EXE: загрузит программу в оперативную память и передаст ей управление.
Не рекомендуется работать с системой, назначив в качестве каталога по умолчанию (текущего каталога)
тот, в котором хранятся перечисленные выше файлы (этот каталог будем называть системным). Вопервых, в таком случае можно ошибочно стереть какой-либо из файлов системы программирования и
тем самым нарушить ее работоспособность, а во-вторых, этот каталог очень скоро заполнится другими
файлами, прямо не относящимися к Турбо Паскалю.
После успешного вызова системы экран ПК приобретает вид, показанный на рис. 1 (верхняя строка со
словом Авто может отсутствовать)
56
Рис. 1 Вид экрана после вызова Турбо Паскаля
Сразу же скажем, что для выхода из Турбо Паскаля следует нажать клавишу Alt и, не отпуская ее, клавишу с латинской буквой X, после чего можно отпустить обе клавиши.
!!!Совет: чтобы лучше ознакомиться с работой в среде Турбо Паскаля, рекомендую запустить
систему, выбрать из лекций какой-нибудь пример программы, и далее не просто читать текст, а
сразу пытаться применить на практикке.
Верхняя строка содержит «меню» возможных режимов работы Турбо Паскаля, нижняя - краткую справку
о назначении основных функциональных клавиш. Вся остальная часть экрана принадлежит окну
редактора, очерченному двойной рамкой и предназначенному для ввода и коррекции текстов программ.
В его верхней строке приводятся имя того дискового файла, откуда был прочитан текст программы
(новому файлу присваивается имя NONAME00.PAS), два специальных поля, используемых при работе с
устройством «мышь» (эти поля выделены квадратными скобками), и цифра 2 - номер окна. В Турбо
Паскале можно работать одновременно с несколькими программами (или частями одной крупной
программы), каждая из которых может располагаться в отдельном окне редактора. Среда позволяет
использовать до 9-ти окон редактора одновременно (см. п. 10.2)
Кроме окна (окон) редактора в Турбо Паскале используются также окна отладочного режима, вывода
результатов работы программы, справочной службы, стека, регистров. По желанию они могут
вызываться на экран поочередно или присутствовать на нем одновременно.
Функциональные клавиши
Функциональные клавиши используются для управления средой Турбо Паскаля. Они обозначаются F1,
F2, ..., F12 и располагаются в самом верхнем ряду клавиатуры. С каждой из этих клавиш связывается
некоторая команда меню. Действие почти всех функциональных клавиш можно модифицировать тремя
особыми клавишами: Alt (от ALTernative - дополнительный), Ctrl (ConTRoL -управляющий) и Shift (SHIFTсдвиговый). Эти клавиши используются подобно клавиши временной смены регистра на пишущей
машинке: нужно нажать на одну из них и затем, не отпуская ее, нажать функциональную клавишу. В
дальнейшем такое совместное нажатие двух клавиш будем обозначать чертой. Например, Alt-F3
означает, что вместе с клавишей Alt необходимо нажать клавишу F3, Ctrl-F9 - вместе с Ctrl нажимается
F9 и т.д.
Ниже приводятся команды, которые передаются среде Турбо Паскаля функциональными клавишами и
некоторыми их комбинациями с клавишами Ctrl и Alt:
Fl - обратиться за справкой к встроенной справочной службе (Help-помощь);
57
F2 - записать редактируемый текст в дисковый файл;
F3 - прочитать текст из дискового файла в окно редактора;
F4 - используется в отладочном режиме: начать (или продолжить) исполнение программы и
остановиться перед исполнением той ее строки, на которой стоит курсор;
F7 - используется в отладочном режиме: выполнить следующую строку программы; если в строке есть
обращение к процедуре (функции), войти в эту процедуру и остановиться перед исполнением первого ее
оператора;
F8- используется в отладочном режиме: выполнить следующую строку программы; если в строке есть
обращение к процедуре (функции), исполнить ее и не прослеживать ее работу;
F5 - распахнуть активное окно на весь экран;
F6 - сделать активным следующее окно;
F9 - компилировать программу, но не выполнять ее;
F10 - перейти к диалоговому выбору режима работы с помощью главного меню;
Ctrl-F9 - выполнить прогон программы: компилировать программу, находящуюся в редакторе, загрузить
ее в оперативную память и выполнить, после чего вернуться в среду Турбо Паскаля.
Alt-F5 - сменить окно редактора на окно вывода результатов работы (прогона) программы.
Подробнее об этих командах см. в методических указаниях к лабораторным работам, а сейчас самый
краткий комментарий.
Во-первых, Вам понадобятся команды Ctrl-F9 для проверки работы Вашей программы и Alt-X - для
выхода из Турбо Паскаля. Клавиши F2 и F3 помогут Вам в работе с Вашим каталогом. Командой Alt-F5
Вы в любой момент сможете просмотреть данные, выданные на экран в результате прогона программы.
Текстовый редактор
Текстовый редактор среды Турбо Паскаля предоставляет пользователю удобные средства создания и
редактирования текстов программ. Признаком того, что среда находится в состоянии редактирования,
является наличие в окне редактора курсора -небольшого мигающего прямоугольника. Режим
редактирования автоматически устанавливается сразу после загрузки Турбо Паскаля. Из режима
редактирования можно перейти к любому другому режиму работы Турбо Паскаля с помощью
функциональных клавиш или выбора нужного режима из главного меню. Если среда находится в
состоянии выбора из меню, курсор исчезает, а в строке меню появляется цветной указательпрямоугольник, выделяющий одно из кодовых слов (опций меню). Для перехода от состояния выбора
режима из главного меню в состояние редактирования нужно нажать клавишу Esc (ESCape ускользать, убегать), а для перехода к выбору из главного меню - F10.
Рассмотрим основные приемы работы с текстовым редактором.
Для создания текста программы нужно ввести этот текст с помощью клавиатуры ПК подобно тому, как
это делается при печатании текста на пишущей машинке. После заполнения очередной строки следует
нажать на клавишу Enter, чтобы перевести курсор на следующую строку (курсор всегда показывает то
место на экране, куда будет помещен очередной вводимый символ программы).
Окно редактора имитирует длинный и достаточно широкий лист бумаги, фрагмент которого виден в окне.
Если курсор достиг нижнего края, осуществляется прокрутка окна редактора: его содержимое смещается
вверх на одну строку и снизу появляется новая строка листа. Если курсор достиг правой границы экрана,
окно начинает по мере ввода символов смещаться вправо, показывая правый край листа. Размеры
листа по горизонтали и вертикали ограничиваются только общим числом символов в файле, которых не
должно быть больше 64535, однако компилятор Турбо Паскаля воспринимает строки программы длиной
не более 126 символов.
58
Окно можно смещать относительно листа с помощью следующих клавиш:
Page Up -на страницу вверх;
Page Down - на страницу вниз;
Ноте - в начало текущей строки;
End - в конец текущей строки;
Ctrl-Page Up -в начало текста;
Ctrl-Page Down - в конец текста.
Клавишами перевода курсора (эти клавши помечены стрелками и располагаются в правой части
клавиатуры) его можно смещать по экрану. При достижении границ окна оно смещается на строку Или
на символ.
Если Вы ошиблись при вводе очередного символа, его можно стереть с помощью клавиши со стрелкой
(или надписью Backspace), расположенной над клавишей Enter. Клавиша Delete стирает символ, на
который в данный момент указывает курсор, а команда Ctrl-Y- всю строку, на которой расположен
курсор.
Следует помнить, что редактор Турбо Паскаля вставляет в конце каждой строки невидимый символразделитель. Этот символ вставляется клавишей Enter, а стирается клавишами Backspace или Delete. С
помощью вставки/стирания разделителя можно «разрезать»/«склеить» строки. Чтобы разрезать строку,
следует подвести курсор к нужному месту и нажать Enter, чтобы склеить соседние строки, нужно
установить курсор в конец первой строки (для этого удобно использовать клавишу End) и нажать Delete
или установит курсор в начало второй строки (клавишей Ноте) и нажать Backspace.
Нормальный режим работы редактора - режим вставки, в котором каждый вновь вводимый символ как
бы «раздвигает» текст на экране, смещая вправо остаток строки. Следует учитывать, что разрезание
текста и последующая вставка пропущенных строк возможны только в этом режиме. Редактор может
также работать в режиме наложения новых символов на существующий старый текст: в этом режиме
новый символ заменяет собой тот символ, на который указывает курсор, а остаток строки не смещается
вправо. Для перехода к режиму наложения нужно нажать клавишу Insert, а если нажать эту клавишу еще
раз, вновь устанавливается режим вставки. Признаком того, в каком режиме работает редактор,
является форма курсора: в режиме вставки он похож на мигающий символ подчеркивания, а в режиме
наложения он представляет собой крупный мигающий прямоугольник, заслоняющий символ целиком.
И еще об одной возможности редактора. Обычно редактор работает в режиме автоотступа. В этом
режиме каждая новая строка начинается в той же позиции на экране, что и предыдущая. Режим
автоотступа поддерживает хороший стиль оформления текста программы: отступы от левого края
выделяют тело условного или составного оператора и делают программу более наглядной. Отказаться
от автоотступа можно командой Ctrl-O I (при нажатой Ctrl : нажимается сначала клавиша с латинской
буквой О, а затем О отпускается и нажимается I ), повторная команда Ctrl-O I восстановит режим
автоотступа.
Ниже перечислены наиболее часто используемые команды редактор Турбо Паскаля.
Смешение курсора
Page Up -на страницу вверх;
Page Down - на страницу вниз;
Ноте - в начало текущей строки;
End - в конец текущей строки;
Ctrl-Page Up - в начало текста;
59
Ctrl-Page Down - в конец текста.
Команды редактирования
Backspace - стирает символ слева от курсора;
Delete - стирает символ, на который показывает курсор;
Ctrl-Y- стирает строку с курсором;
Enter - вставляет новую строку, разрезает старую;
Ctrl-Q L - восстанавливает измененную строку (действует, если курсор не
покидал строку после ее изменения).
Работа с блоком
Ctrl-K В - начинает выделение блока;
Ctrl-K K- заканчивает выделение блока;
Ctrl-K Y - уничтожает выделенный блок;
Ctrl-K С - копирует блок;
Ctrl-K V - перемещает блок на новое место;
Ctrl-K W - записывает блок в файл;
Ctrl-K R - читает блок из файла;
Ctrl-K P - печатает блок.
Основные приемы работы в среде Турбо Паскаля
Работа с файлами
Как уже говорилось, сразу после запуска Турбо Паскаля среда переходит в режим редактирования
текста, в котором можно подготовить новую программу или исправить существующую.
Основной формой хранения текстов программ вне среды являются файлы. После завершения работы с
Турбо Паскалем можно сохранить текст новой программы в дисковом файле с тем, чтобы использовать
его в следующий раз. Для обмена данными между дисковыми файлами и редактором среды
предназначены клавиши F2 (запись в файл) и F3 (чтение из файла). Если Вы создаете новую программу,
то среда еще не знает имя того файла, в который Вы захотите поместить текст этой программы, и
поэтому она присваивает ей стандартное имя NONAME00.PAS (NO NAME - нет имени). Для сохранения
текста программы в файле нужно нажать F2. В этот момент среда проверит имя программы и, если это
стандартное имя NONAME, спросит, нужно ли его изменять: на экране появится небольшое окно запроса
с надписью
Save File as
(Сохранить в файле с именем...)
Ниже надписи располагается поле для ввода имени файла, в котором можно написать нужное имя (без
расширения) и нажать Enter - текст будет сохранен в файле. Если в имени опущено расширение, среда
присвоит файлу стандартное расширение PAS. Если Вы захотите завершить работу с Турбо Паскалем, а
в редакторе остался не сохраненный в файле текст, на экране появится окно с запросом
60
NONAMEOO.PAS has been modified.Save?
(Файл NONAME00.PAS был изменен. Сохранить?)
В ответ следует нажать Y(Yes - да), если необходимо сохранить текст в файле, или N(No - нет), если
сохранять текст не нужно.
Прогон и отладка программы
После подготовки текста программы можно попытаться исполнить ее, т.е. откомпилировать программу,
связать ее (если это необходимо) с библиотекой стандартных процедур и функций, загрузить в
оперативную память и передать ей управление. Вся эта последовательность действий называется
прогоном программы и реализуется командой Ctrl-F9.
Если в программе нет синтаксических ошибок, то все действия выполняются последовательно одно за
другим, при этом в небольшом окне сообщается о количестве откомпилированных строк и объеме
доступной оперативной памяти. Перед передачей управления загруженной программе среда очищает
экран (точнее, выводит на экран окно прогона программы), а после завершения работы программы
вновь берет управление компьютером на себя и восстанавливает на экране окно редактора.
Если на каком-либо этапе среда обнаружит ошибку, она прекращает дальнейшие действия,
восстанавливает окно редактора и помещает курсор на ту строку программы, при компиляции или
исполнении которой обнаружена ошибка. При этом в верхней строке редактора появляется
диагностическое сообщение о причине ошибки. Все это позволяет очень быстро отладить программу,
т.е. устранить в ней синтаксические ошибки и убедиться в правильности ее работы. Если ошибка
возникла на этапе прогона программы, простое указание того места, где она обнаружена, может не дать
нужной информации, так как ошибка может быть следствием неправильной подготовки данных в
предыдущих операторах программы. Например, если ошибка возникла в результате извлечения
квадратного корня из отрицательного числа, будет указан оператор, в котором осуществляется
извлечение корня, хотя ясно, что первопричину ошибки надо искать где-то раньше, там, где
соответствующей переменной присваивается отрицательное значение. В таких ситуациях обычно
прибегают к пошаговому исполнению программы с помощью команд, связанных с клавишами F4, F7 и
F8. Пока еще не накоплен достаточный опыт отладки, можно воспользоваться одной клавишей F7, после
нажатия на которую среда осуществит компиляцию, компоновку (связь с библиотекой стандартных
процедур и функций) и загрузку программы, а затем остановит прогон перед исполнением первого
оператора. Строка программы, содержащая этот оператор, будет выделена на экране указателем
(цветом). Теперь каждое новое нажатие F7 будет вызывать исполнение всех операций,
запрограммированных в текущей строке, и смещение указателя к следующей строке программы. В
подозрительном месте программы можно просмотреть текущее значение переменной или выражения.
Для этого нужно установить курсор в то место строки, где находится имя интересующей Вас
переменной, и нажать Ctrl-F4. На экране появится диалоговое окно, состоящее из трех полей (в верхнем
поле будет стоять имя переменной, два других поля будут пустыми). Нажмите Enter, чтобы в среднем
поле получить текущее значение переменной. Если перед нажатием Ctrl-F4 курсор стоял на пустом
участке строки или указывал на имя другой переменной, верхнее поле диалогового окна также будет
пустым или содержать имя этой другой переменной. В этом случае следует ввести с помощью
клавиатуры имя нужной переменной и нажать Enter. Кстати, таким образом можно вводить не только
имена прослеживаемых переменных, но и выражения - среда вычислит и покажет значение введенного
выражения.
Справочная служба Турбо Паскаля
Неотъемлемой составной частью среды Турбо Паскаля является встроенная справочная служба. Если
Вы достаточно хорошо владеете английским языком, у Вас не будет проблем при работе с Турбо
Паскалем: в затруднительной ситуации достаточно нажать F1 и на экране появится необходимая
справка. Эта справка зависит от текущего состояния среды, поэтому справочную службу называют
контекстно-чувствительной. Например, если нажать F1 в момент, когда среда обнаружила ошибку в
программе, в справке будут сообщены дополнительные сведения о причинах ошибки и даны
рекомендации по ее устранению.
61
Существуют четыре способа обращения к справочной службе непосредственно из окна редактора:
F1 - получение контекстно-зависимой справки;
Shift-F1 - выбор справки из списка доступных справочных сообщений;
Ctrl-F1 - получение справки о нужной стандартной процедуре, функции, о стандартной константе или
переменной;
Alt-F1 - получение предыдущей справки.
По команде Shift-F1 на экране появится окно, содержащее упорядоченный по алфавиту список
стандартных процедур, функций, типов, констант и переменных, для которых можно получить
справочную информацию.
Эту же справку можно получить и по-другому. Напечатайте на экране имя процедуры (функции, типа и
т.д.) или подведите курсор к имеющемуся в тексте стандартному имени и нажмите Ctrl-F1. Среда
проанализирует ближайшее окружение курсора, выделит имя и даст нужную справку.
Во многих случаях справка содержит небольшой пример, иллюстрирующий соответствующие
возможности Турбо Паскаля. Не торопитесь запоминать его или записывать на листе бумаги: его можно
«вырезать» из справки и перенести в окно редактора. Для этого после вызова справки нажмите Alt-E,
выберите в появившемся дополнительном меню продолжение Copy examples (копировать примеры) и
нажмите Enter -текст примера скопируется во внутренний буфер редактора. Для извлечения пример из
буфера: нажмите Esc, чтобы выйти из справочной службы; подведите курсор к свободной строке в окне
редактора; нажмите Shift-Insert (копирование содержимого буфера в текст программы) и Ctrl-K H, чтобы
убрать выделение скопированного текста цветом.
10.2 Ваша первая программа
Для знакомства с языком Турбо Паскаля попробуем составить несложную программу, осуществляющую
вывод какого-либо сообщения на экран ПК. Пусть это будет фраза «Я программирую на Турбо Паскале».
Вот возможный вариант такой программы:
Пример 1
Program My_First_Program;
const
Text = 'Я программирую на Турбо Паскале';
begin
WriteLn(Text);
end.
Прежде всего проанализируем форму представления текста. В программе шесть строк. Строки
программы обычно выделяют некоторые смысловые фрагменты текста и могут не связываться с
конкретными действиями в программе: расположение текста программы по строкам - дело вкуса
программиста, а не требование синтаксиса языка. Ту же программу можно было бы написать, например,
так:
Program My_First_Program; const Text =
'Я программирую на Турбо Паскале';begin WriteLn(Text); end.
В отличие от некоторых других языков программирования пробел в языке Турбо Паскаль используется
как разделитель отдельных конструкций языка, поэтому программа
62
PROGRAMMy_First_Program;constText=
'Я программирую на Турбо Паскале';BEGINWriteLn(Text);end.
будет неверной.
В Турбо Паскале игнорируется различие в высоте букв (заглавные или строчные), если только это не
связано с текстовыми константами. Начало программы могло бы, например, выглядеть так:
program my_first_program;
Теперь о смысле отдельных строк. Первая строка
Program My_First_Program;
начинается словом Program и содержит объявление имени программы. Слово Program зарезервировано
в Турбо Паскале, т.е. не может использоваться ни в каких иных целях, кроме как для объявления имени
программы. В Турбо Паскале имеется множество зарезервированных слов. Любое из них нельзя
использовать в качестве идентификатора (имени) какого-либо объекта программы - переменной,
константы и т.д. Замечу, что редактор среды Турбо Паскаля обычно выделяет зарезервированные слова
цветом. Поскольку имя программы никак в дальнейшем не используется, требование его объявления
кажется излишним. В Турбо Паскале можно опускать объявление имени оператором Program без какихлибо последствий для программы.
В рассматриваемом примере имя My_First_Program есть не что иное, как английская фраза «Моя Первая
Программа», но только написанная без пробелов - пробел является разделителем и не может
использоваться произвольно (вместо пробелов в идентификаторах разрешается использовать символ
подчеркивания).
Первая строка заканчивается особым разделителем - точкой с запятой. Этот разделитель в языке Турбо
Паскаль отмечает конец оператора или описания. Использование особого разделителя позволяет
располагать несколько операторов на одной строке.
Вторая строка
const
содержит единственное зарезервированное слово const, означающее, что далее будут описаны одна
или несколько констант (CONSTants - константы). Константами в языке считаются такие объекты
программы, которые не могут изменять своего значения. В отличие от многих других языков
программирования, константа в Турбо Паскале может иметь собственное имя, что соответствует
принятой в научных и инженерных расчетах практике именования часто используемых констант.
Например, со школы мы помним о существовании константы п—3.14159265. При обработке программы
имя константы pi будет заменяться компилятором на ее значение.Описать константу в Турбо Паскале значит указать ее имя и значение. Такое указание содержится в третьей строке
Text = 'Я программирую на Турбо Паскале';
в которой константе с именем Text присваивается в качестве значения строка символов «Я
программирую на Турбо Паскале».
В Турбо Паскале могут использоваться константы разного типа - целые или вещественные числа,
символы, строки символов, массивы и т.д. Признаком того, что Text является константой типа строка
символов, служат два апострофа, обрамляющих строку, причем сами апострофы этой строке не
принадлежат, а лишь указывают компилятору на то, что все заключенные в них символы следует
рассматривать как единое целое - текстовую константу. Если понадобится включить сам апостроф в
текстовую константу, достаточно его написать дважды подряд. Например, описание
Text = 'Турбо' 'Паскаль';
создаст константу со значением
63
Турбо'Паскаль
Все три первые строки не связаны с какими-либо конкретными действиями при работе программы. Они
сообщают компилятору некоторые сведения о самой программе и использующихся в ней объектах. Эта
часть программы называется разделом описаний. Зарезервированное слово begin в четвертой строке
сигнализирует компилятору о начале другой части программы - раздела операторов. В нашем примере
этот раздел содержит оператор
WriteLn(Text);
который, собственно, и выводит сообщение на экран компьютера.
Завершает всю программу зарезервированное слово end с точкой. Точка оповещает компилятор о конце
текста программы. За сочетанием end. можно размещать какой угодно текст - он не будет
обрабатываться компилятором.
Перед тем как попробовать откомпилировать и исполнить нашу программу, обсудим ее единственный
исполняемый оператор
WriteLn(Text);
Процедура WriteLn относится к стандартным или встроенным процедурам Турбо Паскаля. Стандартная
процедура не нуждается в предварительном описании, она доступна любой программе, в которой
содержится обращение к ней. Процедура WriteLn - одна из немногих процедур Турбо Паскаля, при
обращении к которым допускается использование произвольного числа параметров. Параметры
передаются процедуре в виде списка, располагающегося в круглых скобках сразу за именем процедуры.
В нашем примере процедуре передается единственный параметр -константа Text. Как мы уже увидели
ранее (см. п.9.2), самым первым параметром при обращении к процедуре WriteLn можно указать адрес
приемника информации - устройство или дисковый файл, в который направляется вывод. Таким
способом программист может легко переадресовать вывод данных. Если, как это сделано в нашем
примере, адрес вывода не указан, вывод направляется на экран дисплея.
Анализируя всю программу в целом, мы обнаружим, что четыре использовавшихся в ней слова
(Program, const, begin и end) являются зарезервированными. Два слова My_First_Program и Text служат
идентификаторами (именами) некоторых объектов программы. Программист может использовать в
качестве идентификаторов любые последовательности символов, которые удовлетворяют следующим
ограничениям:




идентификатор может состоять из букв латинского алфавита, цифр, знака подчеркивания;
никакие другие символы в идентификаторе недопустимы;
идентификатор не может начинаться с цифры;
идентификатор не может совпадать ни с одним из зарезервированных слов;
длина идентификатора может быть произвольной, но значащими считаются первые 63 символа.
Как и всюду в программе, в идентификаторах игнорируется разница в высоте букв, поэтому, например,
идентификаторы Text, text и TEXT с точки зрения компилятора идентичны.
Теперь попробуйте выполнить программу. Для этого после набора ее текста нажмите Ctrl-F9. Если Вы не
ошиблись при вводе текста, то спустя несколько секунд заметите быструю смену изображений на
экране: сразу после загрузки программы Турбо Паскаль очищает экран, предоставляя его в
распоряжение работающей программы пользователя. Такой экран называется окном программы. После
завершения прогона (работа программы часто называется ее прогоном) на экране вновь появится окно
редактора с текстом программы. Если Вы не успели разглядеть изображение окна программы, нажмите
Alt-F5. После нажатия на любую клавишу среда вернет экран в режим воспроизведения окна редактора.
Перед тем, как двигаться дальше, полезно подробнее ознакомиться с некоторыми возможностями среды
Турбо Паскаля. Нажмите клавишу F10, чтобы перейти к режиму выбора из главного меню, подведите
указатель к опции Window (окно) (это для версии TP6.0, а для версии 7.0 - подведите указатель к опции
Debug (отладка)) и нажмите клавишу Enter - на экране раскроется меню второго уровня, связанное с
этой опцией. Новое меню как бы «выпало» из верхней строки, поэтому такое меню часто называют
выпадающим. Отыщите в новом меню опцию Output (вывод программы), подведите к ней указатель и
нажмите клавишу Enter еще раз. На экране вновь появится окно программы, но оно уже не будет
64
исчезать после нажатия на любую клавишу - экран будет связан с этим окном постоянно. Теперь
добьемся того, чтобы на экране демонстрировались два окна одновременно: вновь нажмите клавишу
F10, выберите Window, нажмите клавишу Enter, подведите указатель к опции Tilе(черепица) и нажмите
клавишу Enter еще раз. Если все сделано правильно, экран приобретет вид, показанный на рис. 2.
Рис. 2 Вид экрана с окнами редактора и программы
Двойная рамка, очерчивающая окно программы, свидетельствует о том, что именно это окно активно в
данный момент. Сделаем активным окно редактора: нажмем клавишу Alt и, не отпуская ее, - клавишу с
цифрой 1 (окно редактора имеет номер 1, окно программы - номер 2, см. верхние правые углы рамок на
рис. 2). Теперь все готово к дальнейшим экспериментам с программой.
Попробуем изменить выводимый на экран текст. Например, уберем в конце третьей строки точку с
запятой и отредактируем ее таким образом:
Text = 'я учусь программировать на турбо паскале'
Если Вы запустите программу вновь, нажав клавиши Ctrl-F9, компилятор сообщит:
Error 85: ";" expected. (Ошибка 85: Отсутствует ";".),
а редактор установит курсор на первый символ слова begin, показывая то место, где при разборе текста
обнаружена ошибка (разделитель «;» может отделять от конца оператора сколько угодно пробелов;
компилятор пропускает эти пробелы в поисках разделителя до тех пор, пока не обнаружит
зарезервированное слово, - вот почему курсор стоит не в конце строки с объявлением константы, а
перед словом begin). Исправьте программу - поставьте в конце третьей строки разделитель «;» и вновь
запустите счет. На этот раз все пройдет нормально, но вывод программы изменится, и в окне программы
появится текст
я учусь программировать на турбо паскале
Этот текст строго соответствует заданному в текстовой константе набору символов, поэтому в нем
отсутствуют прописные буквы.
65
ПРИЛОЖЕНИЕ 1. Ответы к задачам для самоконтроля
1.1 a:=3.4;
1.2 а) 6; б) 7; в) -1; г) -2
1.3
4
4
44
4
1.4 а) [0..55]; б) [-32..-8]; в) [25..67]; г) [-32..65]
2.1 а) 3; б) 2; в) 0; г) 2; д) и е) – ошибки
2.2
а) A:=((x–y)^(2/5)+7.5*y*(2–x)^(1/2))/(2*x*y)–(y+(6*y+z)/(3–y)*x^5)/(3*x).
б)
 y  9
x

2
4

x 
 y  3( x  y ) 

B
 9,5 y 2  y  8 
2
2 y 
x y

3
2.3 x:=3.4; x:=y; x:=6/3;
2.4 а) False; б) True;
3.1
1) x=–7.0 y=–-14.0 z=–4.5
2) ответ: x=0.0 y=–32.5 z=– 65.0
3.2 а) 7; б) 5
3.3 а) –1; б) –2; в) 0
4.1 a[p+1]:=7;
4.2 p=17
5.1 а) a=15;
б) a=15;
в) a=17;
г) a=17;
b=15
b=17
b=15
b=17
6.1 n=11
6.2 а) de; б) abef; в) a***bcd
Рекомендуемая литература
Настоящий конспект лекций содержит весь необходимый теоретический и практический
материал для выполнения лабораторных работ, контрольной работы и получения зачета по дисциплине
“ Программирование на языках высокого уровня”. Однако в случае непонимания каких-либо моментов
при изучении дисциплины желательно воспользоваться дополнительной литературой.
Например, могу посоветовать следующую книгу:
Марченко А.И., Марченко Л.А. Программирование в среде Turbo PASCAL 7.0. Базовый
курс. Киев: «ВЕК+», 2003.
66
Можете воспользоваться и любой другой книгой (не справочником ) по Турбо Паскалю. Желательно,
чтобы в книге было описание работы в среде Турбо Паскаль и больше примеров. Также можно поискать
нужный материал в Интернете (ключевые слова поиска: Турбо Паскаль или Turbo Pascal).
67
Download