使用goto语句的替代方法

时间:2015-02-23 05:21:57

标签: c goto

我对编写一个需要' /'来自用户的字符和警告用户不要在分子中使用0。我已经构建了程序,但我想要一种使用goto语句的替代方法。

# include <stdio.h>
int main()
{
    char o;
    int num1,num2;
    printf("Enter one operator like '+' '-' '/' '%%' '*' : ");
    scanf("%c",&o);
    printf("Enter 1st number: ");
    scanf("%d",&num1);
my: printf("Enter 2nd number: ");
    scanf("%d",&num2);

下面我想删除这两行,但它应该达到与它相同的效果。

    if(o=='/' && num2==0 ){
        printf("You can't divide by zero \n");
        goto my;
    }    
    switch(o) {
        case '+':
            printf("%d + %d = %d",num1, num2, num1+num2);
            break;
        case '-':
            printf("%d - %d = %d",num1, num2, num1-num2);
            break;
        case '*':
            printf("%d * %d = %d",num1, num2, num1*num2);
            break;
        case '/':
            printf("%d / %d = %d",num1, num2, num1/num2);
            break;
        case '%':
            printf("%d %% %d = %d",num1, num2, num1%num2);
            break;
        default:
            printf("Operator is not correct");
            break;
    }
    printf("\n\n");
    system ("pause");
}

3 个答案:

答案 0 :(得分:8)

  

goto本身没有任何问题!

这是大多数人都无法理解的,而只是简单地将几十年前的一篇文章中的一个选择不当的片段鹦鹉学舌,Dijkstra后来自己后悔了这句话,说出了一些令人不快的感觉。人们正在制造宗教信仰&#34;。

如果人们只是尝试了解使用gotobreakcontinue等指南背后的原因,或限制功能退出点,以及等等,他们是更好的艺术实践者。

Dijkstra 实际上反对什么,以及我全心全意同意的是,在一个计算环境中肆无忌惮地使用go to statement&#34;迭代方面很少。许多环境goto的事实可能导致很多意大利面条代码,很难遵循。

我实际上认为行业中的盲目教条主义比goto陈述更为严重:-) goto的问题是误用,因为,提到,它可以使代码更难以遵循,当我听到这些声明时,我倾向于做什么:

  

代码难以遵循或维护,因为它违反了&#34;规则&#34;?

如果您按如下方式重构代码:

// ===================================================
// Get the second number, disallowing zero if dividing.
getSecondNum:
    printf ("Enter 2nd number: ");
    scanf ("%d", &num2);
    if ((o == '/') && (num2 == 0)) {
        printf ("You can't divide by zero \n");
        goto getSecondNum;
    }
// ===================================================

如果您想要提供基于dowhile更多可读或可理解的解决方案,那么您会很难受。您可能匹配的可读性,但您经常会发现在零或多do和一个或多个while之间选择不当的选项可以呈现代码 less 可读。

对于它的价值,这与我在非goto中使用相同代码的方式非常接近 - 使用方式:

// ===================================================
// Get the second number, disallowing zero if dividing.
do {
    printf ("Enter 2nd number: ");
    scanf ("%d", &num2);
    if ((o == '/') && (num2 == 0)) {
        printf ("You can't divide by zero \n");
} while ((o == '/') && (num2 == 0));
// ===================================================

但是还有其他问题,例如代码重复。这也可以修复但通常涉及使用更多变量,或使用break 完全goto相同的问题(b)


所以,底线,不要把你不了解的东西视为福音,它是来自Dijkstra,Knuth,dkr还是无关紧要甚至你可能相信的任何其他神: - )

考虑为什么首先可以将其视为福音,然后 一个)

经常在状态机,错误处理等中使用goto,它实际上简化代码本来难以理解的地方。


(a)这包括来自网上随机人员的建议,甚至包括那些被称为&#34; paxdiablo&#34; : - )


(b) 想要考虑的一件事就是让用户即使对某个部门也输入零,然后在计算中用一些东西对其进行排序像:

case '/':
    if (num2 == 0)
        printf ("%d / 0 is undefined, cannot divide by zero", num1);
    else
        printf ("%d / %d = %d", num1, num2, num1 / num2);
    break;

我自己可能更喜欢catch-early选项,但可能对您来说是一个可行的解决方案。

答案 1 :(得分:0)

有多种选择可以查看我的。

while(1)
{
   printf("Enter a number\n");
   if(scanf("%d",&num2) == 1)
   {
     if(o == '/' && num2 == 0)
     {
       printf("You can't divide by zero\n");
     }
     else
     break;
   }
}

答案 2 :(得分:0)

将其转换为如下所示的循环:

do {
    printf("Enter 2nd number: ");
    scanf("%d",&num2);
    if(o=='/' && num2==0 ){
        printf("You can't divide by zero \n");
        continue;
    } else {
        break;
    }
} while (1);