【问题标题】:(C++) Goto statement not working. Beginner [closed](C++) Goto 语句不起作用。初学者[关闭]
【发布时间】:2014-08-03 14:46:31
【问题描述】:

我正在制作 USD 到 MXN 的转换器,我希望它可以双向工作。 if 语句有效(尝试了 cout

    #include "stdafx.h"
    #include <cstdlib>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])
    {
int user;
int u, m;
cout << "US/MXN Converter" << endl;
cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
cout << endl;

cout << "What Way to convert" << endl;
cout << "[1] US to MXN" << endl;
cout << "[2] MXN to US" << endl;
cout << "Selection: ";
cin >> user;

if (user == 1)
{
    goto USTMXN;
}
else
{
    goto MXNTUS;
}

    USTMXN:
cout << "Enter the amount of US Dollars to Convert" << endl;
cout << "Amount: ";
cin >> u;
m = u * 12.99;
cout << endl;
cout << "MXN Pesos: " << m << endl;
goto END;

    MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;

    END:

system("PAUSE");
return EXIT_SUCCESS;
    }

【问题讨论】:

  • 不要说“不会工作”,而是说你期望发生的事情,以及实际发生的事情。
  • @kfsone goto 是一个完全合法的 C++ 语句,在我看来并没有得到充分利用。否则,为什么它会在规范中?想想编译器现在不必做的工作!编译和运行包含 goto 的代码所节省的时间远远超过了实际使用 goto 语句所带来的任何社会隐含的污名。
  • @user3547330 这里真正要使用的不是goto,而是子程序或函数。
  • @user3547330:再一次,“不起作用”并不是对问题的有意义的描述。在你解释你的问题是什么之前,它没有任何意义。

标签: c++ if-statement converter goto


【解决方案1】:

作为程序员,我们必须做的最基本的事情之一就是学会将问题分解为更小的问题。您实际上遇到了一系列问题。

我将向您展示如何解决您的问题。您可能想为这个答案添加书签,因为我会先发制人一些问题,您将在接下来的几步中遇到问题,并让您准备 - 如果您注意 - 自己解决它们;)

让我们从剥离您的代码开始。

现场演示:http://ideone.com/aUCtmM

#include <iostream>

int main()
{
    std::cout << "Enter a number: ";
    int i;
    std::cin >> i;

    std::cout << "Enter a second number: ";
    int j;
    std::cin >> j;

    std::cout << "i = '" << i << "', j = '" << j << "'\n";
}

我们在这里检查什么?我们正在检查是否可以向用户提出两个问题。效果很好。

接下来是你对 goto 的使用,我强烈建议你不要使用它。使用函数会更好。我将首先在这里演示您的 goto 案例:

#include <iostream>

int main()
{
    int choice;
    std::cout << "Enter choice 1 or 2: ";
    std::cin >> choice;
    if ( choice == 1 )
        goto CHOSE1;
    else if ( choice == 2 )
        goto CHOSE2;
    else {
        std::cout << "It was a simple enough question!\n";
        goto END;
    }

CHOSE1:
    std::cout << "Chose 1\n";
    goto END;

CHOSE2:
    std::cout << "Chose 2\n";
    goto END;

END:
    std::cout << "Here we are at end\n";
}

现场演示:http://ideone.com/1ElcV8

所以 goto 不是问题。

剩下的就是你对变量的使用了。通过第二组变量(mm,uu),您真的把事情搞砸了。您不仅不需要拥有这些,而且您正在做一些非常顽皮的事情,因为这些变量只存在于一个范围内,而不存在于另一个范围内。你可以“摆脱”它,但它会在以后再次困扰你。

两个主要代码流的区别在于变量名称。第二种转换情况如下所示:

    MXNTUS:
int mm, uu;
cout << "Enter the amount of Pesos to Convert" << endl;
cout << "Amount: ";
cin >> mm;
uu = mm / 12.99;
cout << endl;
cout << "US Dollars: " << m << endl;
goto END;

这里的问题是您在输出中意外地使用了变量“m”。这就是我们所说的未初始化。

cout << "US Dollars: " << m << endl;

中间那个m应该是mm

您的编译器实际上应该对此发出警告。如果不是,并且您只是开始学习,则应该弄清楚如何提高编译器警告级别。

最好做一个函数来进行转换;你可以为每个方向创建一个函数,但我已经创建了一个处理这两种情况的函数:

#include <iostream>

static const double US_TO_MXN = 12.99;
static const char DATA_DATE[] = "6/12/2014";

void convert(const char* from, const char* to, double exchange)
{
    std::cout << "Enter the number of " << from << " to convert to " << to << ".\n"
                 "Amount: ";
    int original;
    std::cin >> original;
    std::cout << to << ": " << (original * exchange) << '\n';
}

