Побочный эффект (side effect)
Под термином "главный эффект", понимается возврат функцией одного значения или возврат процедурой вычисленных значений (результатов) через параметры-переменные. Обычно предполагается (с точки зрения ясности работы программы), что все действия, которые выполняются в процедурах или функциях, соответствуют главному эффекту, т.е. предполагается, что главный эффект является единственным и за пределами подпрограммы невозможно обнаружить никаких других последствий ее выполнения. Однако по аналогии с фармакологией наряду с главным эффектом часто бывает и побочный.
Побочным эффектом называется такой эффект, который появляется вне тела процедуры или функции, и заключается в выполнении действий, отличных от тех, которые производят главный эффект.
Наиболее часто побочный эффект проявляется в следующих вариантах:
1 вариант. В изменении в теле процедуры или функции значений глобальных параметров. При этом использование глобальных переменных само по себе не является побочным эффектом. Побочных эффектом является их изменение в теле процедуры или функции. При этом предполагается, что главная (вызывающая) программа и подпрограммы обмениваются между собой данными через общие области памяти (глобальные переменные).
ПРИМЕР.
var
x, y : real;
стандартная функция |
begin
пользовательская (наша) подпрограмма |
тело (код) программы (основной раздел действий) |
end;
begin
x:= 2;
writeln ('x =', x);
y:= A(x); Вызов подпрограммы
writeln ('y =', y, ' при x = ', x);
end.
Побочный эффект заключается в изменении значения глобального параметра X. Вначале выполняется X := 2, далее при вызове функции А Х изменяется на 1.5. После этого вызова в главный алгоритм будет возвращено новое значение глобального параметра Х = 1.5. Это значение и будет выведено на экран последним оператором. Главное, глядя только на главную программу невозможно понять, почему значение X изменилось.
2 вариант. Необоснованный вызов в теле процедуры или функции процедур ввода–вывода, где этого никто (из тех, кто ее запускает) не ждет (обычно вывод выполняет в вызывающей части программы - при получении результатов - а не в вызываемой, где требуется только вычислять). Например, из текста программы может быть видно (ожидаться), что вывод результата должен быть только после вызова определенной подпрограммы (р1), однако при вызове другой подпрограммы (р2) тоже наблюдается вывод чего-то. Возникает вопрос, а что выводится? В результате ухудшается понятность программы.
3 вариант. В изменении значений фактических параметров, которые не должны изменяться (по логике человека, использующего программу). Например, функция не может по определению изменять ничего кроме возвращаемого значения. Если же функция изменяет какой-либо из параметров (из заголовка), то это - побочный эффект.
Если вызов функции, использующей побочный эффект, находится в выражении, то значение этого выражения может зависеть от порядка следования в нем операндов.
Пример: X:=X - B
Var 10 10 = X x = 0; B = 10;
X, Y : word; x:= x - 10=-10;
function F (B : word) :word; f:= 10*10=100;
begin
X:= X - B; x = 10; B = 10;
F:=B*B; x:= x - B=10 - 10=0;
end; f:= B*B=10*10=100
begin
X:= 10; x = 0; B = 0;
Y:= F(10)*F(X); x:= x - B=0;
writeln ('y =', y, ' при x = ', x); f:= 0*0=0;
X:=10;
Y:= F(X)*F(10); x = 10; B = 10;
writeln ('y =', y, ' при x = ', x); x:= x-B=0;
end. f:= B*B=100;
На экран будет выведено:
y=10000 при x= -10
y=0 при x= 0
Объяснение: при включенной оптимизации при вычислении значения выражения типа А1*А2 на Паскале вначале вычисляется А2, а потом А1 (для целей оптимизации операнды операции вычисляются в порядке помещения их на стек – в обратном порядке, т.е. справа налево).
При наличии в программе побочных эффектов невозможно предсказать по тексту главного алгоритма, какие реальные действия в программе выполняются, если не анализировать ход выполнения каждой процедуры и функции, что ухудшает понимание программы.
Вывод: Можно использовать побочный эффект для определенных целей (например, для обмена данными между главной программой и подпрограммами), но надо строго оговаривать все такие случаи.
Дата добавления: 2016-05-28; просмотров: 2965;