Когда подходящее время использовать оператор goto?(Любой язык, любая проблема) - PullRequest
2 голосов
/ 22 февраля 2011

Мне дали задание в моем классе CS, чтобы придумать ситуацию, когда было бы неплохо использовать оператор goto и написать для него программу. Это может быть любая ситуация (хотя я должен написать программу за 3 дня), и до сих пор я не думал ни о чем, что не могло бы быть легко решено ни рекурсией, ни итерацией. Единственное, о чем я подумал, - это Ханойские башни, но это можно сделать всего за несколько строк с помощью рекурсии. У вас есть какие-нибудь предложения? Спасибо за вашу помощь.

РЕДАКТИРОВАТЬ: Это должен быть фактический оператор goto, а не другие операторы, которые служат той же цели. Например, пользователь, ответивший предложением переключиться, поднять, бросить и т. Д., Не работает для назначения.

Ответы [ 9 ]

1 голос
/ 22 февраля 2011

Часто пренебрегаемый момент заключается в том, что GOTO может просто ужасно запутаться в if/else утверждениях бизнес-кода для спагетти.

И прежде чем вы откажетесь от меня за такое заявление, поймите, что бизнес-логика может быть ужасно сложной. Я имею в виду, что иногда ваши единственные варианты - создать кучу логических переменных, установить / сбросить их в беспорядке if / else, а затем в более поздней части кода после того, как вы сбежали из гнезда if / else, чтобы замочить виджет когда переменная 5 установлена ​​в отличие от оператора GOTO.

Те, кто придерживается строки «никогда», показывают только свою неспособность к адаптации и невежество.

1 голос
/ 22 февраля 2011

Этот пример C ++ является спорным:

if(a)
{
    ... // case 1
}
else if(b)
{
    if(c)
    {
        ... // case 1 again
    }
    else
    {
        ... // case 2
    }
}
else
{
    ... // case 3
}

Проблема здесь в том, что вы должны либо дублировать код в if() для случая 1, либо вы должны продублировать код для обработки случая 1. ВВ этом примере код обработки был продублирован.Посмотрите это альтернативное решение no-goto:

if(a || (b && c))
{
    ... // case 1
}
else if(b && !c)
{
    ... // case 2
}
else
{
    ... // case 3
}

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

Вот решение, использующее goto, которое не имеет компромиссов:

if(a)
{
case1:
    ... // case 1
}
else if(b)
{
    if(c)
    {
        goto case1;// case 1 again
    }
    else
    {
        ... // case 2
    }
}
else
{
    ... // case 3
}

В C ++ область действия - это то, что нужно учитывать.goto в C ++ является почти единственным способом прыгал исполнение с либеральной точкой зрения сферы.

1016 * Даже если спорны, я все равно бы не использовать goto в образце я дал, потому что это усложняет порядоквыполнение.Знание положения вещей на case1: на самом деле не очень интуитивно понятно.
1 голос
/ 22 февраля 2011

goto использование должно быть в порядке в программе, которая демонстрирует проблемы спагетти-кода.

1 голос
/ 22 февраля 2011

Единственное время, когда можно использовать goto, - это когда никакая другая доступная вам конструкция элемента управления не может обеспечить такое поведение.

Как говорит GJ, основное время - это когда у вас фактически нет ничего, что может выполнить итерацию, как, например, когда вы находитесь на земле сборки.

1 голос
/ 22 февраля 2011

Переключение предложений может быть видом использования.

На самом деле любой цикл использует (внутренне) код операции процессора goto инструкция!

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

0 голосов
/ 26 ноября 2014

Есть несколько очень случайных случаев, когда goto может быть более читабельным и, возможно, более безопасным, когда дело доходит до обслуживания кода. Первое, что приходит на ум, это проблема «также» кода:

//...

if(a)
{
    //do a
}
else if(b)
{
    //do b
}
else if(c)
{
    //do c
}
else goto skip_also_stuff;
{
    //if any if in the chain was true, do this too
    //do if a and b and c
}
skip_also_stuff:

//...

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

0 голосов
/ 09 ноября 2011

Ответ от Шикса точный.Я считаю, что единственное разумное использование goto - это разрыв глубоко вложенного цикла.

Это надуманный пример:

#include <stdio.h>

int main()
{
  // find 6 positive numbers less than 100
  // , half odd
  // , half even
  // , that add up to a multiple of 123

  int n1, n2, n3, n4, n5, n6;

  for (n1 = 2; n1 < 100; n1+=2) 
    for (n2 = 2; n2 < 100; n2+=2) 
      for (n3 = 2; n3 < 100; n3+=2) 
        for (n4 = 1; n4 < 100; n4+=2) 
          for (n5 = 1; n5 < 100; n5+=2) 
            for (n6 = 1; n6 < 100; n6+=2) 
              if (((n1 + n2 + n3 + n4 + n5 + n6) % 123) == 0) 
                goto found; 

  printf("tested all numbers less than 100, couldn't find an answer\n");
  return 0;
found:
  int sum = n1 + n2 + n3 + n4 + n5 + n6;
  printf("answer: %d + %d + %d + %d + %d + %d = %d ( %% 123 is %d)\n", 
         n1, n2, n3, n4, n5, n6, sum, sum % 123);
  return 0;
}
0 голосов
/ 16 октября 2011

Вот пример:

while(...){
    switch(...){
     ...
     goto loop_done;       // break won't work here
    }
 loop_done: ...
0 голосов
/ 22 февраля 2011

Обработка исключений.

Выражение "рейз" или "бросок" - это своего рода переход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...