int main()  // this is valid since C++2003
{
    std::cout << "US/MXN Converter\n"
                 "1 US = " << US_TO_MXN << " MXN (" << DATA_DATE << ")\n"
                 "\n";

    int choice = 0;
    // Here's a better demonstration of goto
GET_CHOICE:
    std::cout << "Which conversion do you want to perform?\n"
                "[1] US to MXN\n"
                "[2] MXN to US\n"
                "Selection: ";
    std::cin >> choice;

    if (choice == 1)
        convert("US Dollars", "Pesos", US_TO_MXN);
    else if (choice == 2)
        convert("Pesos", "US Dollars", 1 / US_TO_MXN);
    else {
        std::cerr << "Invalid choice. Please try again.\n";
        goto GET_CHOICE;
    }

    // this also serves to demonstrate that goto is bad because
    // it's not obvious from the above that you have a loop.
}

ideone 现场演示:http://ideone.com/qwpRtQ

有了这个,我们可以继续清理一大堆东西并扩展它:

#include <iostream>
using std::cin;
using std::cout;

static const double USD_TO_MXN = 12.99;
static const double GBP_TO_MXN = 22.03;
static const char DATA_DATE[] = "6/12/2014";

void convert(const char* from, const char* to, double exchange)
{
    cout << "Enter the number of " << from << " to convert to " << to << ".\n"
                 "Amount: ";
    int original;
    cin >> original;
    cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";
}

int main()  // this is valid since C++2003
{
    cout << "Foreign Currency Converter\n"
            "1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
            "1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
            "\n";

    for ( ; ; ) {   // continuous loop
        cout << "Which conversion do you want to perform?\n"
                "[1] USD to MXN\n"
                "[2] MXN to USD\n"
                "[3] GBP to MXN\n"
                "[4] MXN to GBP\n"
                "[0] Quit\n"
                "Selection: ";
        int choice = -1;
        cin >> choice;
        cout << '\n';

        switch (choice) {
            case 0:
                return 0;       // return from main

            case 1:
                convert("US Dollars", "Pesos", USD_TO_MXN);
                break;

            case 2:
                convert("Pesos", "US Dollars", 1 / USD_TO_MXN);
                break;

            case 3:
                convert("British Pounds", "Pesos", GBP_TO_MXN);
                break;

            case 4:
                convert("Pesos", "British Pounds", 1 / GBP_TO_MXN);
                break;

            default:
                cout << "Invalid selection. Try again.\n";
        }
    }
}

http://ideone.com/iCXrpU

这方面还有很多改进的余地,但我希望它对你有所帮助。

---- 编辑----

迟到的提示:您似乎正在使用基于 system("PAUSE") 的 Visual Studio。无需添加到您的代码中,只需使用 Debug -> Start without Debugging 或按 Ctrl-F5。它会自动为你做暂停:)

---- 编辑 2 ----

一些“你是怎么做到的”点。

    cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";

我非常小心地没有执行using namespace std;,当您开始使用更多的 C++ 时,该指令将成为您存在的祸根。最好不要习惯它,等你对 C++ 编程更加熟悉,更重要的是调试奇怪的编译错误时,再让自己开始使用它。

但是通过添加 using std::coutusing std::cin,我节省了很多打字时间,而没有创建我必须避免的函数/变量名称的雷区。

那么这条线会做什么:

    cout << '\n' << original << ' ' << from << " gives " << int(original * exchange) << ' ' << to << ".\n";

'\n' 是单个字符,一个回车符。这样做比std::endl 更有效,因为std::endl 必须去戳输出系统并强制写入;它不仅仅是行尾字符,它实际上终止了行,如果你愿意的话。

int(original * exchange)

这是一个让 C 程序员感到困惑的 C++ 特性。我实际上是在以original * exchange 的结果作为参数创建一个“临时”整数。

int i = 0;
int i(0);

两者是等价的,一些程序员建议养成使用第二种机制的习惯,这样你就可以理解当你以后遇到所谓的“最令人烦恼的解析”时会发生什么:)

convert("Pesos", "British Pounds", 1 / GBP_TO_MXN)

1 / x “反转”的值。

    cout << "Foreign Currency Converter\n"
            "1 USD = " << USD_TO_MXN << " MXN (" << DATA_DATE << ")\n"
            "1 GBP = " << GBP_TO_MXN << " MXN (" << DATA_DATE << ")\n"
            "\n";

这可能会令人困惑。我将隐喻与此混合在一起,我对此感到有些羞耻,但它读起来很好。同样,采用将问题分解为更小的问题的概念。

cout << "Hello " "world" << '\n';

