3

I was doing a simple calculator with the following code. Right now it executes perfectly. When I tried to change things around, however, it doesn't work. I used BOOL program to check whether to continue asking for input from the person or finish the program.

If I change the expression of while statement to just (program) and change YES/NO in the program statements, why does the code fail to do what is inside the while?

// A simple printing calculator
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]
    Calculator *deskCalc = [[Calculator alloc] init];
    double value1;
    char operator        
    BOOL program;

    [deskCalc setAccumulator: 0];

    while (!program) {
    NSLog (@"Please type in your expression");
    scanf (" %lf %c", &value1, &operator);
    program = NO;

        if (operator == '+') {
            [deskCalc add: value1];
        }
        else if (operator == '-') {
            [deskCalc subtract: value1];
        }
        else if (operator == '*' || operator == 'x') {
            [deskCalc multiply: value1];
        }
        else if (operator == '/') {
            if (value1 == 0)
                NSLog (@"Division by zero!");
            else
                [deskCalc divide: value1];
        }
        else if (operator == 'S') {
            [deskCalc set: value1];
        }
        else if (operator == 'E') {
            [deskCalc accumulator];
            program = YES;
        }
        else {
            NSLog (@"Unknown operator");
        }
    }

    NSLog (@"The result is %f", [deskCalc accumulator]);

    [deskCalc release];

    [pool drain];
    return 0;
}
jscs
  • 63,694
  • 13
  • 151
  • 195
makaed
  • 419
  • 1
  • 5
  • 13

2 Answers2

7

You haven't set the initial value of program, so it defaults to a garbage value which just happens to be non-zero.

Set the initial value of program when you declare it:

BOOL program = NO; // or YES, whichever is appropriate
Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • If it's always garbage (non-zero), is it safe to assume that 99.99% of the time it will evaluate to True (since only 0 is considered false)? – 5StringRyan Sep 22 '11 at 17:12
  • 2
    Absolutely not. Its value is undefined. It could evaluate to a random value every time. Rule of thumb: ***ALWAYS INITIALIZE YOUR VARIABLES IN C.*** – Jonathan Grynspan Sep 22 '11 at 17:13
  • 1
    I completely agree with you on the initialization (as I do in my own code). I was just thinking about how an "undefined" value is always random and how many times 0 would randomly be chosen. Could anything other than 0 (that could be randomly assigned to the bool variable without initialization) give a "FALSE" during an evaluation? – 5StringRyan Sep 22 '11 at 17:30
  • No, only `0` is false in C (at least in this context.) Don't rely on the value of `program` being anything at all though. This is undefined behaviour. The value of `program` when uninitialized could be neither zero nor non-zero but `purple * 10` or `pow(elephant, feelings)`. You don't know and should never *ever* rely on it. – Jonathan Grynspan Sep 22 '11 at 17:57
  • So there is a "purgatory" value that could neither be zero or non-zero, that's interesting. I'm curious how an if statement would treat a bool with this type of "purgatory" value. – 5StringRyan Sep 22 '11 at 18:05
  • @Hans: You may be interested in this SO question: http://stackoverflow.com/questions/1597405/what-happens-to-a-declared-uninitialized-variable-in-c-does-it-have-a-value Mentioned there are "trap values" which are, apparently, just such a "purgatory" bit pattern. – jscs Sep 22 '11 at 18:16
  • I'm not saying there *is* such a value on your system. I'm saying ***you cannot know for certain what value, if any, is held***. – Jonathan Grynspan Sep 22 '11 at 18:26
  • Also, how to deal with value1 and operator since they have to be inputed by the user? I don't need to initialize them? – makaed Sep 22 '11 at 18:35
  • Initialize them anyway to `0` or equivalent. As I said before, ***ALWAYS INITIALIZE YOUR VARIABLES IN C***. – Jonathan Grynspan Sep 22 '11 at 18:41
  • @JoshCaswell - Thanks for the link, it is an interesting read. – 5StringRyan Sep 22 '11 at 18:48
2

It is always a good practice to initialize all your variables when you declare them.

Also using scanf for input may be overdoing it, if I were you I would use fgets and then extract the information from the string using strtok. That way even if the user puts his elbow on the keyboard you will not have to worry. Alternatively if you are fond of scanf use sscanf on that string instead of strtok.

AndersK
  • 35,813
  • 6
  • 60
  • 86