Операции (окончание)
Язык C. Лекция 4
Операция последовательного вычисления выражений (запятая) позволяет вычислить несколько выражений последовательно в заданном порядке — так, как они записаны (слева направо). При этом значением всего комбинированного выражения будет значение последнего вычисленного (самого правого) подвыражения. Значения остальных подвыражений теряются (но могут быть использованы их побочные эффекты).
Пример: Нужно вычислить квадрат какого-либо сложного выражения (скажем, ) и присвоить результат переменной z. Предполагается, что переменные phi, a, x содержат значения соответствующих величин, используемых в формуле.
1. Плохое решение
#include <math.h>
double a, phi, x, z;
....................
z = ((1.0 + 3.0*sin(phi))*exp(-a*x*x))*((1.0 + 3.0*sin(phi))*exp(-a*x*x))
Недостаток этого решения в том, что одни и те же величины вычисляются дважды, т.е. затрачивается лишнее время. Кроме того, сама строка программы выглядит чересчур грмоздкой — не сразу можно понять, что здесь вычисляется квадрат, приходится внимательно сравнивать сомножители.
|
|
2. Лучшее решение
Введем промежуточную переменную t и сохраним в ней значение возводимого в квадрат выражения:
#include <math.h>
double a, phi, x, t, z;
....................
t = (1.0 + 3.0*sin(phi))*exp(-a*x*x);
z = t*t;
Здесь нет лишних операций, а запись стала более наглядной — сразу видно, что z получает значение квадрата некоторой величины. Однако вместо одного оператора пришлось написать два.
3. Решение, использующее операцию «запятая»
Операция последовательного вычисления выражений позволяет записать предыдущее решение в виде единственного оператора:
#include <math.h>
double a, phi, x, t, z;
....................
z = (t = (1.0 + 3.0*sin(phi))*exp(-a*x*x)), t*t;
Значение первого подвыражения теряется, но так как это выражение присваивания, то вычисленная величина сохраняется в переменной t (побочный эффект). Значение всего выражения равно значению правого подвыражения, т.е. t*t. Так как операция «запятая» вначале обязательно вычисляет левый операнд, то к моменту вычисления t*t в переменной t уже находится нужное значение.
Другое применение операции «запятая» — возможность записать несколько выражений там, где согласно синтаксису требуется единственное выражение. Типичный пример — цикл for:
for (i = 0, s = 0.0; i < n; i++) s += a[i]*b[i];
Здесь цикл вычисляет скалярное произведение двух n-мерных векторов a и b (равное сумме произведений их элементов). По правилам языка C заголовок цикла for (содержимое круглых скобок) состоит из трех выражений, разделенных точками с запятой. Первое выражение вычисляется один-единственный раз перед входом в цикл (это выражение обычно используют для инициализации, т.е. задания начальных значений). Второе выражение — это условие выполнения цикла. Третье выражение вычисляется в конце каждого повторения цикла, перед тем, как вновь проверяется условие, заданное вторым выражением. В приведенном примере выражение инициализации состоит из двух подвыражений присваивания, связанных операцией «запятая». Значение комбинированного выражения здесь вообще не используется, его смысл состоит исключительно в побочном эффекте — присваивании начальных нулевых значений переменным i (индексу) и s (сумме). Операция «запятая» позволяет объединить эти два независимых присваивания в одно выражение, требуемое синтаксисом заголовка цикла.
|
|