![]() 4. A Crude Calculator
Now, what we have done so far was pretty useless, so, when are we going to get to do something that actually is of some value? OK. Let's try creating our first useful program: a crude calculator. For this we'll revamp our main() function again:
#include <stdio.h>
#include <stdbool.h>
int main()
{
int vFirstArg,
vSecondArg;
char vOperation;
bool vFinished;
// Make sure our flag is initialized!
vFinished = false;
// Now loop until user doesn't want anymore:
while( vFinished != true )
{
printf( "What operation do you want to do?\n" );
scanf( "%c", &vOperation );
fpurge( stdin );
if( vOperation == '+' )
{
printf( "Enter left argument: " );
scanf( "%d", &vFirstArg );
fpurge( stdin );
printf( "\nEnter right argument: " );
scanf( "%d", &vSecondArg );
fpurge( stdin );
printf( "\n%d + %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg + vSecondArg );
}
else
vFinished = true;
}
printf( "Finished.\n" );
return 0;
}
The first new thing here is char, which is the variable type used for a single character. Note that single characters are usually enclosed in single quotes, aka apostrophes, unlike the usual bunch of text like what we hand to printf() (However, there is also text of 1 character in length, I'll explain that more closely later). To hand a char to printf() or scanf(), use the %c format sequence. The second new type is bool, which is short for boolean. A boolean is a value that can only have 2 states, either false or true (think of this as an on/off switch). It is defined in the header stdbool.h that we're now including in addition to stdio.h. An example: If you want to write a program that drives a car, you might want to have the driver check whether it's raining before starting to drive. You'd then use a boolean variable named e.g. isItRaining to remember this, so you can have your commands that hit the brakes when the car needs to stop check isItRaining. If it is raining, you might want to use the more careful braking code so your car doesn't get out of control. Anyway, if it rains, you'd assign the value true to it, while on good days you'd set it to false. Variables that contain booleans are often also called flags -- this comes from US postal mail boxes, which have a little flag on them which can be turned up to indicate to the postman that it contains mail to be picked up. Now, the first line after the variable declarations assigns the value false to our bool variable vFinished. This is necessary since a newly-declared variable contains garbage. Not zero, not true, not false, just any arbitrary value. If your program wants to use a variable, make sure you have assigned it a value. Assigning a value to a variable the first time is usually also called initializing a variable. The next line is something new: The While-Loop. A while loop takes the following form: while( <condition> ) <command>; And does the command <command> repeatedly, while the boolean value <condition> is true. That is, it checks whether <condition> is true, if not just goes on with the rest of the program, but if it is, does <command> and checks <condition> again. If it is still true, it just repeats this behaviour endlessly until <condition> becomes false. Note that there is no semicolon behind the braces around the condition. If you're wondering why we need to do the same commands repeatedly, it's time for a bit of storytelling again: Every computer program is usually just started, then runs its main() function and quits again. That's what all our previous programs did: They spilled some text to the terminal and then disappeared again. But more advanced programs can do lots of different things, and even do them in sequence. The art of programming is delaying the end of main() until the user has been able to do what she wanted and signals to us that it's time for our program to go. To achieve this, a program usually repeatedly asks the user to enter what she wants to do and then does that. And then asks again, does that, asks again ... until the user enters a special thing to do that tells us the user wants to exit our program (also called to quit). When that happens we have to cause our loop to end. For this reason we have vFinished. It's false when we start our program and stays this way until the user asks us to quit. At that moment, we set it to true to indicate we want to stop repeating our commands and finish. Trouble is, while expects condition to be true while we want to repeat, whereas vFinished is true when we want to quit. Of course we could just turn vFinished into vKeepRunning and set it to true and be all hunky-dory, but you wanted to learn how to make the computer do what you want, not how to do what the computer wants, right? OK, so how do we fix this? We introduce the "is not" operator, !=. != compares what's to its left and right and if both sides have different values (for example, one of them is true and the other is false) it returns true. That is: 1 != 1 (read "one is not one")
2 != 2 (read "two is not two")
1 != 2 (read "one is not two")
2 != 1 (read "two is not one")
So, to get back to our program: The condition of the loop is vFinished != true which is true if vFinished is false, and false if vFinished is true. Thus, it is exactly what we need here. Yeah! We won against the computer! Now an additional problem: I spoke of several commands, but a while loop may only have one command following it. What do we do? Well, there's also a solution for that: curly brackets! In C, you can use curly brackets to group several commands into one command:
{
vVariable = 1;
vVariable = 2;
}
This is one command to C! (But note that they're still done one after the other by C - you can't use this to have your computer do five times the work) Thus, if we want several commands in our while loop, we just enclose them in curly braces. Note that even though there is no semicolon after the curly braces, C treats them as if there was a semicolon behind them. I.e.
while( vKeepRunning )
{
vVariable = 1;
vVariable = 2;
}
is perfectly valid, just as while( vKeepRunning ) vVariable = 1; You needn't put a semicolon behind the closing curly bracket (and in most cases, you shouldn't). Now, the next two lines in the program are pretty straightforward. We ask the user what she wants to do and then we get the character the user typed using scanf(). The next part is what is interesting. Since we now have whatever the user wanted to do in our char variable vOperation, we now need to take special action depending on whatever is in vOperation. For this, we use the if conditional, which takes the form: if( <condition> ) <ifCommand>; else <elseCommand>; Where it does the command represented by <ifCommand> if <condition> is true, and <elseCommand> when <condition> is false. Note that you can leave away the entire "else" part if you want it to do nothing if <condition> is false, i.e. if( <condition> ) <ifCommand>; Note that while the if-conditional looks similar to the while-loop, an if is only executed once, whereas a while does things repeatedly. Now, we use the opposite to the "is not" operator != to compare vOperation to the values we want to handle. The opposite is the == operator, which means "is equal to". That is, if( vOperation == '+' ) does the <ifCommand> part if vOperation actually contains a "+" character, and else performs the <elseCommand> part. If you're wondering why the plus sign is enclosed in apostrophes instead of quote characters, re-read my statements on the char type above. That's pretty much all that is special about this program. The "if"-part of the "if" conditional simply asks for the two values to add and then outputs the result, using the "+" operator to add the two together. The "else" part simply sets vFinished to true, which causes "while" to stop repeating. When this happens, the program will resume execution after the end of "while"'s commands and thus write "Finished." to the screen and exit by returning zero. Now you have a very crude and limited calculator that allows you to perform additions. To end the calculator session, just enter something different than a plus sign. For those of you who like to experiment, I suggest you try the following: Extend this program to also perform subtraction, multiplication and division. The multiplication operator is * and the division operator is /. Remember to guard against the user dividing a number by zero, as C does not guard against this, and your program will simply crash. Hint: You can put another if inside an if or else block. Don't forget to leave in the final "else" statement that assigns true to vFinished, though, or you won't get out of your program anymore. Below is the finished code you can check against:
int main()
{
int vFirstArg,
vSecondArg;
char vOperation;
bool vFinished;
// Make sure our flag is initialized!
vFinished = false;
// Now loop until user doesn't want anymore:
while( vFinished != true )
{
printf( "What operation do you want to do?\n" );
scanf( "%c", &vOperation );
fpurge( stdin );
if( vOperation == '+' )
{
printf( "Enter left argument: " );
scanf( "%d", &vFirstArg );
fpurge( stdin );
printf( "\nEnter right argument: " );
scanf( "%d", &vSecondArg );
fpurge( stdin );
printf( "\n%d + %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg + vSecondArg );
}
else
{
if( vOperation == '-' )
{
printf( "Enter left argument: " );
scanf( "%d", &vFirstArg );
fpurge( stdin );
printf( "\nEnter right argument: " );
scanf( "%d", &vSecondArg );
fpurge( stdin );
printf( "\n%d - %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg - vSecondArg );
}
else
{
if( vOperation == '*' )
{
printf( "Enter left argument: " );
scanf( "%d", &vFirstArg );
fpurge( stdin );
printf( "\nEnter right argument: " );
scanf( "%d", &vSecondArg );
fpurge( stdin );
printf( "\n%d * %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg * vSecondArg );
}
else
{
if( vOperation == '/' )
{
printf( "Enter left argument: " );
scanf( "%d", &vFirstArg );
fpurge( stdin );
printf( "\nEnter right argument: " );
scanf( "%d", &vSecondArg );
fpurge( stdin );
if( vSecondArg == 0 )
{
printf( "Flunked maths class, eh?\n" );
printf( "You can't divide by zero!\n" );
}
else
printf( "\n%d / %d = %d\n",
vFirstArg,
vSecondArg,
vFirstArg / vSecondArg );
}
else
vFinished = true;
}
}
}
}
printf( "Finished.\n" );
return 0;
}
|
![]() 1. What you need | ||||
| Home | Admin | Edit Last Change: 2008-04-20 @156, © 2003-2008 by M. Uli Kusterer, all rights reserved. |