-6A82E~1
.PDF31
7. ПРОГРАММИРОВАНИЕ АЛГОРИТМОВ С ИСПОЛЬЗОВАНИЕМ ЗАПИСЕЙ
7.1 Описание записей
Запись (record) – это структура данных, состоящая из фиксированного числа элементов; в одном поле данные имеют один и тот же тип, а в разных полях могут иметь разные типы.
Общий вид описания записи следующий:
var имя_записи : record
список_элементов_1 : тип_1; {Поле 1} список_элементов_2 : тип_2; {Поле 2}
. . .
список_элементов_n : тип_n; {Поле n}
end;
Другой способ:
type имя_типа = record
список_элементов_1 : тип_1; {Поле 1} список_элементов_2 : тип_2; {Поле 2}
. . .
список_элементов_n : тип_n; {Поле n}
end;
var имя_записи : имя_типа;
Здесь список_элементов - перечень имен элементов через запятую; тип_1, тип_2,..., тип_n - типы полей.
Пример 1. Известно, что в Турбо-Паскале нет комплексных чисел. Однако данные комплексного типа можно описать переменной типа record:
var C:record Re,Im:real
end;
или
var C:record Re:real; Im:real;
end;
или
type Complex=record Re,Im:real
end;
var C:Complex;
32
Здесь Re, Im – соответственно действительная и мнимая части комплексного числа.
Обращение к элементу записи выполняется с помощью составного уточненного имени. Общий вид составного имени такой:
имя_записи . имя_элемента
Например,
C . Re , C . Im
Элемент записи используется в программе так же, как и обычная переменная, т.е. элемент записи можно указывать как в левой части оператора присваивания, так и в правой его части (в выражениях). Над элементов записи можно выполнять любые действия, допустимые для данных его типа. Обращение к записи в целом, а не только к ее элементам допускается лишь в операторе присваивания вида
S1:=S2;
где S1, S2 - записи с идентичной структурой.
Записи, как и массивы, могут быть упакованными. Запись может быть элементом других структур. Например, можно построить массив записей.
Пример 2. Пусть необходимо описать массив комплексных чисел
type Complex=record Re, Im: real;
end;
var C:array[1..10] of Complex; Ch:Complex;
Тогда для присваивания второму элементу массива C значения Ch = 2 + 5i можно использовать следующие операторы:
C[2].Re:=2;
C[2].Im:=5; или C[2]:=Ch;
Кроме переменных типа record, Турбо-Паскаль позволяет определять типизованные константы типа record:
type Zap=record x,y : real;
end;
const Z : Zap=(x:2.0;y:1.5);
33
7.2Оператор присоединения with
Вслучае использования вложенных записей при обращении к их отдельным элементам могут получаться очень длинные составные имена. Для сокращения записи составных имен используется оператор with, который имеет следующий вид:
with имя_записи do оператор;
Здесь имя_записи - простое или составное имя записи; оператор - простой или составной оператор, в котором при ссылках на элементы записи имя_записи можно опускать. При этом данный оператор недолжен изменять переменную указанную в имени записи.
Эффективность применения оператора присоединения with рассмотрим на следующем примере:
Составить программу для вычисления среднего балла группы студентов (20 человек) за сессию (5 экзаменов).
1 вариант (без оператора with) Program PR1;
Type student=record fio:string[20]; bal:array[1..5] of integer; sr:real
end;
Var grup:array[1..20] of student; i,j:integer;
Begin
For i:=1 to 20 do begin Write('FIO ',i,'-go student '); Readln(grup[i].fio); Writeln('Ball ',i,'-go student '); For j:=1 to 5 do begin Write(j, 'examen '); Readln(grup[i].bal[j]);
grup[i].sr:=grup[i].sr+grup[i].bal[j];
end;
grup[i].sr:=grup[i].sr/5;
Writeln('Sredni ball studenta ',grup[i].fio,' = ',grup[i].sr:3:3); end;
End.
2 вариант (с оператора with) Program PR1;
Type student=record fio:string[20];
34
bal:array[1..5] of integer; sr:real
end;
Var grup:array[1..20] of student; i,j:integer;
Begin
For i:=1 to 20 do With grup[i] do begin
Write('FIO ',i,'-go student '); Readln(fio);
Writeln('Ball ',i,'-go student '); For j:=1 to 5 do begin Write(j, 'examen '); Readln(bal[j]);
sr:=sr+bal[j];
end;
sr:=sr/5;
Writeln('Sredni ball studenta ',fio,' = ',sr:3:3); end;
End.
Применение одного раза With grup[i] сколько раз позволило сократить написание grup[i]. ?
Program PR1; |
Program PR1; |
Type student=record |
Type student=record |
fio:string[20]; |
fio:string[20]; |
bal:array[1..5] of integer; |
bal:array[1..5] of integer; |
sr:real |
sr:real |
end; |
end; |
Var grup:array[1..20] of student; |
Var grup:array[1..20] of student; |
i,j:integer; |
i,j:integer; |
Begin |
Begin |
For i:=1 to 20 do begin |
For i:=1 to 20 do |
Write('FIO ',i,'-go student '); |
With grup[i] do begin |
Readln(grup[i].fio); |
Write('FIO ',i,'-go student '); |
Writeln('Ball ',i,'-go student '); |
Readln(fio); |
For j:=1 to 5 do begin |
Writeln('Ball ',i,'-go student '); |
Write(j, 'examen '); |
For j:=1 to 5 do begin |
Readln(grup[i].bal[j]); |
Write(j, 'examen '); |
grup[i].sr:=grup[i].sr+grup[i].bal[j]; |
Readln(bal[j]); |
end; |
sr:=sr+bal[j]; |
grup[i].sr:=grup[i].sr/5; |
end; |
Writeln('Sredni ball studenta ',grup[i].fio,' = ',grup[i].sr:3:3); |
sr:=sr/5; |
end; |
Writeln('Sredni ball studenta ',fio,' = ',sr:3:3); |
End. |
end; |
|
End. |
|
|
35
8 ОРГАНИЗАЦИЯ ПОДПРОГРАММ ПОЛЬЗОВАТЕЛЯ
8.1 Общие сведения
Часто в программе обнаруживаются однотипные участки, которые выполняют одни и те же вычисления, но с различными данными. Такие части программ целесообразно оформлять в виде подпрограмм. Использование подпрограмм позволяет:
1)сделать основную программу более наглядной и компактной;
2)уменьшить объем используемой памяти ЭВМ;
3)сократить время отладки, так как программирование и отладку основной программы и подпрограммы могут осуществлять параллельно разные программисты.
В Турбо-Паскале выделяют два вида подпрограмм: процедуры и функции. Текст процедуры или функции может быть размещен в основной программе одним из следующих способов:
1)расположен непосредственно в разделе описаний основной програм-
мы;
2)записан в отдельный файл и вставлен в раздел описаний основной программы с помощью директивы компилятора {$I имя_файла};
3)оформлен в виде внешнего модуля.
8.2 Подпрограммы процедуры
Описание процедуры имеет вид
Procedure имя_процедуры (формальные параметры);
раздел описаний
Begin
раздел операторов
End;
и помещается в основной программе ( Program ) в разделе описаний. Формальные параметры - представляют собой список переменных с ука-
занием их типа, которые отделяются друг от друга точкой с запятой. Эти переменные не описываются в разделе описаний процедур.
Допускается использование процедур без списка формальных парамет-
ров.
Параметры процедур могут быть:
1)параметры-значения (входные параметры);
2)параметры-переменные (выходные параметры).
36
Описание входных параметров процедуры в списке формальных параметров имеет вид:
Procedure имя_процедуры (список_переменных_1:тип_1; список_переменных_2:тип_2; ...);
Соответственно описание выходных параметров выглядит так:
Procedure имя_процедуры (var список_переменных_1:тип_1; var список_переменных_2:тип_2; ...);
В Турбо-Паскале допускается так же использование нетипизованных выходных параметров.
Вызов процедуру в основной программе производится оператором вида
имя_процедуры ( фактические параметры );
Здесь параметры представляют собой список фактических параметров, перечисленных через запятую (без указания их типа). Между формальными и фактическими параметрами должно быть соответствие по количеству параметров, порядку их следования и типу данных. Имена соответствующих параметров могут быть одинаковыми или разными.
Входными фактическими параметрами, т.е. теми, которые передаются в процедуру, могут быть константы, переменные и выражения.
Выходными фактическими параметрами (которые получают значения из процедуры) могут быть только переменные. В качестве выходного параметра запрещается использовать любую переменную, имеющую упакованный тип. Значение формального входного параметра может изменяться в самой процедуре, однако никакого влияния на значение фактического входного параметра это не оказывает.
При использовании в качестве параметров процедур данных сложного типа (массивы, множества, записи) в основной программе необходимо предварительно описать имя типа этих данных, которые потом указываются в списке формальных параметров процедуры.
Пример 1. Пусть необходимо составить процедуру, которая перемножает две квадратные матрицы A и B, а результат заносит в матрицу C.
Program PR;
Type Matr=array[1..10,1..10] of real; Var a,b,c:Matr;
i,j,n:integer;
37
Procedure Malt_M(n:integer; m1,m2:Matr; var m:Matr); Var i,j,k:integer;
Begin
for i:=1 to n do for k:=1 to n do m[i,k]:=0; for i:=1 to n do
for k:=1 to n do
for j:=1 to n do m[i,k]:=m[i,k]+m1[i,j]*m2[j,k]; End;
BEGIN
writeln(' Введите размер - N ?'); read(n);
writeln(' Введите матрицу A'); for i:=1 to n do
for j:=1 to n do read(a[i,j]); writeln(' Введите матрицу B'); for i:=1 to n do
for j:=1 to n do read(b[i,j]); Malt_M(n,a,b,c);
writeln(' Матрица C'); for i:=1 to n do begin
for j:=1 to n do write(' ',c[i,j]:5:1); writeln;
end;
END.
8.3 Подпрограммы функции
Другой вид подпрограммы в языке Турбо-Паскаль - функция - оформляется аналогично процедуре и отличается от нее по структуре только заголовком, общий вид которого такой:
Function имя_функции(формальные параметры) : тип;
раздел описаний
Begin
раздел операторов, среди которых должен быть оператор
имя_функции:=имя_переменной или выражение
End;
Другие отличительные особенности функции следующие:
1) функция имеет только один результат выполнения (но может иметь несколько входных параметров);
38
2)результат обозначается именем функции. Поэтому в разделе операторов функции обязательно должен присутствовать оператор присваивания, в левой части которого стоит имя этой функции;
3)в заголовке функции обязательно должен быть указан тип функции;
4)вызов функции в основной программе осуществляется непосредственно внутри выражения по ее имени с указанием фактических параметров.
N
Пример 2. Оформим подпрограмму вычисления суммы i в виде функ-
i 1
ции:
function Sum(N:integer):integer; var s,i:integer;
Begin
S:=0;
for i:=1 to N do s:=s+i; Sum:=s;
End;
Тогда в основной программе можно использовать следующий оператор:
x:=Sum(10);
10
который присваивает переменной x значение i
i 1
8.4 Область действия переменных
Переменные, представленные в разделе описания основной программы (program), действуют в разделе операторов основной программы и в любой ее подпрограмме (procedure и function). Эти переменные называются глобальными. Переменные, описанные в подпрограмме, действуют только в этой подпрограмме и в любой объявленной в ней процедуре и функции. Такие переменные называются локальными. Они недоступны для операторов основной программы и других подпрограмм.
Напомним, что каждый модуль (процедура, функция, программа) состоит из заголовка, содержащего соответственно ключевое слово Procedure,
Function, Program, и блока.
При написании программ, имеющих вложенные модули, необходимо придерживаться следующих правил:
1)описывать имена переменных в том блоке, где они используются, если это возможно;
2)если одна и та же переменная используется в двух и более блоках, то описывать ее необходимо в самом внешнем из них, содержащем все остальные блоки, которые используют данную переменную;
39
3)если переменная, используемая в процедуре, должна сохранить свое значения до следующего вызова этой процедуры, то такую переменную надо описать только во внешнем блоке, содержащем данную процедуру;
4)в Турбо-Паскале каждый вызываемый модуль должен быть описан до его вызова;
5)в Турбо-Паскале в одном модуле может быть описано не более 512 процедур или функций.
8.5 Описание алгоритмов и программ
Описание алгоритма и программы для задачи №1
Программа
Program Lab7_T1;{Familii}
Type func=function(x:integer):real; Var S1,S2:real; n1,m1,n2,m2:integer;
r:text;
{$F+}
Function f1(x:integer):real; Begin
f1:=5/(1+x*x);
End;
Function f2(x:integer):real; Begin f2:=5/(1+ln(x)/ln(10));
End;
{$F-}
Procedure Sum(n,m:integer;f:func;Var S:real);
Var x:integer;
Begin
S:=0;
For x:=n to m do S:=S+f(x);
End;
Begin
Assign(r,'res7-t1');Rewrite(r);
Writeln('n1,m1=');Readln(n1,m1);
Sum(n1,m1,f1,S1);
Writeln(r,'S1=',S1:8:5);
Writeln('n2,m2=');Readln(n2,m2);
Sum(n2,m2,f2,S2);
Writeln(r,'S2=',S2:8:5);
Close(r);
End.
Для решения поставленной задачи: «Составить схему алгоритма и про-
m
грамму для вычисления циклической суммы f (x) , когда вид функции заранее
x n
40
неизвестен. Вычислить значения сумм |
20 |
5 |
и |
50 |
|
5 |
, результат записать в |
|
|
|
|
|
|||
|
x 10 |
1 x2 |
|
x 51 |
lg(x) |
|
|
файл,» – была написана программа Lab7_T1. В начале программы объявлены
Пользовательский тип
func – подпрограмма-функция действительного типа от одной переменной x целого типа, предназначена для описания суммируемых функций.
Глобальные переменные
S1, S2 – действительного типа, для хранения значения первой ( 20 |
5 |
) и вто- |
||
|
||||
50 |
|
x 10 1 x2 |
|
|
5 |
|
|
|
|
рой ( |
|
) суммы соответственно; |
|
|
1 lg(x) |
|
|||
x 5 |
|
|||
n1, m1, n2, m2 – целого типа, для хранения нижнего и верхнего пределов первой и второй суммы соответственно;
r – файловая переменная текстового типа, предназначена для организации работы с текстовым файлом, в котором будет хранится результат работы программы.
Далее в программе описаны пользовательские подпрограммы.
f1 – подпрограмма-функция действительного типа, предназначена для задания первой суммируемой функции. Имеет
формальный входной параметр
x – целого типа, принимает значение аргумента функции.
В подпрограмме задается первая суммируемая функция f1:=5/(1+x*x).
f2 – подпрограмма-функция действительного типа, предназначена для задания второй суммируемой функции. Имеет
формальный входной параметр
x – целого типа, принимает значение аргумента функции.
В подпрограмме задается вторая суммируемая функция f2:=5/(1+ln(x)/ln(10)). Sum – подпрограмма-процедура, предназначена для вычисления циклической
m
суммы вида f (x) . Имеет формальные параметры
x n
входные
n, m – целого типа, принимают значения нижнего и верхнего пределов суммы; f – типа func, принимает суммируемую функцию;
выходной
S – действительного типа, передает вычисленное значение суммы.
Вподпрограмме объявлена локальная переменная
x – целого типа, выступает в качестве управляющего параметра цикла и значения аргумента функции.
Вначале процедуры инициализируем карман для циклической суммы S:=0. Затем в цикле For по x от n до m совершаем циклическое суммирование
S:=S+f(x).
В начале головной программы связываем имя файловой переменной r с именем файла на диске 'res7-t1'. Открываем файл для записи. Запрашиваем
