Предыдущий раздел

Накопитель

Накопителем обычно называют переменную ("ячейку памяти"), где накапливается результат операции, которую надо произвести над всеми элементами некоторой последовательности однотипных данных (это может быть массив, или упорядоченный список, или записи файла, и т.д.). Эта операция должна быть такова, что ее можно выполнить, перебирая все эти данные последовательно.

Простейшим примером такой операции является суммирование конечной последовательности чисел:

  Задача 1. Вычислить сумму элементов числового массива.

Решение. Пусть массив
 

 
уже дан и содержит какие-то числа. Надо сложить все эти 6 чисел. Это можно, например, сделать так:
 

 
Но понятно, что такой подход затруднителен для суммирования массива из 20 – 30 чисел, и уж совершенно непригоден для массивов, состоящих из сотен элементов. А как поступить, если мы обрабатываем записи, пусть даже короткого, файла, когда в каждый момент времени доступна лишь одна запись, а количество записей заранее не известно?

Попробуем другой способ. Вместо того, чтобы сложить все числа сразу, будем прибавлять их одно за другим… К чему? Вот как раз для этого и служит накопитель! Заведем переменные
 

 
и напишем фрагмент программы:
 

Попробуем мысленно выполнить программу за Pascal, и сразу же, при первом проходе цикла, обнаружим ошибку. В строке, помеченной {!!!}, неизвестно, к какому значению sum мы прибавляем mas[1]. Чему должна быть равна сумма, пока мы еще ничего к ней не прибавили? По-видимому, нулю. Внесем необходимые исправления:
 

Такое первоначальное задание значения – характерная черта использования накопителей. Можно сформулировать
Правило. Перед использованием накопителя его надо инициализировать, т.е. придать ему значение, которое он естественно должен иметь до начала обработки данных.

Мы уже отмечали, что накопитель используется не обязательно для вычисления суммы чисел. Можно накапливать в нем произведение чисел (и тогда инициализировать его значением 1 !). Можно решить и такую задачу:

  Задача 2. В файле, ассоциированном с файловой переменной
 

 
содержится заранее неизвестное количество целых чисел. Выяснить, все ли они положительны.

Решение 1. Нам надо вычислить значение логического выражения
 
(1-е число положительно) и (2-е число положительно) и ...
... и (n-е число положительно)
,
 
причем количество n проверяемых чисел заранее неизвестно. Заведем накопитель логического типа AllPositive и переменную x, в которую будем считывать числа из файла одно за другим.

Алгоритм решения строим следующим образом.
 
{В цикле, пока не будет обнаружен конец файла}    
  {Читаем в переменную x очередное число из файла}
  {Учитывая его знак, изменяем значение накопителя
   AllPositive}                                   

Прежде, чем реализовать этот алгоритм, дополним недостающее:
   1) надо объяснить Pascal’ю, что {будем читать файл с начала};
   2) логический накопитель надо инициализирвать значением TRUE. Почему? С одной стороны, можно сослаться на формально-логическое правило, что про элементы пустого множества объектов (в данном случае, множества чисел, проверенных до начала просмотра файла) любое утверждение истинно. С другой стороны, выбрать правильное из двух возможных начальных значений можно наугад, с последующей проверкой правильности работы программы выполнением ее мысленно или под отладчиком.

Наконец, можно приступить к реализации алгоритма. Переменные:
 

Фрагмент программы будет иметь вид:
 

После выполнения этого фрагмента AllPositive = TRUE означает, что все числа в файле положительны, а AllPositive = FALSE – что среди них есть нули или отрицательные.

Усовершенствование программы. Это касается только лишь этого примера и не имеет отношения к обсуждению понятия накопителя. Если уже обнаружено неположительное число, то отрицательный ответ на заданный вопрос уже известен, и не надо проверять другие числа. Поэтому выполнение цикла надо досрочно прекратить:

Решение 2.
 

В этом решении идея накопителя оказалась стертой – осталась инициализация накопителя, но изменение его значения происходит только при необходимости (Вы можете проверить, выполняя мысленно обе программы, что значение накопителя изменяется в них одинаково). Тем не менее, сама идея накопителя оказалась нам полезной для того, чтобы найти первое решение задачи. Уже после этого можно задуматься об усовершенствованиях алгоритма.

  Задача 3. Написать функцию, которой так не хватает в языке Pascal -
 
FUNCTION Power(x:REAL; n:INTEGER):REAL;
 
вычисляющую значение для положительного x и целого n.

Можно просмотреть 2 варианта решения этой задачи.

  Еще одна, стандартная,
  Задача 4. Написать функцию
 
FUNCTION Factorial(n:WORD):REAL;
 
вычисляющую факториал n! = 1·2·…·n неотрицательного целого n.

После того, как мы уже получили значительный опыт конструирования алгоритмов с использованием накопителя, для этой задачи можно без особых комментариев просто привести готовый ответ.

Следующий раздел