ОШИБКА: ярлык "foo" используется, но не определен

Так что я дурачился с некоторым C++ и получил ранее заявленную ошибку с некоторым кодом, который выглядел примерно так:

#include <iostream>
using namespace std;

char foodstuffs;

void fruit()
{
cin>>foodstuffs;
switch(foodstuffs)
{
case 'a': goto foo; break;
case 'b': goto fooo; break;
}
}

int main()
{
cout<<"What do you want to eat? (a/b)";
fruit();
foo: cout<<"You eat an apple.";
fooo: cout<<"You eat a banana.";
}

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

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

У меня вопрос, как я могу заранее определить эти метки, чтобы функция fruit() знала, что они из себя представляют? Кроме того, мне нужно сделать это, не перемещая метки из основной функции.

4 ответа

goto оператор может перейти только к локально определенным меткам, он не может перейти к другим функциям.

Таким образом, этикетки в main не будет ссылаться, и goto заявления в fruit не найдете ярлыки.

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

void foo()
{
    if(feelLikeIt)
       goto foobar;
}

void bar()
{
    std::string message = "Hello";
foobar:
    cout << message << endl;
}

Переход на foobar из foo запрещен, потому что "message" не существует.

Таким образом, язык просто не позволяет вам сделать это.

Кроме того, способ, которым вы пытаетесь использовать "goto", не позволит вам повторно использовать функцию "fruit()", потому что она всегда принимает решение о том, что делать с выбором, а не с вызывающей его функцией. Что делать, если вы хотите сделать это:

cout<<"What do you want to eat? (a/b)";
fruit();
foo: cout<<"You eat an apple.";
fooo: cout<<"You eat a banana.";
cout<<"What does your friend want to eat? (a/b)";
fruit();
// oops, you just created a loop because fruit made the decision on what to do next.

На самом деле вы хотите использовать "fruit()" как функцию, которая возвращает значение.

enum Fruit { NoSuchFruit, Apple, Banana };

Fruit fruit(const char* request)
{
    char foodstuffs;
    cout << request << " (a/b)";
    cin >> foodstuffs;
    switch (foodstuffs)
    {
        case 'a': return Apple;
        case 'b': return Banana;
        default:
            cout << "Don't recognize that fruit (" << foodstuffs << ")." << endl;
            return NoSuchFruit;
    }
}

const char* fruitNames[] = { "nothing", "an apple" ,"a banana" };

int main()
{
    Fruit eaten = fruit("What do you want to eat?");
    cout << "You ate " << fruitNames[eaten] << "." << endl;
    eaten = fruit("What does your friend want to eat?");
    cout << "Your friend ate " << fruitNames[eaten] << "." << endl;
}

Сожалею. Ты не можешь goto на метку, которая находится за пределами текущей исполняющей функции. Кроме того, существуют другие ограничения на использование goto, Например, вы не можете пропустить определение переменной, используя goto, И есть другие, о которых я не полностью осведомлен.

Суть?

Не использовать goto,

goto не может использоваться для навигации за пределами текущей функции. Попробуйте вернуть что-то из функции и используйте это в условии if else.

Другие вопросы по тегам