View Categories

Оператор перехода

Самый базовый и низкоуровневый оператор управления программой - оператор безусловного перехода goto позволяет перейти к другой строке программы по метке. goto по сути работает на уровне процессора - переход к другой инструкции в памяти.

Почти все остальные операторы управления программой основаны на механизме goto и просто обёрнуты в более удобный синтаксис

Для работы оператора нужно создать в программе метку - уникальное имя, после которого стоит двоеточие - имя:. После этого можно будет перейти к ней при помощи goto имя;:

goto label;

// код1
// код1

label:
// код2

В данном случае весь "код1" будет пропущен - после строки goto label; программа перейдет сразу к "код2".

Зацикливание #

Если метка будет объявлена выше, чем goto:

label:
// код
goto label;

То программа зациклится и будет по кругу выполнять "код", находящийся между label: и goto label;.

По условию #

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

if (a > b) goto label;
// ...
label:

Проблемы #

В общем случае не рекомендуется использовать goto в своей программе, он плохо читается и может создать путаницу. Доказано, что в любой ситуации можно заменить goto на другую конструкцию. Также он может приводить к ошибкам, например:

goto label;

int a = 0;

label:
int b = a;

Здесь мы переходим к использованию переменной, которая по сути не была создана и инициализирована - ошибка "передача управления в обход инициализации".

Где использовать #

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

Обработка ошибок на нескольких этапах: последовательно проверяем некоторые условия, при возникновении ошибки пропускаем все следующие проверки и переходим к некоторому завершающему коду. Если ошибок нет - выполняется также другой код. Например запрос к серверу с обработкой ошибок подключения, затем разбор результата и так далее.

if (ошибка1) goto exit;
if (ошибка2) goto exit;
if (ошибка3) {
    // код3
    goto exit;
}

// код, если ошибок нет

exit:
// завершающий код

На if-else получится примерно такая макаронина, её размер будет увеличиваться при увеличении количества обрабатываемых ошибок:

if (!ошибка1) {
    if (!ошибка2) {
        if (!ошибка3) {
            // код, если ошибок нет
        } else {
            // код3
        }
    }
}

// завершающий код

Аналогично - выход из вложенных циклов (о них - в следующем уроке):

for (..) {
    for (..) {
        for (..) {
            if (..) goto exit;
        }
    }
}

exit:

Здесь без goto пришлось бы городить флаг, по которому выходить из каждого цикла через break.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх