我应该在这里使用goto语句吗

Should I use goto statement here?

本文关键字:语句 goto 在这里 我应该      更新时间:2023-10-16

一位优秀的绅士告诉我goto语句很糟糕,但我不明白我怎么不能在这里使用它:

int main()
{   
   using namespace std;
   int x;
   int y;
   int z;
   int a;
   int b;
   Calc: //How can i get back here, without using goto?
   {
   cout << "To begin, type a number" << endl;
   cin >> x;
   cout << "Excellent!" << endl;
   cout << "Now you need to type the second number" << endl;
   cin >> y;
   cout << "Excellent!" << endl;
   cout << "Now, what do you want to do with these numbers?" << endl;
   cout << "Alt. 1 +" << endl;
   cout << "Alt. 2 -" << endl;
   cout << "Alt. 3 *" << endl;
   cout << "Alt. 4 /" << endl;
   cin >> a;
       if (a == 1) {
    z = add(x, y);
   }
   if (a == 2) {
    z = sub(x, y);
   }
   if (a == 3) {
    z = mul(x, y);
   }
       if (a == 4) {
    z = dis(x, y);
   }
}
cout << "The answer to your math question is ";
cout << z << endl;
cout << "Do you want to enter another question?" << endl;
cout << "Type 1 for yes" << endl;
cout << "Type 0 for no" << endl;
cin >> b;
    if (b == 1) {
    goto Calc;
}
cout << "Happy trails!" << endl;
return 0;
}

正如你所看到的,这是一个计算器。此外,如果你愿意,你能建议一种更好的方式(如果存在(让用户选择操作(+-*/(吗。头文件处于控制之下。我为cout的许多声明道歉。

以下是一个经过清理且格式正确的版本,使用do/while循环进行结构:

using namespace std;
int main()
{   
    int x, y, z, a, b;
    do {
        cout << "To begin, type a number" << endl;
        cin >> x;
        cout << "Excellent!" << endl;
        cout << "Now you need to type the second number" << endl;
        cin >> y;
        cout << "Excellent!" << endl;
        cout << "Now, what do you want to do with these numbers?" << endl;
        cout << "Alt. 1 +" << endl;
        cout << "Alt. 2 -" << endl;
        cout << "Alt. 3 *" << endl;
        cout << "Alt. 4 /" << endl;
        cin >> a;
        if (a == 1) {
            z = add(x, y);
        }
        else if (a == 2) {
            z = sub(x, y);
        }
        else if (a == 3) {
            z = mul(x, y);
        }
        else if (a == 4) {
            z = dis(x, y);
        }
        cout << "The answer to your math question is ";
        cout << z << endl;
        cout << "Do you want to enter another question?" << endl;
        cout << "Type 1 for yes" << endl;
        cout << "Type 0 for no" << endl;
        cin >> b;
    } while (b != 0);
    cout << "Happy trails!" << endl;
    return 0;
}

Erm,使用适当的循环结构whilefor等。

在这种情况下,"更普遍接受"的方法是do {。。。CCD_ 7,但是编译的结果可能是相同的。

  • goto使得跟踪执行的来源和去向变得困难。

  • goto鼓励spagetti代码,除非你严格限制它的使用位置(例如,你可以争辩说你只将它用于清理块,但在RAII存在的情况下,这样的争论毫无意义(。

  • 您正在使用goto来模拟循环。你为什么不写一个循环?

  • 它是模糊的,因此,使您的代码对其他人来说不太可用。

  • CCD_ 10使得跟踪对象的寿命变得更加困难。

实际问题的简短回答:不,您不应该在此代码中使用goto。没有必要。

goto的使用应该是"当它使代码更清晰或更安全时"。"使代码更清晰"的典型例子是有几层嵌套循环,而某些特定情况需要离开所有嵌套级别,添加"我们想退出循环吗"会使代码更加复杂。"让它更安全"的一个例子是,如果函数持有锁、打开文件或类似的东西,并且需要提前返回,但您也需要关闭文件或释放锁,使用"goto exit_now;"比试图记住持有哪些锁、文件等然后执行return;更安全。

此:

if (a == 1) {
    z = add(x, y);
}
if (a == 2) {
    z = sub(x, y);
}
if (a == 3) {
    z = mul(x, y);
}
if (a == 4) {
    z = dis(x, y);
}

是一个典型的情况,你应该使用"开关":

switch(a)
{
   case 1:
     z = add(x, y);
     break;
   case 2:
     z = sub(x, y);
     break;
  ....
}

使代码更加清晰——对于a是否更改了值以及是否可以使用另一个if语句,也没有任何混淆。

您可以轻松避免代码中的"goto"。只需将其划分为几个功能:

using namespace std;
void question () {
  cout << "To begin, type a number" << endl;
  cin >> x;
  // put rest of the code here
}
int main () {
  int ask = 1;
  while ( ask == 1 ) {
    question();
    cout << "Do you want to enter another question?" << endl;
    cout << "Type 1 for yes" << endl;
    cout << "Type 0 for no" << endl;
    cin >> ask;
  }
  return 0;
}

编辑:正如评论中所指出的,使用do while实际上是一个更好的选项。

goto并不是自动坏的。无法读取的代码是错误的。每当你发现自己需要一些模糊的编程结构,比如"goto"时,通常意味着你的代码要么写得不好,要么你的程序设计有缺陷。

解决方案几乎总是更多的函数。例如:

bool run_program();
int  prompt_user_begin();
int  prompt_user_again();
int  prompt_operation_type();
bool prompt_continue();

int main()
{
  while(run_program())
  {}
  cout << "Happy trails!" << endl;
  return 0; 
}

bool run_program()
{
  int first;
  int second;
  int operation_type;
  int result;
  first  = prompt_user_begin();
  cout << "Excellent!" << endl;
  second = prompt_user_again();
  cout << "Excellent!" << endl;
  operation_type = prompt_operation_type();
  switch(operation_type)
  {
    case 1: result = add(first, second); break;
    case 2: result = sub(first, second); break;
    case 3: result = mul(first, second); break;
    case 4: result = div(first, second); break;
  }
  cout << "The answer to your math question is ";
  cout << result << endl;
  return prompt_continue();
}
int prompt_user_begin ()
{
  int x;
  cout << "To begin, type a number" << endl;
  cin >> x;
  return x;
}
int prompt_user_again ()
{
  int x;
  cout << "Now you need to type the second number" << endl;
  cin >> x;
  return x;
}
int prompt_operation_type ()
{
  int x;
  cout << "Now, what do you want to do with these numbers?" << endl;
  cout << "Alt. 1 +" << endl;
  cout << "Alt. 2 -" << endl;
  cout << "Alt. 3 *" << endl;
  cout << "Alt. 4 /" << endl;
  cin >> x;
  return x;
}
bool prompt_continue ()
{
  int x;
  cout << "Do you want to enter another question?" << endl;
  cout << "Type 1 for yes" << endl;
  cout << "Type 0 for no" << endl;
  cin >> x;
  return x==1;
}