Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кетков.doc
Скачиваний:
17
Добавлен:
27.09.2019
Размер:
2.22 Mб
Скачать

6.4. Специальные формы оператора присваивания

Следующая группа операторов присваивания обязана своим происхождением формату машинных команд в двухадресных машинах:

COD A1,A2

Здесь COD – код машинной операции;

A1,A2 – адреса ячеек оперативной памяти и/или арифметических регистров.

Результат выполнения такой операции над содержимым A1 и A2 записывается по адресу A1 (A1=A1A2). По аналогии с такой записью в языках C, C++ появилась следующая синтаксическая конструкция:

v = exp; //вместо v = v  exp;

Здесь символ  обозначает один из следующих знаков двухместных операций:

+,-,*,/,%,<<,>>,&,|,^

Например:

x += 2; //вместо x=x+2;

z /= 1.5; //вместо z=z/1.5;

Довольно экзотически выглядит оператор присваивания, в правой части которого через запятую задана последовательность некоторых действий. Например:

x=(y=sin(a+b),z=cos(a-b),max(y,z));

Действия в скобках выполняются слева направо, т.е. сначала будет вычислено значение sin(a+b), которое занесут в переменную y, затем будет вычислено значение переменной z. Окончательным результатом скобки, которое будет присвоено переменной x, станет вычисление значения функции max(y,z).

6.5. Условный оператор

С помощью условного оператора в программе можно создать две альтернативные цепочки операторов, выполнение каждой из которых происходит в зависимости от истинности или ложности заданного условия:

if(условие) {S1; S2;...} [else {Q1;Q2;...}]

Если условие, указанное в круглых скобках истинно, то выполняется цепочка операторов S1, S2,… . В противном случае выполняется цепочка операторов Q1,Q2,… . Альтернативная ветвь вместе со служебным словом else может отсутствовать. И тогда речь идет о выполнении или обходе цепочки операторов S1,S2,… .

Простейшие условия задаются в виде проверки соотношения двух однотипных выражений:

if(a>b) cout<<a; else cout<<b;

if(x>=0) y=sqrt(x);

Напомним, что операции отношения в языках C, C++ обозначаются следующими символами и их комбинациями:

==

равно

!=

не равно

>

больше

>=

больше или равно

<

меньше

<=

меньше или равно

Более сложные условия могут составляться из элементарных соотношений с помощью логических операций "ИЛИ" (||), "И" (&&), "НЕ" (!). Например, проверка принадлежности x диапазону [a,b] выглядит следующим образом:

if(a<=x && x<=b) ...

В качестве логического условия иногда можно встретить в круглых скобках обычное арифметическое выражение:

if(a)...

В языке C логические переменные отсутствуют. Вместо этого действует соглашение о том, что ложь эквивалентна нулевому значению числового выражения, а истина – не нулевому значению. Поэтому приведенная выше проверка эквивалентна соотношению:

if(a != 0)...

6.6. Оператор безусловного перехода

Перед любым исполняемым оператором программы может находиться символьная метка, отделяемая от оператора двоеточием:

m5: printf("\nx=%f",x);

На помеченный таким образом оператор может быть передано управление с помощью оператора goto m5. Но такие переходы допустимы только внутри функции. Переход из одной функции в другую по оператору goto недопустим.

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

Рассмотрим две реализации программы, которая вводит три целочисленных значения и выводит максимальное из них. В первой из них (программа-спагетти) на 10 исполняемых строк приходится 5 операторов goto. Во второй реализации потребовалось всего 5 исполняемых строк и ни одного оператора goto.

Пример 6.1. Программа-спагетти.

#include <stdio.h>

#include <conio.h>

void main()

{ int a,b,c;

scanf("%d %d %d",&a,&b,&c);

if(a>b) goto m1;

if(b>c) goto m2;

m3: printf("max=%d",c);

goto m5;

m1: if(c>a) goto m3;

m4: printf("max=%d",a);

goto m5;

m2: printf("max=%d",b);

m5: getch();

}

Пример 6.2. Пример прозрачной логики

#include <stdio.h>

#include <conio.h>

void main()

{ int a,b,c;

scanf("%d %d %d",&a,&b,&c);

if(b>a) a=b;

if(c>a) a=c;

printf("max=%d",a);

getch();

}

Одним из случаев, когда применение оператора goto приводит к более простой и более эффективной программе является необходимость выйти из внутреннего цикла за пределы внешнего цикла:

int i,j;

for(i=0; i<n; i++) {...

for(j=0; j<20; j++) {...

if(условие_выхода) goto mm;

}

}

mm:

Конечно, можно придумать более запутанную схему, не используя goto:

int i,j,k=1;

for(i=0; i<n && k; i++) {...

for(j=0; j<20 && k; j++) {...

if(условие_выхода) {k=0; break;}

}

}

Применяя оператор goto, стоит следовать следующим рекомендациям:

  • не входить внутрь блока извне, особенно если в начале этого блока присутствуют объявления локальных переменных с инициализацией;

  • не входить в цикл извне, ибо это приведет к неправильной работе цикла;

  • не передавать управление внутрь условного оператора;

  • не передавать управление внутрь переключателя.