Пример 4. Работа с массивами
Пусть требуется написать программу для ввода массива x из 100 вещественных чисел и вычисления суммы всех элементов этого массива:
Сделаем естественное предположение, что длина нашей программы не будет превышать 199 ячеек, и поместим массив x, начиная с 200-ой ячейки памяти. Вещественную переменную S с начальным значением 0.0 и целую переменную n с начальным значением 100 поместим в конце текста программы (после команды СТОП), и будем вводить в память вместе с командами при нажатии кнопки ПУСК. Заметим, что так в программе сэкономили ячейку, в которой должна была бы хра-ниться команда обнуления переменной S. Таким образом, в качестве счётчика цикла будет удобнее использовать не целую переменную i, изменяющуюся от 1 до 100, как в приведённой выше формуле, а переменную n с начальным значением 100, которая будет изменяться от 100 до 1. Другими словами, мы реализуем цикл, который на Турбо-Паскале можно было бы записать в виде
const S:real=0.0; n:integer=100; i:integer=1;
. . .
repeat S := S + x[i]; i := i + 1; n := n - 1 until n = 0
Ниже приведён текст этой программы.
№ |
Команда |
Комментарий |
||||
001 |
ВВВ |
200 |
100 |
000 |
Read(x); массив xв ячейках 200÷299 |
|
2 |
СЛВ |
008 |
200 |
008 |
S := S+x[1] |
|
3 |
СЛЦ |
002 |
002 |
011 |
Модификация команды в ячейке 2 |
|
4 |
ВЧЦ |
010 |
010 |
009 |
n := n-1 |
|
5 |
ПБ |
000 |
002 |
000 |
if n>0 then goto 002 |
|
6 |
ВЫВ |
008 |
001 |
000 |
Write(S) |
|
7 |
СТОП |
000 |
000 |
000 |
Стоп |
|
8 |
00 |
000 |
000 |
000 |
Вешественная переменная S = 0.0 |
|
9 |
00 |
000 |
000 |
001 |
Целая константа 1 |
|
010 |
00 |
000 |
000 |
100 |
Переменная n с начальным значением 100 |
|
1 |
00 |
000 |
001 |
000 |
Константа переадресации |
|
Рассматриваемая программа выделяется новым приёмом программирования, она является самомодифицирующейся программой. Обратим внимание на третью строку программы. Содержащаяся в ней команда изменяет исходный код программы (меняет команду в ячейке с адресом 002) для организации цикла перебора элементов массива2. При первом выполнении этой команды она адресуется к первому элементу массива, затем ко второму и т.д. Для перехода от одного элемента массива к следующему модифицируемая команда рассматривается как целое число, к которому прибавляется специально подобранная константа переадресации. Согласно одному из принципов Фон Неймана, числа и команды в учебной машине неотличимы друг от друга, а, значит, изменяя числовое представление команды, мы можем изменять и её суть.
У такого метода программирования есть один существенный недостаток: модификация кода программы внутри её самой повышает сложность программирования, может привести к путанице и вызвать появление ошибок. Заметим также, что такую программу нельзя повторно выполнить, просто передав управление на её первую команду3, так как нужно будет предварительно восстановить исходный вид всех модифицированных команд. Кроме того, самомодифицирующуюся программу трудно понимать и вносить в неё изменения. Только представьте себе, что Вам необходимо составить алгоритм для машины Тьюринга, в которой можно изменять команды в клетках таблицы (например, заменить команду движения головки по ленте влево на движение вправо). Настоящий кошмар для современного программиста!
В нашей учебной машине, однако, самомодифицирующаяся программа – это единственный способ обработки достаточно больших массивов. В других архитектурах ЭВМ, с которыми Вы познакомитесь в свое время, есть и иные, более эффективные способы работы с массивами, поэтому метод программирования с модификацией команд в современных компьютерах, как уже говорилось, обычно не используется.
