Книга: C# 4.0: полное руководство
Оператор goto
Оператор goto
Имеющийся в C# оператор goto
представляет собой оператор безусловного перехода. Когда в программе встречается оператор goto
, ее выполнение переходит непосредственно к тому месту, на которое указывает этот оператор. Он уже давно "вышел из употребления" в программировании, поскольку способствует созданию "макаронного" кода. Тем не менее оператор goto
все еще находит применение — иногда даже эффективное. В этой книге не делается никаких далеко идущих выводов относительно правомочности использования оператора goto
для управления программой. Следует, однако, подчеркнуть, что этому оператору трудно найти полезное применение, и поэтому он не особенно нужен для полноты языка программирования. Хотя в некоторых случаях он оказывается удобным и дает определенные преимущества, если используется благоразумно. В силу этих причин оператор goto
упоминается только в данном разделе книги. Главный недостаток оператора goto
с точки зрения программирования заключается в том, что он вносит в программу беспорядок и делает ее практически неудобочитаемой. Но иногда применение оператора goto
может, скорее, прояснить, чем запутать ход выполнения программы.
Для выполнения оператора goto
требуется метка — действительный в C# идентификатор с двоеточием. Метка должна находиться в том же методе, где и оператор goto
, а также в пределах той же самой области действия. В приведенном ниже примере программы цикл суммирования чисел от 1 до 100 организован с помощью оператора goto
и соответствующей метки.
х = 1;
loopl: х++;
if(х < 100) goto loopl;
Кроме того, оператор goto
может быть использован для безусловного перехода к ветви case
или default
в операторе switch
. Формально ветви case
или default
выполняют в операторе switch
роль меток. Поэтому они могут служить адресатами оператора goto
. Тем не менее оператор goto
должен выполняться в пределах оператора switch
. Это означает, что его нельзя использовать как внешнее средство для безусловного перехода в оператор switch
. В приведенном ниже примере программы демонстрируется применение оператора goto
в операторе switch.
// Применить оператор goto в операторе switch.
using System;
class SwitchGoto {
static void Main() {
for(int i=1; i < 5; i++) {
switch(i) {
case 1:
Console.WriteLine("В ветви case 1");
goto case 3;
case 2:
Console.WriteLine("В ветви case 2");
goto case 1;
case 3:
Console.WriteLine("В ветви case 3");
goto default;
default:
Console.WriteLine("В ветви default");
break;
}
Console.WriteLine();
}
// goto case 1; // Ошибка! Безусловный переход к оператору switch недопустим.
}
}
Вот к какому результату приводит выполнение этой программы.
В ветви case 1
В ветви case 3
В ветви default
В ветви case 2
В ветви case 1
В ветви case 3
В ветви default
В ветви case 3
В ветви default
В ветви default
Обратите внимание на то, как оператор goto
используется в операторе switch
для перехода к другим его ветвям case
или к ветви default
. Обратите также внимание на то, что ветви case
не оканчиваются оператором break
. Благодаря тому что оператор goto
препятствует последовательному переходу от одной ветви case
к другой, упоминавшееся ранее правило недопущения "провалов" не нарушается, а следовательно, необходимость в применении оператора break
в данном случае отпадает. Но как пояснялось выше, оператор goto
нельзя использовать как внешнее средство для безусловного перехода к оператору switch
. Так, если удалить символы комментария в начале следующей строки:
// goto case 1; // Ошибка! Безусловный переход к оператору switch недопустим.
приведенная выше программа не будет скомпилирована. Откровенно говоря, применение оператора goto
в операторе switch
, в общем, не рекомендуется как стиль программирования, хотя в ряде особых случаев это может принести определенную пользу.
Ниже приведен один из полезных примеров применения оператора goto
для выхода из глубоко вложенной части программы.
// Продемонстрировать практическое применение оператора goto.
using System;
class Use_goto {
static void Main() {
int i=0, j=0, k=0;
for(i=0; i < 10; i++) {
for(j=0; j < 10; j++ ) {
for(k=0; k < 10; k++) {
Console.WriteLine ("i, j, k: " + i + " " + j +
" " + k) ;
if(k == 3) goto stop;
}
}
}
stop:
Console.WriteLine("Остановлено! i, j, k: " + i + ", " + j + " " + k) ;
}
}
Выполнение этой программы дает следующий результат.
i, j, k: 000
i, j, k: 001
i, j, k: 002
i, j, k: 003
Остановлено! i, j, k: 0, 0 3
Если бы не оператор goto
, то в приведенной выше программе пришлось бы прибегнуть к трем операторам if
и break
, чтобы выйти из глубоко вложенной части этой программы. В данном случае оператор goto
действительно упрощает код. И хотя приведенный выше пример служит лишь для демонстрации применения оператора goto
, вполне возможны ситуации, в которых этот оператор может на самом деле оказаться полезным.
И последнее замечание: как следует из приведенного выше примера, из кодового блока можно выйти непосредственно, но войти в него так же непосредственно нельзя.
- Оператор цикла foreach
- Оператор break
- Оператор continue
- Оператор безусловного перехода goto
- Оператор цикла с предусловием while
- goto:
- ОПЕРАТОРЫ
- 6.4. Оператор continue
- Оператор перехода goto
- Стиль программирования: использование операторов goto и полных путей доступа в пространствах имен
- ДРУГИЕ УПРАВЛЯЮЩИЕ ОПЕРАТОРЫ: break, continue, goto