
книги из ГПНТБ / Соловейчик, Р. Э. Программирование на АЛГОЛ-60 учеб. пособие
.pdfРассмотрим процедуру, выполняющую транспонирование мат рицы. Присвоим этой процедуре идентификатор , масси ву компонент транспонируемой квадратной матрицы - идентифика тор а , нижней и верхней границам индексов ее компонент - идентификаторы т и п соответственно. Тогда эта процедура может быть записана следующим образом:
procedure Trane (a,m,n)j array a , Integer |
m, гц |
t |
||
begin |
real p ; Integer |
i,k { |
|
|
|
for It я e step 1 |
until n do |
|
|
|
for k: я 1 .+ |
1 step 1 until n |
do |
|
|
begin p: = a [ i , |
k] t a [i»*J *яв |
[^»*]»8 |
[k»i]*=P |
|
end |
|
|
|
end |
|
|
|
|
К этой процедуре следует дать некоторые пояснения. Преж |
||||
де всего, |
транспонируемая матрица квадратная, i n k |
- целые |
переменные, вводимые для обозначения индексов элемента матри
цы, а р |
- вспомогательная вещественная переменная, |
исполь |
зуемая для выполнения процесса транспонирования. |
|
|
Если в программе, содержащей описание процедуры |
Irene , |
|
встретится массив, описанный следующим образом: |
|
array Ъ £l •: 10, I : lo j ^
то для транспонирования матрицы, отвечающей этому массиву, нужнонаписать следующее обращение к процедуре:
Trane ( ъ, 1 , ю ) .
Покажем использование этой процедуры на полной программе, вы числяющей матрицу
|
d = (а^ •* Ъ) * о® ~ Ь^ , |
|
|
где а,ъ,е |
и d - квадратные матрицы |
13-го |
порядка. Индексы |
компонент |
пронумерованы от 0 до 1 2 , а |
т |
обозначает опера- |
—71
цию транспонирования матрицы.
В этой программе мы познакомимся с возможностью поясне ний алголовского текста, которая состоит в том, что после точ ки с .запятой или слова begin можно написать слово сс— ent , затем любой поясняющий текст, оканчивающийся точкой с запятой.
На работу программы это не оказывает никакого влияния. Не |
|
||||||||||||||
смотря на искусственный характер этого цримера, он даст нам |
|
||||||||||||||
наглядное пояснение всего изложенного. |
|
|
|
|
|
||||||||||
Полная программа, вычисляющая матрицу |
д |
, с использо |
|||||||||||||
ванием процедуры транспонирования матриц будет следующей: |
|
|
|||||||||||||
begin real eua? |
Integer |
l.m .qt |
array |
a,b ,o,d |
[o« 1 2 ,0»I2j [ |
||||||||||
|
|
|
procedure |
5Tens |
( |
a , |
m, |
n |
|
|
|
||||
|
|
|
begin real |
pj |
integer |
l,k j |
|
|
|
||||||
|
|
|
|
|
fo r |
1 ; * |
m |
step 1 |
u n til |
n d£ |
|
|
|||
|
|
|
|
|
|
for |
k s»l*i |
step ц until n do |
|
|
|||||
|
|
begin |
pi»e |
£ i,k j} |
e[i,k ]»= .a jk ,ijj a [k,ij |
=»P |
|
||||||||
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ВВОД |
( a, |
b, |
о |
) i |
|
|
|
|
|
|
|
|
||
Trnnn tИ.0 .1 2 )! |
oomment |
|
место матрицы a |
заняла матрица aT |
i |
||||||||||
for .1» a 0 step 1 |
until |
12 |
do |
|
|
|
|
|
|
||||||
fo r |
m: a |
0 |
step |
1 |
until 12 |
do |
|
|
|
|
|
||||
,®| .=a[j,m j+b[j, ra); oomment найдена сумма матриц а |
и Ъ |
3' |
|||||||||||||
Trans (c 9 0 , 1 2 ); |
comment |
место матрицы |
о |
заняла матрица |
о1 |
: |
|||||||||
for j s |
=t 0 step 1 |
until |
12 |
do |
|
|
|
|
|
|
|||||
3 fo r |
m: = |
0 |
step |
1 |
|
until |
12 |
|
do |
|
|
|
|
|
|
begin sum 1 = О ; |
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
for q » =» 0 aten 1 |
until |
12 |
йД |
|
|
|
||||||||
|
sum» |
= sum |
* a £ j,q ] |
* |
0 |
[*’*] } |
|
|
|
||||||
|
d |
j'j,mj |
: |
- |
sum |
|
|
|
|
|
|
|
|
■— 72
|
|
end . |
окончено умножение матриц аТ + ь и |
оТ |
• |
||||||
Тгвпв(ъ,о,72) .comment |
место матрицы |
ъ заняла матрица |
ф |
||||||||
ъ i |
|||||||||||
for |
,1 : = |
О step |
1 |
until 1 2 |
do |
|
|
|
|||
|
for |
m* |
= |
O step 1 |
|
until 12 |
do |
|
|
|
|
d p |
,mj |
•= |
d £j,m j |
-b |
jV.mj; comment |
найдена матрица |
g |
; |
|||
|
|
|
печать |
(d) |
; |
|
|
|
|
||
|
end |
|
|
stop |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Необходимо |
отметить некоторые особенности этой програм |
мы. Прежде всего надо обратить внимание на то, что обозначение одного из фактических параметров совпадает с обозначением со ответствующего формального параметра. Выше уже указывалось на допустимость подобного, но мы еще раз хотим подчеркнуть, что это совершенно разные вели, а совпадают только их обозначе
ния. В нашем примере это формальный |
параметр а |
|
и массив |
||||||||||
компонент матрицы |
а |
. Кроме того, |
подчеркнем, |
что |
после |
||||||||
выполнения процедуры Trans |
( а . О, |
1 2 ) идентификатор |
а |
||||||||||
обозначает массив компонент транспонированной матрицы, т.е. |
|||||||||||||
матрицы |
m |
. Затем при нахождении суммы матриц |
а |
и |
ъ . |
||||||||
а |
|||||||||||||
этой сумме опять присваивается наименование |
а |
. Далее |
пос |
||||||||||
ле |
выполнения |
процедур |
Тгапв |
( е,0,12) и |
Trans |
|
( ъ>0.12) |
||||||
транспонированным матрицам с2 |
и |
|
присваиваются |
"старые" |
|||||||||
наименования, |
т.е. с |
и ъ . При нахождении |
произведения мат |
||||||||||
риц ят + ъ и |
|
мы присваиваем этому произведению наиме |
|||||||||||
нование |
d |
. Наконец, при нахождении разности матриц (а^+ъ)* |
|||||||||||
* с |
и |
ът |
|
мы снова присваиваем этому произведению |
|||||||||
наименование |
d |
. Нестандартное |
слово АЛГ01-60 |
stop |
, |
||||||||
стоящее |
перед заключительным |
end |
, означает |
остановку |
машины; оно может |
быть |
опущено без изменения работы програм |
|
мы. |
|
|
|
Приведем еще один |
подобный |
пример. Пусть патл нужно най |
|
ти'сумму площадей |
треугольников со сторонами, которые образо |
||
ваны из отрезков длинной а,ь,с |
и d . Для этого сконструи |
73 •'
руем процедуру, вычисляющую площадь треугольника по трем его сторонам, точнее, по длинам трех его сторон. Эту гггацедуру
построим на основании формулы Герона
где а,ь,с |
- длины сторон треугольника; |
Р - полупериметр |
Тогда для решения поставленной задачи, |
нам нужно будет |
четыре раза обратиться к этой процедуре, а затем сложить по лученные результаты. Программа, приводимая ниже," решает эту задачу; заметим что она не претендует на оптимальность,
begin re a l |
B ,b,e,d,aum 5 |
array |
Q |
: 4J |
- |
|
|
||||||||
|
procedure |
Г (x ,y ,z ,e ) |
{ |
Гба! |
x ,y ,z ,e |
; |
|
||||||||
|
|
begin real |
p |
; |
|
|
|
|
|
|
|
||||
|
|
|
|
pi = .5 * (x + у * z ) t |
|
|
|
||||||||
|
|
si |
=sqrt |
(p r(p - |
x) л |
(p - |
у) |
(p |
- |
z) ) |
|||||
end |
• |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ВВОД |
( a , b , c , d |
) ; |
|
|
|
|
|
|
|
|
|
|
|||
Г (a,b,c,Q |
JYJ |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
Г ( b , c , d , Q |
[ 2 ] ) |
|
|
|
|
|
|
|
|
|
|
|
|||
r ( c , d , a , Q [ 3 ] |
|
) |
|
|
|
|
|
|
|
|
|
|
|
||
Г ( d , a , b , Q [4 ] ) |
|
|
|
|
|
|
|
|
|
|
|
||||
sum: = Q M + |
Q |
[ 2] |
♦ |
Q |
[3 ] |
* |
Q |
H ; |
|
|
|
|
|||
печать |
( sum |
) f |
st°P |
|
|
|
|
|
|
|
|||||
end . |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Отметим только, что x,y |
и |
s |
- формальные параметры про |
||||||||||||
цедуры |
с идентификатором |
|
г |
, обозначающие длины |
сторон |
||||||||||
треугольника, |
а |
з |
- |
формальный |
параметр той же |
процедуры |
74
для обозначения результата процедуры, т.е. площади треуголь ника.
Подведем краткие итоги изложенных сведений о процедуре. |
|
Процедура в языке АЛГОЛ-60 задается своим описанием, которое |
|
состоит из символа provedага |
( заголовка процедуры и тела |
процедуры. Заголовок процедуры указывает идентификатор про |
|
цедура, список формальных параметров и порядок их следования; |
он служит связующим звеном между обращением к процедуре и те лом цроцедуры. В заголовке процедуры могут быть поставлены таи называемые спецификаторы формальных параметров. Их постановка
облегчает работу транслятора, и поэтому она обычно исполь |
||
зуется. |
|
|
3 качестве спецификаторов используются следующие слова |
||
АЛГОЛа. |
Integer |
, |
|
real , |
|
|
■Boolean |
, |
|
switch |
, |
|
string |
, |
real array. Integer array. Boolean array.
procedure, real prodadnre,
Integer prooadore. Boolean prooednre.
Следует отметить, что с внешней стороны спецификаторы
очень похожи на |
описания, но |
существенное отличие их от опи- г |
|
ramri» состоит в |
том, что для |
соответствующих переменных не |
[ |
предусматривается выделение ячеек в памяти машины, поэтому |
; |
||
есть и некоторые внешние отличия. |
|
||
Так, при спецификации идентификатора массива не указы- |
' |
ваготся границы изменения его индексов, а цри спецификации идентификатора переключателя не указывается массив его меток. Кроме того, есть еще одно условие. Если некоторая переменная
относится к разряду значений, т.е. ,то обязательно должен быть указан тип принимаемых ею значений; слово value должно ставиться перед спецификациями.
Примеры спецификаций
re a l х |
$ |
|
|
|
Integer |
|
к |
j |
|
Boolean |
|
F |
j |
|
a rra y |
e |
j |
|
|
mrltoh |
p o ly ; |
|
||
valne |
n; |
Integer. ' a |
; |
|
valne |
e ,y f |
a rra y a |
; re a l у ; |
|
Отметим, что во всех приведенных н а ш |
процедурах использова |
на спецификация. Обращение к процедуре является оператором, состоящим из идентификатора процедуры и списка фактических параметров, которые должны быть помещены в том не порядке, как соответствующие им формальные параметры. Тело процеду ры, вообще говоря, является блоком, но может быть составным оператором или дане простым оператором.
Процедура - функция
Остановимся на одном частном случае процедуры, когда в результате выполнения ее имеет место присвоение значения
только |
одной переменной. |
В |
этом случае обращение к процедуре может быть сущест |
венно упрощено оформлением этой процедуры как функции. Тог да написание названия этой процедуры с подстановкой факта-
76
ческих параметров не только вызовет обращение к ней, но те перь это есть само значение и оно может быть использовано везде, где оно написано. Поэтому тело процедуры-функции обяза тельно должно оканчиваться оператором, присваивающим ее иден тификатору значение.ответа. Таким образом, процедура представ ляет собой переменную с тем же названием. Подобные процедуры называются процедурами-функциями. Лля обозначения того факта, что используемая процедура является процедурой-функцией, пе
ред словом procedure |
должно стоять описание типа той пере |
|||||
менной, которую она представляет, т.е. |
:1-DtaS— |
или |
||||
Boolean |
. Например, |
разобранную выше процедуру нахож |
||||
дения большего корня квадратного уравнения можно оформить |
||||||
в виде процедуры-функции |
|
|
|
|
||
real |
procedure |
root |
(а,Ъ,с) |
real |
а,Ъ,с ; |
|
rooti |
= (-Ъ + |
sqrt |
(ът 2 ~ 4 |
* a |
X c)) (2 * a) |
• |
Подобное оформление особенно удобно в тех случаях, когда нуж но сразу же использовать полученный результат.
Если требуется найти больший корень уравнения Зх^-5х-12= =0, затем прибавить его к величине theta , все это возвы сить в квадрат и присвоить в качестве нового значения пере менной у , то этого можно добиться , написав
yi = (theta * root (3, -5,.-Х?))1'з ;
В качестве еще одного примера вернемся к рассмотрению вычис ления интеграча
Т |
dx |
I + |
х |
о |
|
по формуле Симпсона и напомним, что основным дефектом состав ленной программы являлось неоднократное написание вычислений значений подынтегральной Функции, особенно'неприятное в слу чае ее громоздкости.
В тассматрпваеыом примере вычисление подынтегрально!!
ФУНКЦИИ
I
1 ♦ X•1 б
77
можно оформить посредством следующей процедуры-функции:
real procedure F (х) j
Ps = 1 /(1 4.х tl6 ) f
и тогда полная программа, реализующая вычисление интеграла j0 , будет для улучшенного варианте следующей :
begin real |
|
а,Ъ,п,вип, h, x, Jo ; |
|
||||
real procedure |
|
F (x) |
; |
^ |
|||
? ! » 1 / ( H xf К ) I |
|
||||||
ВВОД |
(a,b,n |
) |
t |
|
|
|
|
h 1 » (b - a) / n f |
|
|
|||||
sum 1 a 0 .0 ; |
|
|
|
|
|
||
for |
is |
* a atep |
2 * |
h |
until Ъ - 2 |
x h do |
|
sum j |
• so* |
F(x) |
* |
4 x F(x * h)4 |
РСх+г"!!) { |
||
Jo:= |
h/3 * auB |
; |
|
|
|
||
печать |
(Jo) |
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
Обращение с подстановкой наименования и |
|||||||
|
|
значения |
|
|
|
|
Приведем еще один пример процедуры и на нем познакомим- |
||||
ся с некоторыми довольно |
тонкими особенностями языка АЛГ0Д-60. |
||||
|
Рассмотрим процедуру, которая выполняет суммирование об |
||||
щего вида |
I |
« |
|
|
|
|
а а |
|
|
||
|
|
1 яИ |
|
|
|
где |
подразумевается, |
что функция £ |
, подлежащая суммирова |
||
нию, |
зависит от индекса суммирования |
i . Црисвоим этой |
|||
процедуре наименование вив |
и напишем ее 'следующим образом: |
|
|
|
78 — |
procedure |
sum ( 8 ,i,m,n,f ) } |
||
begin s |
: = |
0 ; |
|
for 1 |
j = |
a step 1 _ until n do |
|
8 |
t =» в ♦ |
f |
|
end |
|
|
|
Предположим, что мы хотим использовать эту процедуру для вы
числения суммы 1 fn_1 \
i=n- 1
Это может быть сделано с помощью обращения к цроцедуре sum (h,l,n-l, n *(и-1 )-г 2 , 1 1 3) ,
в результате которого тело процедуры примет вид begin h I а О ;
for ii |
* |
n-1 , step 1 until n * (n -1 )+ 2 do |
h i = |
h + |
if 3 |
end
Так как в операторе цикла допускается возможность изменения • выражения, стоящего после QPtil ^ t в цроцессе вычисле
ния, то оно будет вычисляться на каждом шйге цикла. Однако в большинстве случаев (и в рассматриваемом примере тоже) эта величина бывает постоянной, и поэтому ее достаточно вычис лить всего один раз, перед входом в тело цроцедуры. Именно это и делается, когда производится обращение к цроцедуре с подстановкой значения параметра. В этом случае после списка формальных параметров в описании процедуры ставится слово
vslue |
, а |
за ним располагаются названия тех параметров, |
вместо которых |
подставляются соответствующие значения. Тог |
|
да для рассматриваемого нами случая процедура примет вид |
||
|
procedure |
sum (s,i,m,n,f); velue m,n; integer m,n; |
begin 8 • = 0 ;
for i » a m step 1 until n |
do |
|
в » * a + £ |
|
|
end |
|
|
Тогда при обращении к процедуре |
sum |
, выражения, являю |
щиеся фактическими параметрами, |
соответствующими формальным |
параметрам m и п , будут вычислены только один раз, до входа в тело процедуры, а использоваться они будут вплоть до окончания процедуры. Такой способ описания процедуры более экономен в работе, и его рекомендуется использовать по отно шению ко всем формальным параметрам, которые представляют со бой лишь одно значение.
" Приведем еще один пример процедуры с подстановкой значе ния. Рассмотрим приближенное решение обыкновенного дифференци ального уравнения первого порядка с помощью одного из вариан тов схемы Рунге-Кутта.
Итак, нужно составить процедуру для интегрирования диф
ференциального уравнения вида |
|
у' - * (*»у) |
' |
при начальном условии у = у0 |
при х з х0 . В более общей |
форме можно сказать, что нам известна точка интегральной кри
вой с координатами ( xif у* |
), а требуется найти точку на |
|||||
этой кривой, тлеющую абсциссу (х |
» х^ |
-f h . |
|
|||
По методу Рунге-Кутта- для определения |
у1+1 |
последо |
||||
вательно используем формулы: |
|
|
|
|
||
^ |
= hf(xi ,yi ) i |
|
|
|
|
|
k 2 |
= |
hf (x1 +!*3ri+| /1>s ' |
|
|
|
|
|
= |
hf (Xj^+I.yj^+I2) ; |
|
|
|
|
k^ |
= hf(xi+h,y+kj) , |
|
|
|
|
|
а искомую величину определяем по соотношению |
|
|||||
|
|
1 |
|
|
|
|
yi+1 |
= yi * 6 ^ + 2 k 2 |
♦ 2k3 4 |
Ч > • |
|
Процедура, реализующая эти |
вычисления, должна содержать па |
|
раметры х, у, h и функцию |
f , задающую правую часть .диф |
|
ференциального уравнения. Назовем эту процедуру нк |
она |