Zainab Nabeel
Zainab Nabeel

Reputation: 51

Alternative way to use goto statement

I am confused about writing a program that takes '/' character from user and warning to user not to use 0 in numerator. I have build the program but I want an alternative method to using the goto statement.

# 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);

Below I want to remove these 2 lines but it should achieve the same result as it works.

    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");
}

Upvotes: 3

Views: 228

Answers (3)

Gopi
Gopi

Reputation: 19864

There are multiple alternatives check out mine.

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;
   }
}

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 881393

There is nothing wrong with goto in and of itself!

This is what most people fail to understand, instead simply parroting a poorly chosen snippet from a paper given decades ago, one that Dijkstra himself later came to regret, stating something along the lines of having "a bad feeling that people are making a religion out of it".

If people would simply try to understand the reasons behind guidelines like use of goto, break and continue, or limiting exit points from functions, and so on, they'd be far better practitioners of the art.

What Dijkstra actually railed against, and what I agree with whole-heartedly, was the "unbridled use of the go to statement", in a computing environment where there was mostly little else in terms of iteration. The fact that many environments only had goto could lead to a lot of spaghetti code, very hard to follow.

I actually consider blind dogmatism in the industry far more of a problem than goto statements ever were :-) The problem with goto is its misuse, since, as mentioned, it can make code much harder to follow and what I tend to do when I hear these pronouncements is ask:

Is this code hard to follow or maintain because it breaks the "rules"?

If you were to restructure your code as follows:

// ===================================================
// 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;
    }
// ===================================================

you would be hard-pressed trying to come up with a do or while based solution that was more readable or understandable. You may match the readability but you'll often find that a poorly selected choice between the zero-or-more do and one-or-more while can render the code less readable.

For what it's worth, this is about as close as I can get to the same code in a non-goto-using way:

// ===================================================
// 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));
// ===================================================

but that has other issues such as code duplication. That too can be fixed but it generally involves the use of more variables, or the use of break which has exactly the same issue as goto here(b).


So, bottom line, don't take as gospel something you don't understand, it doesn't matter whether it comes from Dijkstra, Knuth, dkr, or even whatever other gods you may believe in :-)

Think about why it may be considered gospel in the first place, then that's how you decide whether it applies in a given situation(a).

I frequently use goto in state machines, error handling and so on, places where it actually simplifies the code that would otherwise be harder to understand.


(a) This includes advice from random people on the net, even from those called "paxdiablo" :-)


(b) One thing you might want to consider is to let the user enter zero even for a division, and then just sort it out in the calculation with something like:

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

I'd probably prefer the catch-early option myself but this may be a viable solution for you.

Upvotes: 8

SMA
SMA

Reputation: 37023

Convert it into a loop like below:

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);

Upvotes: 0

Related Questions