(注意:“\n”和“\n”不同:“\n”实际上是一个字符串,而“\n”实际上只是回车符)

这会打印出来

Hello world

当 C++ 看到像这样由空格(或 cmets)分隔的两个字符串文字时,它会将它们连接起来,因此它实际上将“Hello world”传递给 cout。

所以你可以将这段代码重写为

    cout << "Foreign Currency Converter\n1 USD = ";
    cout << USD_TO_MXN;
    cout << " MXN (";
    cout << DATA_DATE;
    cout << ")\n1 GBP = ";
    cout << GBP_TO_MXN;
    cout << " MXN (";
    cout << DATA_DATE;
    cout << ")\n\n";

&lt;&lt; 就是我们所说的“语义糖”。当你写

cout << i;

编译器将其翻译成

cout.operator<<(i);

这个看起来很奇怪的函数调用返回cout。所以当你写

cout << i << j;

它实际上是把它翻译成

(cout.operator<<(i)).operator<<(j);

括号(cout.operator&lt;&lt;(i))中的表达式返回cout,所以变成了

cout.operator<<(i); // get cout back to use on next line
cout.operator<<(j);

主指纹

int main()
int main(int argc, const char* argv[])

两者都是合法的。第一个是完全可以接受的 C 或 C++。第二个仅在您计划捕获“命令行参数”时有用。

最后,在 main

return 0;

请记住,main 被指定为返回 int。 C 和 C++ 标准为 main 提供了一个特殊情况,表示它是唯一一个不返回任何内容都不是错误的函数,在这种情况下,程序的“退出代码”可以是任何内容。

通常最好退货。在 C 和 C++ 中,“0”被认为是“假”,而其他任何东西(任何非零)都是“真”。因此,C 和 C++ 程序有一个约定,返回错误代码 0(假,无错误)以指示程序成功或退出没有问题,或任何其他指示(例如 1、2 ... 255)作为错误.

在 main 中使用“return”将结束程序。

【讨论】:

  • 添加了后期编辑:“后期提示:您似乎正在使用 Visual Studio,基于系统(“PAUSE”)。不必总是将其添加到您的代码中,只需使用Debug -> Start Without Debugging 或按 Ctrl+F5。它会自动为你暂停 :)"
  • 非常感谢。这修复并帮助了我的程序。 Visual Studio 没有进行任何调试,所以我在旧的 Dev C++ Bloodshed 中打开它,它就像一个梦一样工作,当然还有你的改进。非常感谢你的好家伙! :)
  • @user3547330 看看我添加的第二个编辑——希望对你有所帮助。此外,您可能希望从 Microsoft 获得 Visual Studio 2013 Express - 它是免费的,并且似乎可以很好地运行此代码 (visualstudio.com/downloads/download-visual-studio-vs)
【解决方案2】:

尝试像这样更改您的代码。不推荐使用 goto 标签。 switch 语句的主要思想:

int option;
  cin >> option

  switch(option)
  {
   case 1: // executed if option == 1
   {
    ... code to be executed ...
    break;
   }
   case 99: //executed id option == 99
   {
   ... code to be executed
   break;
   }
   default: // if non of above value was passed to option
   {
   // ...code...
   break;
   }


  }

这是唯一的例子。

   int main(int argc, char *argv[])
        {
    int user;
    int u, m;
    cout << "US/MXN Converter" << endl;
    cout << "1 US = 12.99 MXN (6/12/2014)" << endl;
    cout << endl;

    cout << "What Way to convert" << endl;
    cout << "[1] US to MXN" << endl;
    cout << "[2] MXN to US" << endl;
    cout << "Selection: ";
    cin >> user;

   switch(user )
    {
     case 1 : 
     {
     //USTMXN:
     cout << "Enter the amount of US Dollars to Convert" << endl;
     cout << "Amount: ";
     cin >> u;
     m = u * 12.99;
     cout << endl;
     cout << "MXN Pesos: " << m << endl;
     break;
     }

    }
    default :
    {
    //MXNTUS:
     int mm, uu;
     cout << "Enter the amount of Pesos to Convert" << endl;
     cout << "Amount: ";
     cin >> mm;
     uu = mm / 12.99;
     cout << endl;
     cout << "US Dollars: " << m << endl;
     break;
    }
   }
    system("PAUSE");
    return EXIT_SUCCESS;
        }

【讨论】:

  • 我没有尝试编译。这只是替换你的代码的主要思想。
  • 那是什么语言? case : user == 1?????
  • 我试过了,还是不行
  • 查找 case 语句的信息和语法。
  • 我真是太新了。就像这实际上是我的第一个程序,我正在学习,所以我不知道“查找案例语句的信息和语法”是什么意思。
猜你喜欢
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多