Операторы перехода
.
оператор
goto mmm:
...
mmm: оператор
Оператор goto дает программисту большую свободу связывать между собой различные части программы. Как осознанно пользоваться этой свободой и не злоупотреблять ей, обсуждается в 3.1. Операторы break, continue и return являются вариантами оператора перехода, действующими в рамках текущего цикла и функции. Поэтому они в меньшей мере нарушают естественную логику работы программы, заданную другими операторами:
-оператор continue выполняет переход из тела цикла к его повторяющейся части, то есть досрочно завершает текущий шаг и переходит к следующему;
-оператор break производит альтернативный выход из самого внутреннего цикла, то есть переходит к первому оператору, следующему за текущим оператором цикла. Заметим, что "покинуть" одновременно несколько вложенных друг в друга циклов при помощи break не удается;
-оператор return производит досрочный выход из текущей функции. Он, кроме всего прочего, возвращает значение результата функции. Это его свойство будет рассмотрено в 2.4.
void F()
{
for (i=0; i<n; m1: i++)
{
if (A[i]==0) continue; //goto m1;
if (A[i]==-1) return; //goto m2;
if (A[i] < 0) break; //goto m3;
}
m2: ... продолжение тела функции
m3:
}
Операторы continue, break и return должны завершаться ограничителем ";" .
Оператор switch можно назвать множественным переходом по группе значений выражения. Он имеет самый "изысканный" синтаксис:
switch (выражение)
{
case константа1: последовательность операторов_1
case константа2: последовательность операторов_2
case константа3: последовательность операторов_3
default: последовательность операторов
}
Выполняется он следующим образом. Вычисляется значение выражения, стоящего в скобках. Затем последовательно проверяется его совпадение с каждой из констант, стоящих после ключевого слова case и ограниченных двоеточием. Если произошло совпадение, то производится переход на идущую за константой простую последовательность операторов. Отсюда следует, что если не предпринять никаких действий, то после перехода к n-й последовательности операторов будет выполнена n+1 -я и все последующие. Чтобы этого не происходило, в конце каждой из них ставится оператор break , который в данном случае производит выход за пределы оператора switch . И последнее. Метка default обозначает последовательность, которая выполняется "по умолчанию", то есть когда не было перехода ни по какой другой ветви. Все эти нюансы отражены в примере, содержащем полный программный эквивалент оператора switch с использованием операторов goto :
.
switch (n) Эквивалент
if (n==1) goto m1;
{ if (n==2) goto m2;
case 1: n=n+2; break; if (n==4) goto m3;
case 2: n=0; break; goto md;
case 4: n++; break; m1: n=n+2; goto mend;
default: m2: n=0; goto mend;
n=-1; m3: n++; goto mend;
} md: n=-1;
mend: ...
Оператор switch обычно используется при анализе значений переменной, когда он заменяет группу условных операторов:
.
switch (c) Эквивалент
{ if (c==' ') {...}
case ' ': ... break; if (c=='+') {...}
case '+': ... break; if (c=='-') {...}
case '-': ... break;
}
В заключение рассмотрим несколько " маленьких хитростей" , связанных с оператором break . При его наличии в теле цикла существуют два пути, через которые программа достигает следующего за циклом оператора: либо "естественный" выход по нарушению условия продолжения цикла, либо альтернативный выход по break . У программы, в принципе, есть возможность определить причину выхода по значениям переменных, которые использовались в цикле:
for (i=0; i< 20; i++) // Достигло ли 20-ти значение i
{ ... if (A[i] < 0) break; ... }
if (i==20) {...был естественный выход ...}
else {...был выход по break...}
Если несколько ветвей оператора switch должны содержать идентичные действия (возможно, с различными параметрами), то можно использовать общую последовательность операторов в одной ветви, не отделяя ее оператором break от предыдущих:
sign=0; // Ветвь для значения c, равного '+',
switch (c) // используется и предыдущей ветвью
{ // для значения '-'
case '-': sign=1;
case '+': Sum(a,b,sign); break;
}