Оператор 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, вполне возможны ситуации, в которых этот оператор может на самом деле оказаться полезным.

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

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК