Лекция 8ПП

advertisement
1
Лекция 8
8.0. Подпрограммы
8.1. Основные понятия
Подпрограмма – логически законченная часть программы, которую по имени можно
вызывать в разные места программы неограниченное число раз.
Она решает часть общей задачи. У нее есть имя, которое используется при вызове
подпрограммы в основную программу.
Подпрограммы бывают 2 видов:
– процедуры и
– функции.
Процедура не возвращает значений (например, рисует) или возвращает несколько
значений (корни квадратного уравнения).
Функция возвращает одно значение.
Программа без структурных элементов называется монолитной. Минимальный
элемент такой программы - оператор. Она сложна в разработке, отладке и
сопровождении.
Структурированная программа называется модульной. Она содержит более крупные
компоненты - подпрограммы. Модульная программа проще создается, более понятна.
Модульная программа может иметь иерархическую структуру.
Работа с подпрограммой включает 2 этапа:
- описание подпрограммы;
- вызов подпрограммы.
Преимущества подпрограммы:
1. в программе нет дублирования кода;
2. повышается надежность программы;
3. улучшается «читаемость» программы;
4. облегчается процесс отладки.
Различают подпрограммы:
– без параметров,
– с параметрами.
8.2. Процедурный тип
Процедурный тип расширяет традиционное понятие подпрограмм, позволяя
обращаться с подпрограммами как с переменными. Используется в программировании,
где структура программы отражает структуру решаемой задачи. В результате алгоритм
решения ясно виден из исходного текста.
Процедурный тип это внешние данные, используемые подпрограммой.
Процедурный тип объявляется следующим образом:
type
<имя1> = procedure;
<имя2> = procedure(<список параметр.>);
<имя3> = function (список параметров) : <тип результата>;
Этот тип определяет процедуру без параметров, процедуру с параметрами или
функцию.
Например:
type
Proc1 = Procedure;
// Тип – процедура без параметров
Proc2 = Procedure(x,y : real);
//Тип – процедура с параметрами
2
Func1 = Function(x,y : real): real; //Тип – функция
8.3. Сравнение вариантов
Рассмотрим 2 варианта решения одной и той же задачи: вывод текстовых блоков с
вставкой стандартного разделителя из трех строк из набора символов “ * ” в конце.
1 –й вариант (Монолитная программа)
program Example1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
i, j : integer;
begin
Writeln('Text 1');
// Вывод 1 текста
for j :=1 To 3 Do
begin
// Вывод строки из 20 символов “ * ”
for i :=1 To 20 Do write( ' * ' );
writeln;
end;
Writeln('Text 2');
//Вывод 2 текста
for j :=1 To 3 Do
begin
// Вывод строки из 20 символов “ * ”
for i :=1 To 20 Do write( ' * ' );
writeln;
end;
readln
end.
Начало
2 – й вариант (Модульная программа)
program Example2;
{$APPTYPE CONSOLE}
uses
SysUtils;
Procedure DrawStr;
// Процедура “Рисовать строки”
var
i, j : integer;
begin
for j :=1 To 3 Do
begin
// Вывод строки из 20 символов “*”
for i :=1 To 20 Do write( ' * ' );
writeln;
// Перейти к следующей строке
end;
end;
begin
//основная программа
Writeln( ' Text 1 ' );
// Вывод 1 текста
DrawStr;
// Вывод строк разделителя
Writeln( ' Text 2 ' );
// Вывод 2 текста
DrawStr;
// Вывод строк разделителя
readln
1 Объявление
процедуры DrawStr
2
3
4
j=1..3, 1
i=1..20, 1
Вывод ' * '
Конец
Начало
1
Вывод Текст1
2
п/п DrawStr
3
Вывод Текст2
4
п/п DrawStr
Конец
3
end.
8.4. Аргументы и параметры
Параметры - данные, с которыми работает подпрограмма. Это внутренние данные
для подпрограммы и перечисляются в ее заголовке с указанием типов.
Они связаны с аргументами.
Аргументы - данные, передаваемые в подпрограмму или возвращаемые из нее. Это
внешние для подпрограммы данные, с которыми имеет дело вызывающая часть
программы. В подпрограмме им соответствуют параметры. Указываются в списке
аргументов при обращении к подпрограмме и являются фактическими параметрами.
Синонимы:
Параметры = формальные параметры,
Аргументы = фактические параметры.
-----------------------------------------------------Для аргументов и параметров надо соблюдать:
- одинаковое количество (An=Pn) ,
- одинаковый порядок следования (A1-P1, A2-P2..)
- совместимость типов.
Все формальные параметры разделяются на 4 категории:
– параметры-значения – в списке параметров указывается их тип, например (x,y :
real); передаются через стек в виде копий и остаются неизменными в подпрограмме;
– параметры-константы – в списке параметров снабжаются служебным словом
(const s : real); передаются подпрограмме в виде копий с помощью адресов, изменяться
подпрограммой не могут;
– параметры-переменные – в списке параметров снабжаются служебным словом
(x,y:byte; var ss : real); инструкции подпрограммы могут изменить значение переменной,
являющейся фактическим параметром;
– параметры процедурного типа – в списке задаются именами и являются
параметрами-значениями.
8.5. Области действия имен
Структура подпрограммы идентична структуре программы.
Имена, объявленные в главной программе являются глобальными. Они доступны во
всех внутренних точках, в том числе и в подпрограммах.
Имена, объявленные в подпрограмме являются локальными. Они доступны во всех
внутренних точках подпрограммы.
Локальное имя во внешней программе недоступно. Память под них выделяется
автоматически в момент вызова подпрограммы.
Если используются одинаковые локальное и глобальное имя, то внутри процедуры
локальное имя блокирует глобальное.
Формат доступа к глобальному имени:
<имя программы>.<глобальное имя>
//имя составное
4
Чтобы получить доступ к такому глобальному имени в подпрограмме его надо
указывать составным.
8.6. Функция
Объявление функции в общем виде
Function <Имя> (p1,p2:T1;...):T;
// Заголовок функции: Имя функции
var
//объявление локальных переменных - параметров
begin
-----------// тело функции
Имя :=<выражение>;
//или
Result := <выражение>; //глобальное имя
-----------end;
-------------------------------------------------------Имя - имя функции (имя существительное) используется для ее вызова,
T - тип возвращаемого функцией результата.
p1, p2 - имена формальных параметров, значение которых используются для
вычисления значения функции. Объявляется в заголовке функции. Конкретные значения
параметры получают во время работы программы в результате вызова функции из
основной программы.
T1 - их тип.
Обращение при обычном синтаксисе.
Форма вызова функции:
program Example3;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
// Объявление аргументов.
a1: integer;
a2,a3: real;
Function MyFunc(p1: integer; p2: real): real;
//Заголовок функции
// Разделы локальных определений
begin
//Тело функции
MyFunc:=<выражение>;
...
end;
begin
//Основная программа
...............
a3:=3+MyFunc(a1,a2);
//Вызов функции по имени в выражении
...............
end.
----------------------------------------------------Соответствия: p1 - a1, p2 - a2
5
Задача1 . Написать функцию, проверяющую, является ли целое число, введенное с
клавиатуры четным. Программа должна использовать эту функцию, проверять является
ли число четным или нет, и выводить соответствующее сообщение.
Начало
program Example4;
{$APPTYPE CONSOLE}
1 Объявление
функции Сhet
нет
да 2
n mod 2=0 ?
uses
SysUtils;
var
m: integer; //вводимое с клавиатуры число
function Chet(n:integer): boolean; //Заголовок функции
begin
//Тело функции Chet
if n mod 2 = 0 then Chet:=True
else Chet:=False;
end;
begin
// Основная программа
repeat
read(m); // Проверка условия на четность числа m
// с помощью функции Chet
if chet(m) then writeln(m,' - chetnoe chislo')
else writeln(m,' - nechetnoe chislo');
until m=0;
readln
end.
3
4 Сhet=False
Сhet=True
Конец
Начало
1
Ввод числа m
да
2
Chet(m) ?
4
m - нечетное
3
m - четное
нет 5
нет
m=0
да
Конец
8.7. Процедуры
Объявление процедуры в общем виде
Procedure <Имя>( p1, p2 : T1; ... // Параметр-значение
var p3, p4 : T2; ... // Параметр-переменная
const p5, p6 : T3; ...); //Параметр-константа
var
//объявление локальных переменных - параметров
begin
//тело процедуры
end;
--------------------------------------------------------
Имя - имя процедуры (глагол) подпрограмму-, используется для ее вызова
var - признак параметров-переменных,
const -признак параметров констант;
6
p1, p2, p3, p4, p5, p6 - имена параметров,
T1, T2, T3 - их типы.
Обращение. Форма вызова процедуры:
program Example5;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
// Объявление аргументов
a1: integer;
a2 : real;
{..........…..}
Procedure MyProc( var p1: integer; p2 : real);
//Разделы локальных определений
begin
//Тело подпрограммы
end;
begin
// Основная программа
{...............}
MyProc(a1, a2);
//Вызов процедуры по имени в строке кода
{...............}
end.
----------------------------------------------------------
Начало
Соответствия: p1 - a1, p2 - a2
Задача2. Вывести таблицу квадратных корней.
Для оформления таблицы использовать процедуру Line.
program Example6;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
i:integer;
Procedure Line(n:integer; c:char);
var
k:integer;
begin
for k:=1 to n do write(c);
writeln;
end;
begin
writeln('Tabl kvadratnyx korney');
Line(15,'=');
writeln('Chislo | Koren');
Line(15,'=');
for i:=1 to 5 do
begin
writeln(i:5,' ',sqrt(i):6:2);
Line(15, '-');
end;
1 Объявление
процедуры
Line
Line
2
k=1..n, 1
3 Вывод
символа
Конец
Начало
1
Вывод
Заголовка
2
п/п Line
3 Вывод
шапки табл.
4
5
46
п/п Line
k=1..n, 1
Вывод c
7
п/п Line
Конец
7
readln
end.
8.8. Процедура или функция?
Процедура и функция два способа оформления подпрограммы. Одну и ту же
подпрограмму можно оформить как процедуру или как функцию.
Пример вычисления сопротивления цепи (Sopr), состоящей из трех параллельных
сопротивлений (R1, R2, R3).
Procedure SoprPar(r1, r2, r3:real; var sr:real);
begin
sr := (r1+r2+r3)/(r1*r2*r3);
end;
Function SoprPar(r1, r2, r3:real; var sr:real):real;
var
sr : real;
begin
sr := (r1+r2+r3)/(r1*r2*r3);
SoprPar:=sr;
end;
Оформление подпрограммы в виде функции более предпочтительно, т.к. целью
вычисления является получение одного значения.
Правило:
Если подпрограмма должна изменить значение только одной переменной основной
программы, то ее следует оформить как функцию, в остальных случаях подпрограмму
следует оформить как процедуру.
9. Модули
Модуль – повторное использование функций и процедур.
Создание модуля:
Командой File => New => Unit (Файл => Новый => Модуль) в редактор кода проекта
добавляется страничка с заготовкой модуля, которая затем заполняется кодом:
unit MayUnit;
interface
implementation
...
end.
Шаблон модуля:
// имя модуля изменяется после его сохранения
//описательная часть
// реализация
// код модуля
Использование модуля MayUnit :
Добавить этот модуль по имени к проекту в список модулей.
program Blank;
{$APPTYPE CONSOLE}
uses
SysUtils, MayUnit;
var
...
begin
8
...
end.
//код проекта
Работа с модулем:
1. Создать консольное приложение командой Файл => Новый => Другое => Console
Application.
2. Cохранить проект в папке KR командой Файл => Сохранить проект как…=> Blank.
3. Создать модуль для преобразования кодов символов из одной кодировки в другую.
Для этого выполнить команду Файл => Новый => Модуль. В редакторе кода проекта
возникает дополнительная страничка с заготовкой модуля. Заполнить ее кодом:
unit Unit1; //Заголовок модуля, после сохранения имя меняется на другое
interface
// Раздел описания
uses
SysUtils;
// Ссылка на подключаемые модули
function Rus(mes:string):string; // Заголовок функции Rus с переменной mes
implementation
// Раздел реализации
function Rus(mes:string):string; //Преобразует строку Windows под строку MSDOS
var i:integer;
//Номер обрабатываемого символа
begin
// Тело функции
for i:=1 to length(mes) do
case mes[i] of // Оператор выбора
'А'..'п': mes[i] := chr(ord(mes[i])-64); //преобразование символов в коды
'р'..'я' : mes[i] := chr(ord(mes[i])-16); //преобразование символов в коды
'Ё' : mes[i] := chr(ord(mes[i])+72); //преобразование символа в код
'ё' : mes[i] := chr(ord(mes[i])+57); //преобразование символа в код
end;
result:=mes; //возвращаемый результат в переменную result
end;
end.
4. Сохранить код модуля командой Файл => Сохранить как…в папке KR под именем
RusTrans.pas. Заголовок модуля Unit1 изменится на RusTrans.
5. Выполнить компиляцию модуля RusTrans.pas с помощью команды Проект =>
Компилировать Blank. В папке проекта KR появится файл компилированного модуля
RusTrans.dcu, а в проекте Blank в разделе Uses добавится строка с его именем.
program Blank;
{$APPTYPE CONSOLE}
uses
SysUtils,
RusTrans in 'RusTrans';
begin
{Main : Insert code here }
.....
writeln(Rus('Я студент ПГАТИ'));
readln;
end.
6. В разделе исполнения проекта Blank между операторными скобками begin… end
для проверки работы модуля RusTrans внести строку кода с любым текстом, например
writeln(Rus('Я студент')).
9
7. Запустить проект на исполнение командой Выполнить => Выполнить, и
убедиться, что при подключении модуля, проблема с отображением букв кириллицы
решена.
8. Удалить введенную для проверки работоспособности строку. Сохранить
изменения в проекте, щелкнув по кнопке Сохранить на панели Инструментов.
9. В соответствующие разделы проекта в вести переменные, процедуры и код для
решения поставленных задач.
01- ☺
2- ☻
3- ♥
4- ♦
5- ♣
6- ♠
789 - Tab
10 11 - ♂
12 - ♀
13 14 - ♫
15 - ☼
16 - ►
17 - ◄
18 - ↕
19 - ‼
20 - ¶
21 - §
22 - ▬
23 - ↨
24 - ↑
25 - ↓
26 - →
27 - ←
28 -∟
29 - ↔
30 -▲
31 - ▼
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 -
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 -
!
"
#
$
%
&
'
(
)
*
+
,
.
/
128 - А
129 - Б
130 - В
131 - Г
132 - Д
133 - Е
134 - Ж
135 - З
136 - И
137 - Й
138 - К
139 - Л
140 - М
141 - Н
142 - О
143 - П
144 - Р
145 - С
146 - Т
147 - У
148 - Ф
149 - Х
150 - Ц
151 - Ч
152 - Ш
153 - Щ
154 - Ъ
155 - Ы
156 - Ь
157 - Э
158 - Ю
159 - Я
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 -
а
б
в
г
д
е
ж
з
и
й
к
л
м
н
о
п
128 - Ђ
129 - Ѓ
130 - ‚
131 - ѓ
132 - „
133 - …
134 - †
135 - ‡
136 - €
137 - ‰
138 - Љ
139 - ‹
140 -Њ
141 -Ќ
142 -Ћ
143 –Џ
144 - ђ
145 - ‘
146 - ’
147 - “
148 - ”
149 - •
150 - –
151 - —
152 - ˜
153 - ™
154 - љ
155 - ›
156 -њ
157 -ќ
158 -ћ
159 -џ
160 161 - Ў
162 - ў
163 - Ј
164 - ¤
165 - Ґ
166 - ¦
167 - §
168 - Ё
169 - ©
170 - Є
171 - «
172 -¬
173 -174 -®
175 -Ї
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 -
░
▒
▓
│
┤
╡
╢
╖
╕
╣
║
╗
╝
╜
╛
┐
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 -
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
-
└
┴
┬
├
─
┼
╞
╟
╚
╔
╩
╦
╠
═
╬
╧
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 -
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
Базовая таблица кодировки ASCII
96 - `
97 - a
98 - b
99 - c
100 - d
101 - e
102 - f
103 - g
104 - h
105 - i
106 - j
107 - k
108 - l
109 - m
110 - n
111 - o
112 - p
113 - q
114 - r
115 - s
116 - t
117 - u
118 - v
119 - w
120 - x
121 - y
122 - z
123 - {
124 - |
125 - }
126 - ~
127 - ⌂
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 -
р
с
т
у
ф
х
ц
ч
ш
щ
ъ
ы
ь
э
ю
я
240 - Ё
241 - ё
242 - Є
243 - є
244 - Ї
245 - ї
246 - Ў
247 - ў
248 - °
249 - ∙
250 - ·
251 - √
252 - №
253 - ¤
254 - ■
255 -
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 -
а
б
в
г
д
е
ж
з
и
й
к
л
м
н
о
п
ГОСТ - альтернативная кодировка MS DOS
208 - ╨
209 - ╤
210 - ╥
211 - ╙
212 - ╘
213 - ╒
214 - ╓
215 - ╫
216 - ╪
217 - ┘
218 - ┌
219 - █
220 - ▄
221 - ▌
222 - ▐
223 - ▀
Кодировка Windows 1251
176 - °
177 - ±
178 - І
179 - і
180 - ґ
181 - µ
182 - ¶
183 - ·
184 - ё
185 - №
186 - є
187 - »
188 -ј
189 -Ѕ
190 -ѕ
191 -ї
Начало
i=1mes
Да
mes[i]=chr(ord
(mes[ i ])-64)
Да
mes[i]=chr(ord
(mes[ i ])-16
mes[i]=
'А'..'п'?
Нет
mes[i]=
'р'..'я'?
Нет
result=mes
Конец
192 - А
193 - Б
194 - В
195 - Г
196 - Д
197 - Е
198 - Ж
199 - З
200 - И
201 - Й
202 - К
203 - Л
204 - М
205 - Н
206 - О
207 - П
208 - Р
209 - С
210 - Т
211 - У
212 - Ф
213 - Х
214 - Ц
215 - Ч
216 - Ш
217 - Щ
218 - Ъ
219 - Ы
220 - Ь
221 - Э
222 - Ю
223 - Я
240 241 242 243 244 245 245 247 248 249 250 251 252 253 254 255 -
р
с
т
у
ф
х
х
ч
ш
щ
ъ
ы
ь
э
ю
я
Download