Материал предоставлен http://it.rfet.ru

Оператор goto

Имеющийся в C# оператор goto представляет собой оператор безусловного перехода. Когда в программе встречается оператор goto, ее выполнение переходит непосредственно к тому месту, на которое указывает этот оператор. Он уже давно «вышел из употребления» в программировании, поскольку способствует созданию «макаронного» кода. Тем не менее оператор goto все еще находит применение — иногда даже эффективное.

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

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

Для выполнения оператора goto требуется метка — действительный в C# идентификатор с двоеточием. Метка должна находиться в том же методе, где и оператор goto, а также в пределах той же самой области действия. В приведенном ниже примере программы цикл суммирования чисел от 1 до 100 организован с помощью оператора goto и соответствующей метки.

x = 1;
loop1:
  x++;
  if (x < 100) goto loop1;

Кроме того, оператор 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: 0 0 0
i, j, k: 0 0 1
i, j, k: 0 0 2
i, j, k: 0 0 3
Остановлено!  i, j, k: 0, 0 3

Если бы не оператор goto, то в приведенной выше программе пришлось бы прибегнуть к трем операторам if и break, чтобы выйти из глубоко вложенной части этой программы. В данном случае оператор goto действительно упрощает код. И хотя приведенный выше пример служит лишь для демонстрации применения оператора goto, вполне возможны ситуации, в которых этот оператор может на самом деле оказаться полезным.

И последнее замечание: как следует из приведенного выше примера, из кодового блока можно выйти непосредственно, но войти в него так же непосредственно нельзя.

Оператор returnТестирование к разделу "Управляющие операторы"