
6.5.2 Параметры – переменные.
При передаче параметров – переменных в подпрограмму фактически через стек передаются их адреса в порядке, объявленном в заголовке подпрограммы. Следовательно, подпрограмма имеет доступ к этим параметрам и может изменять их значения. Механизм передачи параметра по ссылке состоит в следующем:
1. Параметр – переменная указывается в заголовке подпрограммы аналогично параметру – значению, но только перед именем параметра записывается зарезервированное слово var. Действие слова var распространяется до ближайшей точки с запятой, т.е. в пределах одной группы переменных. Например,
procedure T1(var X, Y : real; I, J : integer);
где X, Y – параметры – переменные, а I, J – параметры – значения.
2. При обращении к подпрограмме происходит передача формальному параметру – переменой адреса фактического параметра, а не его значения. При всяком упоминании в подпрограмме параметра, переданного по ссылке, компилятор будет использовать область памяти, отведенную для аргумента из главной программы. Таким образом, всякое изменение в значении формального параметра фактически будет и изменением в значении соответствующего аргумента.
3. Фактический параметр основной программы, соответствующий формальному параметру – переменной, может быть только переменой, но не константой или выражением. Тип параметров – переменных может быть любым, включая и файловый. При вызове подпрограммы на месте параметра – пере–менной в качестве фактического параметра должна использоваться переменная идентичного типа.
Вывод: с помощью параметров – переменных данные можно передавать как из программы в процедуру, так и обратно; таким образом параметры – значения могут быть только входными, а параметры – переменные – входными и выходными.
Пример оформления процедуры.
procedure SUMMA (A, B : real; var Y, Z : real);
const N=5;
var i : integer;
begin for i:= 1 to N do
begin Y:= A+B*i;
Z:= 4*Y–i
end
end;
В описанной процедуре A и B – входные параметры (параметры – значения); они получают свои значения из основной программы. Результаты работы процедуры – выходные параметры Y и Z (параметры – переменные) передаются в основную программу и могут быть там использованы.
Из основной программы описанную процедуру можно вызвать следующим образом:
SUMMA(3.5, 7.6, Y1, Z1);
Это означает, что формальным параметрам A и B будут присвоены значения 3.5 и 7.6 соответственно, а в переменные Y1 и Z1 (фактические параметры) будут переданы результаты работы процедуры (Y, Z соответственно).
Задача 1. Описать процедуру МХ_MN, которая присваивает параметру X большее из вещественных чисел x и y, а параметру Y – меньшее.
procedure MX_MN (var X,Y : real);
var r : real; {промежуточная переменная для обмена данными между
ячейками X и Y}
begin
if X<Y then begin r := X;
X := Y;
Y := r
end
end;
В описанной процедуре формальные параметры X, Y, переданные по ссылке, являются и входными и выходными параметрами одновременно.
Задача2. Определить, что будет напечатано в результате выполнения программы:
program PRIM;
var k: integer;
procedure PLUS1(N : integer);
begin N:= N+10 end;
procedure PLUS2(var N : integer);
begin N:= N+10 end;
{основная программа}
begin
k:= 0; PLUS1(k); Writeln(k);
k:= 0; PLUS2(k); Writeln(k)
end.
Процедура PLUS1 имеет один формальный параметр N (входной параметр, параметр – значение). При вызове процедуры PLUS1 фактический параметр k сопоставляется с формальным параметром N. Таким образом, значением N становится число 0. Внутри процедуры значение N увеличивается на 10 и становится равным 10. Выполнение процедуры закончено. Так как в данном случае используется механизм передачи параметра по значению, то изменение формального параметра не приводит к изменению фактического, т.е. в основной программе печатается значение переменной k, равное 0.
Процедура PLUS2 имеет один формальный параметр N (параметр – переменная), который является входным и выходным одновременно. При вызове процедуры PLUS2 выполняются действия, аналогичные действиям в процедуре PLUS1. Но так как в этом случае используется механизм передачи параметра по ссылке, то в ячейку N засылается адрес ячейки k. Выполнение оператора N:= N+10 в процедуре PLUS2 имеет следующий смысл: взять число из ячейки k, адрес которой хранится в переменной N, прибавить 10 и заслать в ту же ячейку k. Таким образом, все изменения, происходящие с формальным параметром N, одновременно приводят к изменению фактического параметра k. В результате выполнения процедуры PLUS2 формальный параметр N получит значение 10 и в основной программе будет напечатано значение переменной k, равное 10.
Задача 3. Определить, что будет напечатано в результате выполнения программы:
program PRIM1;
var A, B, C, D : integer;
procedure P(var B : integer; C : integer);
var D : integer;
begin A:= 5; B:= 6; C:= 7; D:=8;
Writeln(A, B, C, D)
end;
begin A:= 1; B:= 2; C:= 3; D:= 4;
P(A, B); Writeln(A, B, C, D)
end.
Описанным в основной программе глобальным переменным A, B, C, D присваиваются соответствующие значения 1, 2, 3, 4. При обращении к процедуре P значение фактического параметра A основной программы передается по ссылке формальному параметру B подпрограммы, а значение фактического параметра B основной программы – формальному параметру C процедуры по значению. Таким образом, все изменения, происходящие в процедуре с формальным параметром B, одновременно изменят и значение глобальной переменной A. Все же изменения, происходящие с формальным параметром C процедуры, никак не отразятся на глобальной переменной B, с которой она связана.
В теле процедуры глобальной переменной A присваивается значение 5. Формальному параметру B присваивается 6, а так он связан по ссылке с глобальной переменной A, то в ячейку A так же засылается значение 6. Формальному параметру C присваивается значение 7. Локальной переменной D присваивается значение 8. В теле процедуры печатается значение A, B, C, D соответственно 6, 6, 7, 8. Выполнение процедуры закончено. В основной программе печатаются значения глобальных переменных A, B, C, D соответственно 6, 2, 3, 4.
Задача 4. Найдите целые числа-палиндромы, которые при возведении в квадрат тоже дают палиндромы.
program prim5;
var i,i1,i2:longint;
function Palindrom(n:longint):boolean;
var n1,n2,r:longint;
begin n1:=n;n2:=0; {n1 – остаток числа, n2 – формируемое число}
while n1>0 do
begin r:=n1 mod 10;{очередная цифра формируемого числа }
n1:=n1 div 10;
n2:=n2*10+r;
end;
Palindrom:=(n=n2);
end;
{основная программа}
begin writeln('введите границы чисел:');
write(' нижняя граница:');readln(i1);
write(' верхняя граница:');readln(i2);
for i:=i1 to i2 do
if Palindrom(i) and Palindrom(sqr(i))
then writeln(i,'-палиндром ',sqr(i),'-палиндром');
end.
Задача 5. Даны координаты вершин треугольника и координаты некоторой точки внутри него. Найти расстояние от данной точки до ближайшей стороны треугольника.
program treug;
uses crt;
var
x1,x2,x3,x4,y1,y2,y3,y4:real;
min,h1,h2,h3:real;
function dlina(u11,v11,u22,v22:real):real;
begin
dlina:=sqrt(sqr(u22-u11)+sqr(v22-v11));
end;
procedure Visota(u1,v1,u2,v2:real;var h:real);
var
x,y,z,p,s:real;
begin
x:=dlina(u1,v1,u2,v2);
y:=dlina(u1,v1,x4,y4);
z:=dlina(u2,v2,x4,y4);
p:=(x+y+z)/2; s:=sqrt(p*(p-x)*(p-y)*(p-z));
h:=s/x;
end;
begin
clrscr;
writeln('Введите координаты вершин треугольника x1,y1,x2,y2,x3,y3');
Readln(x1,y1,x2,y2,x3,y3);
Writeln(' Введите координаты точки x4,y4'); Readln(x4,y4);
Visota(x1,y1,x2,y2,h1);
Visota(x1,y1,x3,y3,h2);
Visota(x2,y2,x3,y3,h3);
if h1<h2 then min:=h1 else min:=h2;
if min>h3 then min:=h3;
Writeln(' Наименьшее расстояние до сторон треугольника равно ',min:6:2)
end.
Задача 6. В заданной матрице А(5,5) определить строку с максимальной суммой абсолютных величин её членов.
program matrica;
uses crt;
const n=5;m=5;
type
mass=array[1..n] of integer;
matr=array[1..m] of mass;
var A:matr;
i,j:byte;
max_s, n_max:integer;
function sum(var M:mass):integer;
var
k:byte;
s:integer;
begin
s:=0;
for k:=1 to n do
s:=s+abs(m[k]); sum:=s;
end;
begin
clrscr;
{vvod matrici A}
randomize; Writeln('Matrica A');
for i:=1 to m do
begin
for j:=1 to n do
begin
A[i,j]:=random(100)-30;
Write(A[i,j]:5);
end;
writeln;
end;
max_s:=sum(a[1]); n_max:=1;
for j:=2 to m do
if max_s<sum(A[j]) then begin max_s:=sum(A[j]); n_max:=j end;
Writeln(' Max_сумма в строке = ',max_s, ' её номер ',n_max)
end.
Задача 7 . С помощью функции, определяющей большее из двух чисел, расположить числа a, b, c в порядке убывания.
program poisk_naib;
uses crt;
var a,b,c,d:integer;
procedure max_2(var x,y:integer);
var z:integer;
begin
if x<y then begin z:=x; x:=y; y:=z end
end;
begin
clrscr;
Writeln('Введите четыре числа :');
Readln(a,b,c,d);
max_2(a,b); max_2(c,d);max_2(a,c);max_2(b,d);max_2(b,c);
Writeln('Числа в порядке убывания');
writeln(a:3,b:3,c,:3,d:3);
end.
Задача 8. Дан список имен мужчин и женщин с указанием пола (M или W) и роста (от 140см до 200см ). Составить программу, выдающую имя и рост самого высокого мужчины из списка.
program M_and_W;
type
name = (SVETA, KOLYA, IVAN, MASHA, SASHA, PETR, NINA);
pol = (M, W);
var
rost : array [name] of 140..200;
i, imya : name; max : integer;
const
p : array [name] of pol = (W, M, M, W, M, M, W);
procedure W_NAME(j:name);
begin
case j of
SVETA : Writeln('СВЕТА');
KOLYA : Writeln('КОЛЯ');
IVAN : Writeln('ИВАН');
MASHA : Writeln('МАША');
SASHA : Writeln('САША');
PETR : Writeln('ПЕТР');
NINA : Writeln('НИНА')
end
end;
begin
for i := SVETA to NINA do
begin
Write('Очередное имя списка: ');
W_NAME(i);
Write('Введите рост '); Readln(rost[i])
end;
max:=140;
for i := SVETA to NINA do
if (p[i]=M) and (rost[i]>max) then
begin
max:= rost[i]; imya:= i
end;
Writeln('Самый высокий мужчина – ');
W_NAME(imya);
Writeln(' его рост – ', max)
end.
Задача 9. Определить количество сверхпростых чисел в интервале от 1 до m.
Сверхпростым называется число, если оно простое, и число, полученное из исходного числа при записи цифр исходного числа в обратном порядке ("перевертыш"), тоже будет простым. Например, 13 и 31 — сверхпростые числа.
program super_prost;
uses crt;
var x, k, m : integer; { описание глобальных переменных x, k, m }
{ функция проверки числа х на простое число }
function prost(y: integer): boolean;
var i: integer; { описание локальных переменных i, flag }
flag: boolean;
begin
flag:=true; i:=2;
While (i<=int (y/2)) and flag do
if у mod i=0 then flag:=false;
prost:=flag;
.{ нашли простое число, имеющее только два делителя: }
{ единицу и само это число }
end;
{ "перевертыш" простого числа }
function perevert(y:integer):integer;
var n1,n2,r:integer;
begin n1:=y;
n2:=0; {n1 – остаток числа, n2 – формируемое число}
while n1>0 do
begin r:=n1 mod 10;{очередная цифра формируемого числа }
n1:=n1 div 10;
n2:=n2*10+r;
end;
perevert:=n2;
end;
{ основная программа }
begin
writeln('введите верхнюю границу чисел:');
readln(m);
writeln('Сверхпростые числа':50);
k:=2; { 2 и 3 — простые числа }
for x:=4 to m do
if prost(x) then { вызов функции определения простого числа х }
{ вызов функции определения простого числа для "числа-перевертыша", }
{ полученного вычислением функции perevert(х) от простого числа }
if prost(perevert(x)) then
begin
writeln(x); { печать сверхпростого числа }
k:=k+l;
end;
writeln('всего найдено ',k,' сверхпростых чисел < ', n)
end.