在这种情况下使用 goto 不好吗?

Is it bad to use goto in this situation?

我一直在开发一个基于控制台的计算器应用程序,我想使用 2 个函数来让它看起来更简洁(我不希望 main 有太多行),所以我决定使用 goto从 main 跳转到我的 foil 函数,然后另一个 goto 跳回到 main 的开始。我只是想知道这样做是否不安全。谢谢:)

void foileq()
{
    int a, b, c, d;
    printf("Enter the 4 numbers\n");
    cin >> a;
    cin >> b;
    cin >> c;
    cin >> d;
    cout << a * c << " " << a * d << " " << b * c << " " << b * d << endl;
}

int main()
{
    float a, b;
    string type = "";
BEGIN:
    {
        while (1)
        {
            printf("Add,subtract,multiply,divide,foil,power?\n");
            cin >> type;
            if (type == "foil")
            {
                goto FOIL;
                continue;

            }
            else
            {
                printf("Enter A number\n");
                cin >> a;
                printf("Enter another number\n");
                cin >> b;
                if (strcmp(type.c_str(), "add") == 0)
                    printf("%.2f\n", a + b);
                else if (strcmp(type.c_str(), "subtract") == 0)
                    printf("%.2f\n", a - b);
                else if (strcmp(type.c_str(), "multiply") == 0)
                    printf("%.2f\n", a * b);
                else if (strcmp(type.c_str(), "divide") == 0)
                    printf("%.2f\n", a / b);
                else if (strcmp(type.c_str(), "power") == 0)
                    printf("%.2f\n", pow(a, b));
            }
        }
    }
FOIL:
    foileq();
    goto BEGIN;
}

如果您调用 foileq(); 而不是 goto FOIL;,行为将是相同的。在这种情况下,使用 goto 不会使事情更具可读性。在极少数情况下,goto 会使代码变得更好,这不是其中之一。

此外,您当前编写的 continue 也不需要,因为 goto 就在它前面。

The seemingly universal revolution to GOTO is largely due to Edsger Dijkstra's letter "Go To Statement Considered Harmful".

(来源:while(1) .. break instead of goto

在输入 == 时使用 while 循环退出 "foil"

while( type != "foil" )

然后将 else 更改为 if( type != "foil" ) 以防止它在输入为箔时 运行。

"Is it bad to use goto in this situation?"

在任何情况下使用 goto 几乎总是被认为 不好 。如果你使用它,不要向后跳,而只能向前跳。

类似下面的内容(使用单个标签)可能没问题:

 int foo() {
     while(loop_condition_ok) {
         if(inner_operation_fails()) {
             goto hell;
         }
     }
     return 0;

 hell:
     return -1;
 }