Программирование на языке Турбо Паскаль
Программирование на языке Турбо Паскаль
Лекция 1. Структура программы на языке Turbo Pascal
Приведём простейший пример программы, единственная цель которой (
вывести на экран какое-нибудь приветствие:
program Hello;
begin
writeln('Hello, world!');
readln;
end.
Первая строка ничего не делает, она просто содержит название программы.
Затем, после слова begin начинаются собственно действия. В нашей программе
их два: первое ( это вывод строчки «Hello, world» на экран, а второе (
ожидание нажатия клавиши «Enter», оно нужно для того, чтобы можно было
увидеть результат программы, а затем уже нажать «Enter» и вернуться в Турбо-
Паскаль. И, наконец, слово end с точкой в последней строке говорит о том,
что программа закончилась. Действия, из которых состоит программа,
называются операторами, они отделяются друг от друга точкой с запятой.
А теперь приведём пример, в котором программа уже не «глухая», то есть
может запрашивать какие-либо данные у пользователя. Пусть требуется
спросить у пользователя два числа, после этого вывести на экран их
произведение:
program AxB;
var a,b: integer;
begin
writeln('Введите a и b');
readln(a,b);
writeln('Произведение равно ',a*b);
readln;
end;
В этой программе перед словом begin появляется новая строчка,
начинающаяся словом var. В ней мы указываем, что программе понадобится две
переменные (a и b), в которых можно хранить целые числа (слово integer).
О том, что делает первый оператор, нам известно: он выводит на экран
строчку 'Введите a и b'. При выполнении второго оператора программа будет
ждать, пока пользователь не введет число с клавиатуры и не нажмёт «Enter»;
это число программа запишет в переменную a, затем то же самое делается для
переменной b. Третьим оператором выводим на экран сначала надпись
«Произведение равно », а потом значение выражения a(b («*» ( знак
умножения). Четвёртый оператор пояснений не требует.
А теперь рассмотрим структуру программы в общем виде. Любая программа на
Турбо-Паскале состоит из трех блоков: блока объявлений, блока описания
процедур и функций и блока основной программы. Ниже эти блоки расписаны
более подробно.
Блок объявлений:
program ... (название программы)
uses ... (используемые программой внешние модули)
const ... (объявления констант)
type ... (объявления типов)
var ... (объявления переменных)
Блок описания процедур и функций:
procedure (function)
begin
...
end;
...
Блок основной программы:
begin
... (операторы основной программы) ...
end;
Рассмотрим наиболее важные части вышеописанных блоков. Под заголовком
программы понимается имя, помогающее определить её назначение. Имя, или
идентификатор, строится по следующим правилам: оно может начинаться с
большой или малой буквы латинского алфавита или знака «_», далее могут
следовать буквы, цифры или знак «_»; внутри идентификатора не может стоять
пробел. После имени программы следует поставить «;», этот знак служит в
Паскале для разделения последовательных инструкций. Заметим, что имя
программы может не совпадать с именем соответствующего файла на диске.
После слова const помещаются описания постоянных, которые будут
использованы в программе, например:
const Zero = 0;
pi = 3.1415926;
my_const = -1.5;
Hello = 'Привет !';
За словом var следуют объявления переменных, которые понадобятся нам при
написании программы. Переменные Паскаля могут хранить данные различной
природы: числа, строки текста, отдельные символы и т. п. Ниже приводится
часть типов переменных, которые можно применять.
|Название типа |Возможные значения |Примеры значений |
|integer |целые: -32768 ... 32767 |12, -10000 |
|real |действительные (по модулю):|-9.81, 6.02e-23 |
| |2,9x10-39... 1,7x1038 | |
|string[n] |строка до n символов |‘abcde’, ‘привет’ |
| |длиной, если [n] не | |
| |указано, то до 255 | |
|char |одиночный символ |‘F’, ‘!’, ’_’,’ю’ |
Объявления переменных записываются в следующей форме: var :
;
Если описываются несколько переменных одного типа, то достаточно
записать их имена через запятую, а после двоеточия поставить общий тип.
Примеры объявления:
var Number: integer;
d,l: real;
Name: string[20];
Line: string;
Key1,Key2: char;
Блок основной программы. Здесь, между словами begin и end. располагаются
команды (точнее, операторы), которые будут выполняться один за другим при
запуске программы. Рассмотрим простейшие типы операторов на следующем
примере:
program First;
const a2 = 3;
a1 = -2;
a0 = 5;
var x,f: real;
begin
write(‘Введите значение х ’);
readln(x);
f := a2*x*x+a1*x+a0;
writeln(‘Значение квадратного трехчлена: ’,f);
end.
Первая строка исполняемой (основной) части программы выводит на экран
надпись «Введите значение х », для этого используется процедура write
написанная разработчиками Турбо Паскаля, то есть набор команд, невидимый
для нас, но существующий реально в недрах системы Турбо Паскаль. В качестве
параметра этой процедуры используется наша строчка. Параметры всегда
записываются в круглых скобках, апострофы означают, что параметр имеет
строковый тип. Итак, в первой строке мы видим так называемый оператор
вызова процедуры. Каждый оператор отделяется от следующего знаком «;». Во
второй строке вызывается процедура ввода readln(x), которая ждет, пока
пользователь наберет значение x с клавиатуры и нажмет клавишу «Enter», а
затем переводит курсор на следующую строку (ln ( Line ( строка). В третьей
строке вычисляется значение трехчлена и записывается в переменную f; этот
оператор называется оператором присваивания, и обозначается символом ":=".
В последней строке на экран выводится строка «Значение квадратного
трехчлена: » и значение переменной f. Несложно заметить, что здесь
процедуре writeln передается уже не один, а два параметра, причем они могут
иметь разные типы. Вообще, процедуры ввода и вывода (т.е. write, writeln,
read, readln) могут иметь любое число параметров различных типов,
параметрами могут являться переменные, литералы (т.е. непосредственно
записанные числа, строки; в нашем примере дважды были использованы
строковые литералы), а также выражения. Используя выражение при выводе,
можно заменить две последние строчки нашей программы одной:
writeln('Значение квадратного трехчлена: ', a2*x*x+a1*x+a0);
В арифметических выражениях на Паскале используются следующие знаки для
обозначения операций: +, -, *, /. Для определения порядка действий
используются круглые скобки согласно общепризнанным математическим
правилам.
Замечание об именах. Для обозначения переменных запрещается
использование ряда слов, называемых зарезервированными, они играют в языке
особую роль. Нам уже встречался ряд зарезервированных слов: program, begin,
end, string, const, var, и т.п.
Лекция 2. Процедуры ввода-вывода. Некоторые встроенные функции Турбо-
Паскаля.
1. Процедуры ввода-вывода. Почти каждая программа должна общаться с
пользователем, то есть выводить результаты своей работы на экран и
запрашивать у пользователя информацию с клавиатуры. Для того чтобы это
стало возможным, в Турбо-Паскале имеются специальные процедуры (то есть
небольшие вспомогательные программы), называются он процедурами ввода-
вывода. Для того чтобы заставить процедуру работать в нашей программе,
нужно написать её имя, за которым в скобках, через запятую перечислить
параметры, которые мы хотим ей передать. Для процедуры вывода информации на
экран параметрами могут служить числа или текстовые сообщения, которые
должна печатать наша программа на экран. Опишем назначение этих процедур.
. write(p1,p2,... pn); ( выводит на экран значения выражений p1,p2,...
pn, количество которых (n) неограничено. Выражения могут быть
числовые, строковые, символьные и логические. Под выражением будем
понимать совокупность некоторых действий, применённых к переменным,
константам или литералам, например: арифметические действия и
математические функции для чисел, функции для обработки строк и
отдельных символов, логические выражения и т.п. Возможен форматный
вывод, т.е. явное указание того, сколько выделять позиций на экране
для вывода значения. Пример для вещественных типов: write(r+s:10:5); (
вывести значение выражения r+s с выделением для этого 10 позиций, из
них 5 ( после запятой. Для других типов все несколько проще:
write(p:10); ( вывести значение выражения p, выделив под это 10
позиций. Вывод на экран в любом случае производится по правому краю
выделенного поля.
. writeln(p1,p2,... pn); ( аналогично write, выводит значения p1,p2,...
pn, после чего переводит курсор на новую строку. Смысл параметров (
тот же, замечания о форматном выводе остаются в силе. Существует
вариант writeln; (без параметров), что означает лишь перевод курсора
на начало новой строки.
. readln(v1,v2,...vn); ( ввод с клавиатуры значений переменных v1,...vn.
Переменные могут иметь строковый, символьный или числовой тип. При
вводе следует разделять значения пробелами, символами табуляции или
перевода строки (т.е., нажимая Enter).
. read(v1,v2,...vn); ( по назначению сходно с readln; отличие состоит в
том, что символ перевода строки (Enter), нажатый при завершении ввода,
не «проглатывается», а ждет следующего оператора ввода. Если им
окажется оператор ввода строковой переменной или просто readln; то
строковой переменной будет присвоено значение пустой строки, а readln
без параметров не станет ждать, пока пользователь нажмет Enter, а
среагирует на уже введенный.
Пример. Программа просит пользователя ввести с клавиатуры два целых
числа и печатает на экране их сумму:
program PrintSum;
var a,b: integer;
begin
write('Введите два числа:');
readln(a,b);
writeln('Сумма a и b равна ',a+b);
readln;
end.
2. Функции числовых параметров.
|Название |Значение |
|abs(x) |модуль x |
|cos(x) |косинус x |
|frac(x) |дробная часть x |
|int(x) |целая часть x (т.е. ближайшее целое, не превосходящее x) |
|pi |число ( |
|round(x) |x, округлённое до целого |
|sin(x) |синус x |
|sqr(x) |квадрат x |
|sqrt(x) |квадратный корень из x |
|trunc(x) |число, полученное из x отбрасыванием дробной части |
Лекция 3. Операторы условного выполнения.
1. Оператор if.
Иногда требуется, чтобы часть программы выполнялась не всегда, а лишь
при выполнении некоторого условия (а при невыполнении этого условия
выполнялась другая часть программы). В этом случае пользуются оператором
условного выполнения, который записывается в следующем виде:
if then else ;
Под оператором понимается либо одиночный оператор (например,
присваивания, вызова процедуры), либо т.н. составной оператор, состоящий из
нескольких простых операторов, помещённых между словами begin и end. Важно
заметить, что перед else не ставится точка с запятой. Часть else может и
отсутствовать.
Пример 1: пусть требуется найти число m=max(a,b). Этой задаче
соответствует следующий фрагмент программы на Паскале:
if a>b then m:=a else m:=b;
Пример 2: (без else) пусть дано целое число i. Требуется оставить его
без изменения, если оно делится на 2, и вычесть из него 1, если это не так.
var i: integer;
.......
if i mod 2 = 1 then i:=i-1; {else - ничего не делать}
Примечание: в примере использована операция нахождения остатка от
деления (mod), для нахождения неполного частного в Турбо-Паскале
используется div.
Пример 3: (с использованием составного оператора). Пусть даны две
переменные типа real. Требуется поменять местами значения этих переменных,
если a1>a2.
var a1,a2,buf :real;
.........
if a1>a2 then begin
buf:=a1;
a1:=a2;
a2:=buf;
end;
Следующий пример использует вложенные операторы if.
Пример 4: Поиск корней квадратного уравнения.
program SqEquation;
var a,b,c,d: real;
begin
writeln;
write('Введите коэффициенты a,b,c квадратного уравнения : ');
readln(a,b,c);
d:=sqr(b)-4*a*c;
if d>=0 then
if d=0 then writeln('Единственный корень: x=',-b/(2*a):8:3)
else writeln('Два корня : x1=',(-b+sqrt(d))/(2*a):8:3,
', x2=',(-b-sqrt(d))/(2*a):8:3)
else {d '); readln(n);
write(n,' ученик');
if n1 then writeln('а');
end
else
writeln('ов');
readln;
end.
В этом примере пришлось использовать составной оператор (begin ... end;)
для того чтобы часть else относилась не к оператору if n>1, а к if n '); readln(n);
write(n,' ученик');
case n of
2..4: write('а');
5..10: write('ов');
end;
readln;
end.
Можно также усовершенствовать программу для произвольного натурального
n:
write(n,' ученик');
case n mod 100 of
11..19: write('ов');
else case n mod 10 of
2..4: write('а');
0,5..9: write('ов');
end;
end;
Лекция 4. Операторы циклов в Паскале
В реальных задачах часто требуется выполнять одни и те же операторы
несколько раз. Возможны различные варианты: выполнять фрагмент программы
фиксированное число раз, выполнять, пока некоторое условие является
истинным, и т. п. В связи с наличием вариантов в Паскале существует 3 типа
циклов.
1. Цикл с постусловием (Repeat)
На Паскале записывается следующим образом: repeat until
. (По-русски: повторять что-то пока_не_выполнилось условие). Под
обозначением здесь понимается либо одиночный, либо
последовательность операторов, разделённых точкой с запятой. Цикл работает
следующим образом: выполняется оператор, затем проверяется условие, если
оно пока еще не выполнилось, то оператор выполняется вновь, затем
проверяется условие, и т. д. Когда условие, наконец, станет истинным
выполнение оператора, расположенного внутри цикла, прекратится, и далее
будет выполняться следующий за циклом оператор. Под условием, вообще
говоря, понимается выражение логического типа.
Пример (подсчет суммы натуральных чисел от 1 до 100):
var i,sum: integer;
begin
sum:=0; i:=0;
repeat
i:=i+1;
sum:=sum+i;
until i=100;
writeln('Сумма равна: ',sum);
readln;
end.
Важно заметить, что операторы стоящие внутри цикла repeat (иначе ( в
теле цикла) выполняются хотя бы один раз (только после этого проверяется
условие выхода).
2. Цикл с предусловием (While)
Этот цикл записывается так: while do . (Пока условие
истинно, выполнять оператор). Суть в следующем: пока условие истинно,
выполняется оператор (в этом случае оператор может не выполниться ни разу,
т.к. условие проверяется до выполнения). Под оператором здесь понимается
либо простой, либо составной оператор (т.е. несколько операторов,
заключёных в begin ... end).
Рассмотрим тот же пример, выполненный с помощью while:
var i,sum: integer;
begin
sum:=0; i:=0;
while i:= to do . Вместо
to возможно слово downto. Рассмотрим такой пример: требуется вывести на
экран таблицу квадратов натуральных чисел от 2 до 20.
var i: integer;
begin for i:=2 to 20 do writeln(i,' ',sqr(i)); end.
При выполнении цикла происходит следующее: переменной i присваивается
начальное значение (2), затем выполняется оператор (простой или составной),
после этого к i прибавляется 1, и проверяется, не стало ли значение i равно
конечному (20). Если нет, то вновь выполняется оператор, добавляется 1, и
т. д. В случае, когда вместо to используется downto, все происходит
наоборот: единица не прибавляется, а вычитается. Например, следующий цикл
выведет ту же таблицу, но в обратном порядке:
for i:=20 downto 2 do writeln(i,' ',sqr(i));
В завершение запишем программу о подсчете суммы чисел от 1 до 100 с
помощью for:
var i, sum: integer;
begin
sum:=0;
for i:=1 to 100 do sum:=sum+i;
writeln(sum);
end.
Лекция 5. Символьные и строковые переменные
В математике под переменной обычно понимают некую величину, значения
которой могут быть только числами. В языках программирования почти все
данные, с которыми работают программы, хранятся в виде переменных. В
частности, бывают переменные для хранения текстовых данных: предложений,
слов и отдельных символов.
1. Символьный тип
Тип данных, переменные которого хранят ровно один символ (букву, цифру,
знак препинания и т.п.) называется символьным, а в Паскале — char. Объявить
переменную такого типа можно так: var ch: char;. Для того чтобы положить в
эту переменную символ, нужно использовать оператор присваивания, а символ
записывать в апострофах, например: ch:='R';. Для символьных переменных
возможно также использование процедуры readln, например:
write(‘Выйти из игры? (Да/Нет)’); readln(ch);
if ch=’Д’ then ...{выходить}...
else ...{продолжать}...;
Символьные переменные в памяти компьютера хранятся в виде числовых
кодов, иначе говоря, у каждого символа есть порядковый номер. К примеру,
код пробела равен 32, код ‘A’ — 65, ‘B’ — 66, ‘C’ — 67, код символа ‘1’ —
48, ‘2’ — 49, ‘.’ — 46 и т. п. Некоторые символы (с кодами, меньшими 32)
являются управляющими, при выводе таких символов на экран происходит какое
либо действие, например, символ с кодом 10 переносит курсор на новую
строку, с кодом 7 — вызывает звуковой сигнал, с кодом 8 — сдвигает курсор
на одну позицию влево. Под хранение символа выделяется 1 байт (байт
состоит из 8 бит, а бит может принимать значения 0 или 1), поэтому всего
можно закодировать 28=256 различных символов. Кодировка символов, которая
используется Турбо-Паскале, называется ASCII (American Standard Code for
Information Interchange — американский стандартный код для обмена
информацией).
Для того чтобы получить в программе код символа нужно использовать
функцию chr, например:
var i: byte; {число, занимающее 1 байт, значения — от 0 до 255}
ch: char;
...
readln(i); writeln('символ с кодом ',i,' — это ',chr(i));
Если в качестве кода используется конкретное число, а не выражение и не
переменная, то можно использовать символ «#», скажем так: ch:=#7;. Для
того перехода от кода к символу используется функция ord (от слова ordinal
— порядковый). Имеющиеся знания позволяют нам написать программу, которая
выдаёт на экран таблицу с кодами символов:
program ASCII;
var ch: char;
begin
for ch:=#32 to #255 do write(ord(ch),'—>',ch,' ');
readln;
end.
В этой программе в качестве счётчика цикла была использована символьная
переменная, это разрешается, поскольку цикл for может использовать в
качестве счётчика переменные любого типа, значения которого хранятся в виде
целых чисел.
С использованием кодов работают ещё две функции, значения которых
символьные:
1. succ (от succeedent — последующий), она выдаёт символ со следующим
кодом.
2. pred (от predecessor — предшественник), выдаёт символ с предыдущим
кодом.
Если попытаться в программе получить succ(#255) или pred(#0), то возникнет
ошибка. Пользуясь этими функциями можно переписать предыдущую программу и
по-другому:
...
ch:=#32;
while ch<>#255 do begin
write(ord(ch),'—>',ch,' ');
ch:=succ(ch);
end;
...
Сравнение символов. Также как и числа, символы можно сравнивать на =,
<>, , =. В этом случае Паскаль сравнивает не сами символы, а их
коды. Таблица ASCII составлена таким образом, что коды букв (латинских и
большинства русских) возрастают при движении в алфавитном порядке, а коды
цифр расположены по порядку: ord(‘0’)=48, ord(‘1’)=49, ... ord(‘9’)=57.
Сравнения символов можно использовать везде, где требуются логические
выражения: в операторе if, в циклах и т.п.
2. Строковый тип
Для хранения строк (то есть последовательностей из символов) в Турбо-
Паскале имеется тип string. Значениями строковых переменных могут быть
последовательности различной длины (от нуля и более, длине 0 соответствует
пустая строка). Объявить строковую переменную можно двумя способами: либо
var s: string; (максимальная длина строки — 255 символов), либо var s:
string[n]; (максимальная длина — n символов, n — константа или конкретное
число).
Для того чтобы положить значение в строковую переменную используются те
же приёмы, что и при работе с символами. В случае присваивания конкретной
строки, это строка должна записываться в апострофах (s:='Hello, world!').
Приведём простейший пример со строками: программа спрашивает имя у
пользователя, а затем приветствует его:
program Hello;
var s: string;
begin
write('Как Вас зовут: ');
readln(s);
write('Привет, ',s,'!');
readln;
end.
Хранение строк. В памяти компьютера строка хранится в виде
последовательности из символьных переменных, у них нет индивидуальных имён,
но есть номера, начинающиеся с 1). Перед первым символом строки имеется
ещё и нулевой, в котором хранится символ с кодом, равным длине строки. Нам
абсолютно безразлично, какие символы хранятся в байтах, находящихся за
пределами конца строки. Рассмотрим пример. Пусть строка s объявлена как
string[9], тогда после присваивания s:=’Привет’; она будет хранится в
следующем виде:
|Номер байта |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |
|Содержимое |#6 |‘П’ |‘р’ |‘и’ |‘в’ |‘е’ |‘т’ |‘ю’ |‘s’ |‘%’ |
Для того чтобы в программе получить доступ к n-му символу строки
используется запись s[n]. Если поменять значение s[0] то это отразится на
длине строки. В следующем примере из строки 'Привет' мы сделаем 'Привет!':
s[0]:=#7; s[7]:='!';.
Сравнение строк. Строки сравниваются последовательно, по символам.
Сравниваются первые символы строк, если они равны — то вторые, и т. д. Если
на каком-то этапе появилось различие в символах, то меньшей будет та
строка, в которой меньший символ. Если строки не различались, а затем одна
из них закончилась, то она и считается меньшей. Примеры: 'ананас''свинина', ''Fri then writeln('Сегодня выходной');
...
if day=Mon then writeln('Началась рабочая неделя');
Как вы уже заметили значения перечислимого типа можно сравнивать, при
этом меньшим считается то, которое объявлено раньше (левее) в определении
типа.
Для переменных перечисляемых типов возможно применение функций succ и
pred, например, succ(Wed) дает Thu, Pred(Sun) дает Sat. Если попытаться
написать Pred(Mon) или Succ(Sun), то уже на этапе проверки программы
компилятором произойдет ошибка.
Хранение значений перечисляемого типа устроено внутри довольно просто:
хранятся целые числа от 0 до n, в нашем случае n=6. Существует функция Ord,
которая позволяет получить то число, в виде которого хранится какое-либо
значение перечисляемого типа, например Ord(Wed) дает 2. При необходимости
можно получить значение перечисляемого типа по его численному
представлению, например, Days(1) есть Tue. После всего сказанного можно
заметить, что при сравнении величин перечисляемого типа в действительности
сравниваются их порядковые номера (Ord).
Пример использования перечисляемых типов:
Пусть корабль может двигаться только по четырем направлениям: на север,
на запад, на юг и на восток, то есть текущее направление движения
определяется переменной типа Directions = (North, West, South, East);.
Этому кораблю можно подавать приказы следующих типов: вперёд, назад, влево,
вправо, то есть любой приказ задать переменной типа Orders = (Ahead, Back,
Left, Right);. Пусть корабль двигался по направлению d1, после чего ему
дали приказ p. Программа должна определить, в каком направлении корабль
будет двигаться после выполнения приказа.
program Ship;
type Courses = (North, West, South, East);
Orders = (Ahead, Back, Left, Right);
var d1, d2: Courses;
p: Orders;
i: integer;
s: string;
begin
{Запрашиваем у пользователя информацию о курсе и приказе}
writeln('Введите первоначальный курс корабля ');
write('(0-север, 1-запад, 2-юг, 3-восток) ');
readln(i);
d1:=Courses(i);
writeln('Введите приказ, данный кораблю ');
write('(0-прямо, 1-назад, 2-влево, 3-вправо) ');
readln(i);
p:=Orders(i);
{Определяем новый курс}
case p of
Ahead : d2:=d1;
Back : d2:=Courses((ord(d1)+2) mod 4);
Left : d2:=Courses((ord(d1)+1) mod 4);
Right : d2:=Courses((ord(d1)+3) mod 4);
{-1 - нельзя, так как (Ord(North)-1) mod 4 = -1}
end;
{Выводим результат на экран}
case d2 of
North : s:='север';
West : s:='запад';
South : s:='юг';
East : s:='восток';
end;
writeln('Теперь корабль движется на '+s);
readln;
end.
2. Ограниченный тип
Этот тип также рассмотрим на примере. Пусть в некоторой переменной нужно
хранить текущее число, то есть номер дня в месяце. В Турбо Паскале можно
задать тип DaysInMonth = 1..31;. Переменные и константы этого типа могут
принимать только такие значения, если попытаться задать что-либо другое, то
компилятор выдаст ошибку. В качестве границ могут употребляться и
отрицательные числа, например Temperature=-60..50;
В качестве базового типа (то есть типа, из которого выбирается диапазон
значений) могут использоваться почти все порядковые типы, то есть те,
которые хранятся в виде целых чисел. К порядковым типам относятся: все
целые типы (byte, integer, и т. п.), char, boolean, перечисляемые типы и
ограниченные типы. В качестве базового типа нельзя использовать лишь сам
ограниченный тип (трудно представить, как это можно сделать). С учетом
этого правила допустимы такие объявления типов:
type SmallLatin = 'a'..'z'; {малые латинские буквы}
MyBoolean = True..False; {хотя это и бессмысленно}
Holidays = Sat..Sun; {выходные}
Нельзя в качестве базового типа употребить какой-либо вещественный тип,
следующее объявление приведет к ошибке:
type Wrong = -1.25..1.25;
Заметим, что функции Ord, Succ и Pred могут применяться к любым
порядковым типам, и, в частности, к ограниченным.
Лекция 7. Массивы
1. Понятие массива. Одномерные массивы
Массивы являются представителями структурированных типов данных, то есть
таких, переменные которых составлены из более простых элементов согласно
определённому порядку. Для массивов характерно то, что они являются
совокупностью некоторого числа одинаковых элементов. В простейшем случае
эти элементы могут быть занумерованы натуральными числами из некоторого
диапазона. Рассмотрим пример такой переменной в Турбо Паскале:
var a: array [1..10] of real;
Переменная a состоит из десяти ячеек типа real, можно записывать и
извлекать значения из них, пользуясь записью a[].
Пример 1. Поиск наибольшего числа среди элементов массива.
program FindMaximumInArray;
var a: array[1..10] of real;
i,max: integer;
begin
for i:=1 to 10 do begin
write('Введите элемент номер ',i,' -> ');
readln(a[i]);
end;
max:=a[1];
for i:=2 to 10 do
if a[i]>max then max:=a[i];
writeln('Максимум равен ',max);
readln;
end.
В качестве типа элементов массива можно использовать все типы, известные
нам на данный момент (к ним относятся все числовые, символьный, строковый
и логический типы).
Нумеровать элементы массивов можно не только от единицы, но и от любого
целого числа. Вообще для индексов массивов подходит любой порядковый тип,
то есть такой, который в памяти машины представляется целым числом.
Единственное ограничение состоит в том, что размер массива не должен
превышать 64 Кб. Рассмотрим некоторые примеры объявления массивов.
var Numbers: array [0..1000] of integer;
Names: array [1..10] of string;
Crit: array[shortint] of boolean;
CountAll: array[char] of integer;
Count: array['a'..'z'] of integer;
В следующем примере показано для чего может понадобиться последний тип.
Пример 2. Подсчет количества различных букв в строке.
program CountLetters;
var s: string;
count: array['a'..'z'] of byte;
ch: char;
i: byte;
begin
write('Введите строку > ');
readln(s);
for i:=1 to length(s) do
if (s[i]>='a')and(s[i]0 then
writeln(ch,': ',count[ch]);
readln;
end.
2. Многомерные массивы
При необходимости можно нумеровать массивы не одним индексом а двумя и
более. Двумерному массиву соответствует матрица в математике, то есть
прямоугольная таблица.
Примеры описаний многомерных массивов:
var Matrix: array[1..4,1..3] of real;
Cube3D: array[1..5,1..5,1..5] of integer;
Рассмотрим пример использования двумерного массива.
Пример 3. Построить календарь на следующий год, то есть при вводе номера
месяца и числа выдавать день недели.
program Calendar;
type tWeekDay = (Mon,Tue,Wed,Thu,Fri,Sat,Sun,NoDay);
{NoDay - нет дня (например, 30.02)}
tCalendar = array [1..12,1..31] of tWeekDay;
var CL: tCalendar;
m,d: byte; {месяц и число}
wd: tWeekDay; {день недели}
begin
{Строим массив:}
{1. Заполним весь календарь значениями "нет дня":}
for m:=1 to 12 do
for d:=1 to 31 do CL[m,d]:=NoDay;
{2. Строим массив-календарь:}
m:=1; d:=1;
wd:=Mon;
repeat
CL[m,d]:=wd;
case m of
4,6,9,11: if d=30 then begin m:=m+1; d:=1; end else d:=d+1;
1,3,5,7,8,10,12: if d=31 then begin m:=m+1; d:=1; end else d:=d+1;
2: if d=28 then begin m:=m+1; d:=1; end else d:=d+1;
end;
wd:=tWeekDay((ord(wd)+1) mod 7);
until m=13;
{Выводим на экран:}
repeat
write('Номер месяца > '); readln(m);
write('Число > '); readln(d);
case CL[m,d] of
Mon: writeln('Понедельник');
Tue: writeln('Вторник');
Wed: writeln('Среда');
Thu: writeln('Четверг');
Fri: writeln('Пятница');
Sat: writeln('Суббота');
Sun: writeln('Воскресенье');
NoDay: writeln('Такого дня нет в календаре');
end;
until false;
end.
3. Сортировка и поиск
В прикладных программах широко распространены два типа операций,
связанных с массивами:
1. Упорядочивание элементов массива по возрастанию или убыванию
(сортировка)
2. Поиск элемента в массиве.
Рассмотрим простейший вариант сортировки массива (сортировка выбором).
Пусть есть массив из n элементов; сначала найдём в нём самый маленький
среди элементов с номерами 2,3,...n и поменяем местами с первым элементом,
затем среди элементов с номерами 3,4,...n найдём наименьший и обменяем со
вторым, и т. д. В результате наш массив окажется отсортированным по
возрастанию.
program SelectSort;
const n = 10;
var a: array [1..n] of integer;
i,j,jmin,buf: integer;
{jmin - номер наименьшего элемента,
buf используется при обмене значений двух элементов}
begin
for i:=1 to 10 do begin
write('Введите элемент номер ',i,' -> ');
readln(a[i]);
end;
for i:=1 to n-1 do begin
jmin:=i;
for j:=i+1 to n do
if a[j]999999)
then writeln(‘Ошибка’);
...
end.
Заметим, что в этом примере постоянно приходится обращаться к полям
одной и той же переменной типа запись, и, следовательно, постоянно писать
её имя. Есть возможность избавиться от этого неудобства. В Турбо Паскале
есть оператор присоединения (with), который позволяет один раз указать,
какой записью мы пользуемся и в дальнейшем писать только имена полей.
Обычно этот оператор выглядит так:
with do ;
Чаще всего в качестве оператора используется составной оператор.
Пример:
with p do begin
Surname:=’ Иванов’;
Name:=’Иван’;
...
end;
Страницы: 1, 2, 3
|