C # Перейти к использованию - что еще использовать здесь? - PullRequest
6 голосов
/ 24 сентября 2010

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

static void Main()
{
    Restart:
    ...

    string UserChoice=Console.ReadLine();
    if (UserChoice=="y")
    goto Restart;
}

Действительно ли использование goto здесь так плохо?Я просто не вижу другого способа повторить код без циклов и т. Д. Это кажется очень простым и понятным способом.Или я что-то упустил?

Ответы [ 11 ]

20 голосов
/ 24 сентября 2010
string userchoice;

do {                

    userchoice=Console.ReadLine();

} while (userchoice=="y");
5 голосов
/ 24 сентября 2010

Конечно, если ваш код будет делать то же самое снова и снова, вы должны добавить цикл.Это намного лучше, чем goto.

Используйте что-то вроде этого

string UserChoice = "y";
while( UserChoice == "y"){
  ...
  UserChoice=Console.ReadLine();
}

Это должно сработать для вас.

5 голосов
/ 24 сентября 2010

вместо этого напишите что-то вроде ниже.

while(Console.ReadLine() == "y")
{
.....
}

Да, использовать goto плохо, потому что он делает ваш код менее читабельным.

4 голосов
/ 24 сентября 2010

Неужели использование goto здесь действительно так плохо?

В марте 1968 года Дейкстра отправил письмо Сообщения ACM , которое былоопубликовано под заголовком Перейти к заявлению, которое считается вредным .Это интересное чтение и часть знаний программиста.

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

Он проходит через эти шаги в своих рассуждениях против GOTO:

  1. Сначала рассмотрим очень простой язык без процедур, циклов или GOTO.На таком языке программист может мысленно отслеживать выполнение, воображая указатель выполнения, продвигающийся от начала файла до конца.Для выполнения выполнения модели достаточно одного индекса (т.е. номера строки).

  2. Теперь мы добавим процедуры к языку.Ход выполнения больше не может отслеживаться одним индексом, так как он может находиться внутри процедуры.Мы также должны отслеживать, с какой строки была вызвана процедура.Кроме того, процедуры могут быть вызваны из других процедур.Поэтому мы моделируем прогресс выполнения как последовательность показателей.(В реальной жизни программисты называют такую ​​последовательность «трассировкой стека».)

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

  4. Теперь мы добавим GOTO.Дейкстра утверждает, что при необузданном использовании GOTO наша способность отслеживать ход выполнения теперь не работает.Мы по-прежнему можем отслеживать ход выполнения с помощью «часов выполнения», говоря «сейчас мы выполняем 152-й оператор».Однако это не очень полезно для установления контекста, необходимого для интерпретации значений переменных.

Пока мы используем только операторы GOTO для построения простых циклов, вы можете утверждать, чтоситуация эквивалентна точке (3), и нет никаких проблем.Но в этом случае вы можете просто использовать конструкции цикла.Лучше просто не указывать GOTO в своем коде, чтобы не попасть в ситуацию, описанную в пункте (4).

3 голосов
/ 24 сентября 2010

Я бы использовал цикл do / while:

string UserChoice = "";
do {
    ...
    UserChoice=Console.ReadLine();
} while(UserChoice == "y");
2 голосов
/ 24 сентября 2010

В ответах отсутствует одно основное решение:

while (true)
{
    ...
    if (other-stop-condition) break;     

    ...

    string UserChoice=Console.ReadLine();
    if (UserChoice != "y") break;
}

Оператор break считается менее структурированным, чем чистый, но более структурированным, чем (реальный) переходЕго следует использовать с осторожностью, но у него есть свои применения, такие как other-stop-condition

действительно ли использование goto здесь так плохо?

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

2 голосов
/ 24 сентября 2010

Использование методов вместо GOTO более широко распространено:

static void Main()
{
    Restart();
}

static void Restart()
{
    ...code

    string userChoice = Console.ReadLine();
    if (userChoice=="y")
        Restart();
}
2 голосов
/ 24 сентября 2010

Вы можете использовать рекурсивную функцию, чтобы сделать то же самое без циклов:

public static void Main(string[] args)
{
   PrintChoices();
}

private static void PrintChoices()
{
    string userChoice = Console.ReadLine();

    if (userChoice == "y")
        PrintChoices();        
}
1 голос
/ 24 сентября 2010

Используйте цикл do while, чтобы заменить goto на более читаемый.

do 
{
...
}
while(Console.ReadLine() == "y");
0 голосов
/ 11 марта 2018
class Program
{
    static void Main(string[] args)
    {
        int add;
        try
        {
            ArrayList al = new ArrayList();
        t:
            Console.Write("Enter the Number of elements do you want to insert in arraylist");
            int n = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Enter the Values:");
            for (int i = 0; i < n; i++)
            {
                al.Add(Console.ReadLine());

            }
            foreach (var a in al)
            {
                Console.WriteLine("valus:" + a);
            }
            Console.WriteLine("Add another number yes:1 ");
            add = Convert.ToInt32(Console.ReadLine());
            while (add == 1)
            {
                goto t;

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Enter the Valid Number and try again");
        }
        Console.ReadKey();


    }
}

}

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