Массивы как параметры
Параметрами подпрограмм могут быть переменные не только простых, но и сложных типов, таких как массивы, записи, множества. Рассмотрим для иллюстрации пример с массивами.
Задача: Имеется два массива, по два числа в каждом. Напечатать сумму элементов каждого массива. Использовать функцию sum, единственным параметром которой является имя суммируемого массива.
Программа:
TYPE vector = array [1..2] of Integer;
VAR a,b : vector;
FUNCTION sum (c:vector):Integer;
BEGIN sum:=c[1]+c[2] END;
BEGIN
a[1]:=10; a[2]:=20;
b[1]:=40; b[2]:=50;
WriteLn (sum(a),' ',sum(b));
END.
Начиная вычислять функцию sum(a), Паскаль подставляет в ячейки для элементов массива c значения элементов массива a. Начиная же вычислять функцию sum(b), Паскаль подставляет в ячейки для элементов массива c значения элементов массива b.
В заголовке функции неправильно было бы писать
function sum (c: array [1..2] of Integer):Integer.
Необходимо было сначала определить тип массива в разделе TYPE, а затем использовать это определение и в описании a и b, и в заголовке функции. Таково требование синтаксиса Паскаля.
Параметры-значения и параметры-переменные
Многие процедуры не только рисуют или звучат, но и, подобно функциям, вычисляют что-нибудь полезное. Например, процедура B из следующей программы увеличивает глобальную переменную x на значение параметра y.
VAR x: Integer;
PROCEDURE B (y:Integer);
BEGIN x:=x+y END;
BEGIN
x:=1000;
B(1);
WriteLn(x)
END.
Будет напечатано число 1001.
Однако руководители проектов не любят, когда в подпрограммах встречаются имена глобальных переменных. Мало ли - руководителю придет в голову изменить имя глобальной переменной, и что тогда - переписывать все подпрограммы? Поэтому придумали использовать так называемые параметры-переменные. Вот та же программа с их использованием:
VAR x: Integer;
PROCEDURE B (y:Integer; var c:Integer);
BEGIN c:=c+y END;
BEGIN
x:=1000;
B(1, x);
WriteLn(x)
END.
Здесь y - хорошо знакомый нам параметр. Называется он параметр-значение. При начале выполнения подпрограммы для параметра-значения выделяется место в стеке и туда посылается значение соответствующего фактического параметра (1).
c - незнакомый нам параметр-переменная, отличающийся от параметра-значения словом var. При начале выполнения подпрограммы для параметра-переменной никакого места в стеке не выделяется, а выделяется в стеке место только для адреса соответствующего фактического параметра. Подпрограмма через этот адрес работает непосредственно с переменной, являющейся фактическим параметром (x). Получается, что слово var «снимает защиту» со своего фактического параметра и вы вполне можете нечаянно его испортить.
Вопрос: имеет ли смысл писать B(1, 1000)? Ответ: не имеет, так как подпрограмма не будет знать, какой переменной присваивать результат 1001. Естественно, Паскаль выдаст сообщение об ошибке.
Задания по теме «Процедуры и функции»
Задание 1
Что такое процедура? Что такое функция? В чём их отличие?
Перечислить несколько стандартных функций и процедур.
Задание 2
var x, y, z: real;
Вычислить z = sign( sign(x) + sign(y)), где
-1 приa<0
sign a 0 при a=0
1 при a>0
При решении этой задачи:
не использовать функцию sign;
определить и использовать функцию sign
Задание 3
Даны 3 квадратных уравнения Сколько из них имеют вещественные корни? Определить функцию, позволяющую распознать наличие вещественных корней в квадратном уравнении.
Задание 4
Найти все трехзначные простые числа. Определить функцию, позволяющую распознать простое число.
Задание 5 (дополнительно)
Написать программу, которая выводит на экран меню.
3+3=?
3*3=?
3^3=?
33!=?
Выход
При выборе пункта меню программа производит соответствующее вычисления, печатает результат и возвращается в меню.
Вывод текста меню реализовать в виде процедуры.
Действия каждого пункта меню реализовать в виде процедуры.
Обработку выбора пунктов меню реализовать в виде функции. Возвращаемое значение — номер пункта меню.