The C programming language provides a general decision-making capability in the form of a language construct known as the if statement. The general format of this statement is as follows:
if ( expression )
program statement
Imagine that you could translate a statement such as “If it is not raining, then I will go swimming” into the C language. Using the preceding format for the if statement, this might be “written” in C as follows:
if ( it is not raining )
I will go swimming
The if statement is used to stipulate execution of a program statement (or statements if enclosed in braces) based upon specified conditions. I will go swimming if it is not rain- ing. Similarly, in the program statement
if ( count > COUNT_LIMIT )
printf (“Count limit exceeded\n”);
the printf statement is executed only if the value of count is greater than the value of COUNT_LIMIT; otherwise, it is ignored.
An actual program example helps drive this point home. Suppose you want to write a program that accepts an integer typed in from the terminal and then displays the absolute value of that integer. A straightforward way to calculate the absolute value of an integer is to simply negate the number if it is less than zero. The use of the phrase “if it is less than zero” in the preceding sentence signals that a decision must be made by the program. This decision can be affected by the use of an if statement, as shown in Program 6.1.
Program 6.1 Calculating the Absolute Value of an Integer
// Program to calculate the absolute value of an integer
int main (void)
{
int number;
printf (“Type in your number: “);
scanf (“%i”, &number);
if ( number < 0 )
number = -number;
printf (“The absolute value is %i\n”, number);
return 0;
}
Program 6.1 Output
Type in your number: -100
The absolute value is 100
Program 6.1 Output (Rerun)
Type in your number: 2000
The absolute value is 2000
The program was run twice to verify that it is functioning properly. Of course, it might be desirable to run the program several more times to get a higher level of confidence so that you know it is indeed working correctly, but at least you know that you have checked both possible outcomes of the decision made by the program.
After a message is displayed to the user and the integer value that is entered is stored in number, the program tests the value of number to see if it is less than zero. If it is, the following program statement, which negates the value of number, is executed. If the value of number is not less than zero, this program statement is automatically skipped. (If it is already positive, you don’t want to negate it.) The absolute value of number is then displayed by the program, and program execution ends.
Look at Program 6.2, which uses the if statement. Imagine that you have a list of grades for which you want to compute the average. But in addition to computing the average, suppose that you also need a count of the number of failing grades in the list. For the purposes of this problem, assume that a grade less than 65 is considered a failing grade.
The notion of keeping count of the number of failing grades indicates that you must make a decision as to whether a grade qualifies as a failing grade. Once again, the if statement comes to the rescue.
Program 6.2 Calculating the Average of a Set of Grades and Counting the Number of Failing Test Grades
/* Program to calculate the average of a set of grades and count the number of failing test grades */
#include <stdio.h>
int main (void)
{
int numberOfGrades, i, grade;
int gradeTotal = 0;
int failureCount = 0;
float average;
printf (“How many grades will you be entering? “);
scanf (“%i”, &numberOfGrades);
for ( i = 1; i <= numberOfGrades; ++i ) {
printf (“Enter grade #%i: “, i);
scanf (“%i”, &grade);
gradeTotal = gradeTotal + grade;
if ( grade < 65 )
++failureCount;
}
average = (float) gradeTotal / numberOfGrades;
printf (“\nGrade average = %.2f\n”, average);
printf (“Number of failures = %i\n”, failureCount);
return 0;
}
Program 6.2 Output
How many grades will you be entering? 7
Enter grade #1: 93
Enter grade #2: 63
Enter grade #3: 87
Enter grade #4: 65
Enter grade #5: 62
Enter grade #6: 88
Enter grade #7: 76
Grade average = 76.29
Number of failures = 2
The variable gradeTotal, which is used to keep a cumulative total of the grades as they are typed in at the terminal, is initially set to 0. The number of failing test grades is stored in the variable failureCount, whose value also is initially set to 0. The variable average is declared to be of type float because the average of a set of integers is not necessarily an integer itself.
The program then asks the user to enter the number of grades that will be keyed in and stores the value that is entered in the variable numberOfGrades.A loop is then set up that will be executed for each grade. The first part of the loop prompts the user to enter in the grade. The value that is entered is stored in the variable called, appropriately enough, grade.
The value of grade is then added into gradeTotal, after which a test is made to see
if it is a failing test grade. If it is, the value of failureCount is incremented by 1. The entire loop is then repeated for the next grade in the list.
When all of the grades have been entered and totaled, the program then calculates the grade average. On impulse, it seems that a statement such as
average = gradeTotal / numberOfGrades;
would do the trick. However, recall that if the preceding statement were used, the deci- mal portion of the result of the division would be lost. This is because an integer division would be performed because both the numerator and the denominator of the division operation are integers.
Two different solutions are possible for this problem. One is to declare either numberOfGrades or gradeTotal to be of type float. This then guarantees that the divi- sion is carried out without the loss of the decimal places. The only problem with this approach is that the variables numberOfGrades and gradeTotal are used by the program to store only integer values. Declaring either of them to be of type float only obscures their use in the program and is generally not a very clean way of doing things.
The other solution, as used by the program, is to actually convert the value of one of the variables to a floating-point value for the purposes of the calculation. The type cast operator (float) is used to convert the value of the variable gradeTotal to type float for purposes of evaluation of the expression. Because the value of gradeTotal is cast into a floating-point value before the division takes place, the division is treated as the division of a floating value by an integer. Because one of the operands is now a floating- point value, the division operation is carried out as a floating-point operation. This means, of course, that you obtain those decimal places that you want in the average.
After the average has been calculated, it is displayed at the terminal to two decimal places of accuracy. If a decimal point followed by a number (known collectively as a pre- cision modifier) is placed directly before the format character f (or e) in a printf format string, the corresponding value is displayed to the specified number of decimal places, rounded. So in Program 6.2, the precision modifier .2 is used to cause the value of average to be displayed to two decimal places.
After the program has displayed the number of failing grades, execution of the pro-gram is complete.
1. The if-else Construct
If someone asks you whether a particular number is even or odd, you most likely make the determination by examining the last digit of the number. If this digit is either 0, 2, 4, 6, or 8, you readily state that the number is even. Otherwise, you claim that the number is odd.
An easier way for a computer to determine whether a particular number is even or odd is affected not by examining the last digit of the number to see if it is 0, 2, 4, 6, or 8, but by simply determining whether the number is evenly divisible by 2. If it is, the number is even; else it is odd.
You have already seen how the modulus operator % is used to compute the remainder of one integer divided by another. This makes it the perfect operator to use in determin- ing whether an integer is evenly divisible by 2. If the remainder after division by 2 is zero, it is even; else it is odd.
Look at Program 6.3—a program that determines whether an integer value typed in by the user is even or odd and that displays an appropriate message at the terminal.
Program 6.3 Determining if a Number Is Even or Odd
// Program to determine if a number is even or odd
#include <stdio.h>
int main (void)
{
int number_to_test, remainder;
printf (“Enter your number to be tested.: “);
scanf (“%i”, &number_to_test);
remainder = number_to_test % 2;
if ( remainder == 0 )
printf (“The number is even.\n”);
if ( remainder != 0 )
printf (“The number is odd.\n”);
return 0;
}
Program 6.3 Output
Enter your number to be tested: 2455
The number is odd.
Program 6.3 Output (Rerun)
Enter your number to be tested: 1210
The number is even.
After the number is typed in, the remainder after division by 2 is calculated. The first if statement tests the value of this remainder to see if it is equal to zero. If it is, the message “The number is even” is displayed.
The second if statement tests the remainder to see if it’s not equal to zero and, if that’s the case, displays a message stating that the number is odd.
The fact is that whenever the first if statement succeeds, the second one must fail, and vice versa. Recall from the discussions of even/odd numbers at the beginning of this section that if the number is evenly divisible by 2, it is even; else it is odd.
When writing programs, this “else” concept is so frequently required that almost all modern programming languages provide a special construct to handle this situation. In C, this is known as the if-else construct and the general format is as follows:
if ( expression )
program statement 1
else
program statement 2
The if-else is actually just an extension of the general format of the if statement. If the result of the evaluation of expression is TRUE, program statement 1, which immediately follows, is executed; otherwise, program statement 2 is executed. In either case, either program statement 1 or program statement 2 is executed, but not both.
You can incorporate the if-else statement into Program 6.3, replacing the two if statements with a single if-else statement. The use of this new program construct actu- ally helps to reduce the program’s complexity and also improves its readability, as shown in Program 6.4.
Program 6.4 Revising the Program to Determine if a Number Is Even or Odd
// Program to determine if a number is even or odd (Ver. 2)
#include <stdio.h>
int main ()
{
int number_to_test, remainder;
printf (“Enter your number to be tested: “);
scanf (“%i”, &number_to_test);
remainder = number_to_test % 2;
if ( remainder == 0 )
printf (“The number is even.\n”);
else
printf (“The number is odd.\n”);
return 0;
}
Program 6.4 Output
Enter your number to be tested: 1234
The number is even.
Program 6.4 Output (Rerun)
Enter your number to be tested: 6551
The number is odd.
Remember that the double equal sign == is the equality test and the single equal sign is the assignment operator. It can lead to lots of headaches if you forget this and inadver- tently use the assignment operator inside the if statement.
2. Compound Relational Tests
The if statements that you’ve used so far in this chapter set up simple relational tests between two numbers. In Program 6.1, you compared the value of number against 0, whereas in Program 6.2, you compared the value of grade against 65. Sometimes, it becomes desirable, if not necessary, to set up more sophisticated tests. Suppose, for exam- ple, that in Program 6.2 you want to count not the number of failing grades, but instead the number of grades that are between 70 and 79, inclusive. In such a case, you do not merely want to compare the value of grade against one limit, but against the two limits 70 and 79 to make certain that it falls within the specified range.
The C language provides the mechanisms necessary to perform these types of com- pound relational tests. A compound relational test is simply one or more simple relational tests joined by either the logical AND or the logical OR operator. These operators are rep- resented by the character pairs && and || (two vertical bar characters), respectively. As an example, the C statement
if ( grade >= 70 && grade <= 79 )
++grades_70_to_79;
increments the value of grades_70_to_79 only if the value of grade is greater than or equal to 70 and less than or equal to 79. In a like manner, the statement
if ( index < 0 || index > 99 )
printf (“Error – index out of range\n”);
causes execution of the printf statement if index is less than 0 or greater than 99.
The compound operators can be used to form extremely complex expressions in C. The C language grants the programmer ultimate flexibility in forming expressions. This flexibility is a capability that is often abused. Simpler expressions are almost always easier to read and debug.
When forming compound relational expressions, liberally use parentheses to aid read- ability of the expression and to avoid getting into trouble because of a mistaken assump- tion about the precedence of the operators in the expression.You can also use blank spaces to aid in the expression’s readability. An extra blank space around the && and || operators visually sets these operators apart from the expressions that are being joined by these operators.
To illustrate the use of a compound relational test in an actual program example, write a program that tests to see whether a year is a leap year. A year is a leap year if it is evenly divisible by 4. What you might not realize, however, is that a year that is divisible by 100 is not a leap year unless it also is divisible by 400.
Try to think how you would go about setting up a test for such a condition. First, you could compute the remainders of the year after division by 4, 100, and 400, and assign these values to appropriately named variables, such as rem_4, rem_100, and rem_400, respectively. Then, you could proceed to test these remainders to determine if the desired criteria for a leap year are met.
If you rephrase the previous definition of a leap year, you can say that a year is a leap year if it is evenly divisible by 4 and not by 100 or if it is evenly divisible by 400. Stop for a moment to reflect on this last sentence and to verify to yourself that it is equivalent to our previously stated definition. Now that you have reformulated our definition in these terms, it becomes a relatively straightforward task to translate it into a program statement as follows:
if ( (rem_4 == 0 && rem_100 != 0) || rem_400 == 0 )
printf (“It’s a leap year.\n”);
The parentheses around the subexpression
rem_4 == 0 && rem_100 != 0
are not required because that is how the expression will be evaluated anyway.
If you add a few statements in front of this test to declare your variables and to enable the user to key in the year from the terminal, you end up with a program that deter- mines if a year is a leap year, as shown in Program 6.5.
Program 6.5 Determining if a Year Is a Leap Year
// Program to determines if a year is a leap year
#include <stdio.h>
int main (void)
{
int year, rem_4, rem_100, rem_400;
printf (“Enter the year to be tested: “);
scanf (“%i”, &year);
rem_4 = year % 4;
rem_100 = year % 100;
rem_400 = year % 400;
if ( (rem_4 == 0 && rem_100 != 0) || rem_400 == 0 )
printf (“It’s a leap year.\n”);
else
printf (“Nope, it’s not a leap year.\n”);
return 0;
}
Program 6.5 Output
Enter the year to be tested: 1955
Nope, it’s not a leap year.
Program 6.5 Output (Rerun)
Enter the year to be tested: 2000
It’s a leap year.
Program 6.5 Output (Second Rerun)
Enter the year to be tested: 1800
Nope, it’s not a leap year.
The previous examples show a year that was not a leap year because it wasn’t evenly divisible by 4 (1955), a year that was a leap year because it was evenly divisible by 400 (2000), and a year that wasn’t a leap year because it was evenly divisible by 100 but not by 400 (1800). To complete the run of test cases, you should also try a year that is evenly divisible by 4 but not by 100. This is left as an exercise for you.
As mentioned previously, C gives you a tremendous amount of flexibility in forming expressions. For instance, in the preceding program, you did not have to calculate the intermediate results rem_4, rem_100, and rem_400—you could have performed the calcu- lation directly inside the if statement as follows:
if (( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 )
The use of blank spaces to set off the various operators still makes the preceding expres- sion readable. If you decide to ignore adding blanks and remove the unnecessary set of parentheses, you end up with an expression that looks like this:
if(year%4==0&&year%100!=0)||year%400==0)
This expression is perfectly valid and (believe it or not) executes identically to the expression shown immediately prior. Obviously, those extra blanks go a long way toward aiding understanding of complex expressions.
3. Nested if Statements
In the general format of the if statement, remember that if the result of evaluating the expression inside the parentheses is TRUE, the statement that immediately follows is executed. It is perfectly valid that this program statement be another if statement, as in the following statement:
if ( gameIsOver == 0 )
if ( playerToMove == YOU )
printf (“Your Move\n”);
If the value of gameIsOver is 0, the following statement is executed, which is another if statement. This if statement compares the value of playerToMove against YOU. If the two values are equal, the message “Your Move” is displayed at the terminal. Therefore, the printf statement is executed only if gameIsOver equals 0 and playerToMove equals YOU. In fact, this statement could have been equivalently formulated using compound rela- tionals as follows:
if ( gameIsOver == 0 && playerToMove == YOU )
printf (“Your Move\n”);
A more practical example of “nested” if statements is if you added an else clause to the previous example, as follows:
if ( gameIsOver == 0 )
if ( playerToMove == YOU )
printf (“Your Move\n”);
else
printf (“My Move\n”);
Execution of this statement proceeds as described previously. However, if gameIsOver equals 0 and the value of playerToMove is not equal to YOU, then the else clause is exe- cuted. This displays the message “My Move” at the terminal. If gameIsOver does not equal 0, the entire if statement that follows, including its associated else clause, is skipped.
Notice how the else clause is associated with the if statement that tests the value of playerToMove, and not with the if statement that tests the value of gameIsOver. The general rule is that an else clause is always associated with the last if statement that does not contain an else.
You can go one step further and add an else clause to the outermost if statement in the preceding example. This else clause is executed if the value of gameIsOver is not 0.
if ( gameIsOver == 0 )
if ( playerToMove == YOU )
printf (“Your Move\n”);
else
printf (“My Move\n”);
else
printf (“The game is over\n”);
The proper use of indentation goes a long way toward aiding your understanding of the logic of complex statements.
Of course, even if you use indentation to indicate the way you think a statement will be interpreted in the C language, it might not always coincide with the way that the compiler actually interprets the statement. For instance, removing the first else clause from the previous example
if ( gameIsOver == 0 )
if ( playerToMove == YOU )
printf (“Your Move\n”);
else
printf (“The game is over\n”);
does not result in the statement being interpreted as indicated by its format. Instead, this statement is interpreted as
if ( gameIsOver == 0 )
if ( playerToMove == YOU )
printf (“Your Move\n”);
else
printf (“The game is over\n”);
because the else clause is associated with the last un-elsed if.You can use braces to force a different association in those cases in which an innermost if does not contain an else, but an outer if does. The braces have the effect of “closing off ” the if statement. Thus,
if ( gameIsOver == 0 ) {
if ( playerToMove == YOU )
printf (“Your Move\n”);
}
else
printf (“The game is over\n”);
achieves the desired effect, with the message “The game is over” being displayed if the value of gameIsOver is not 0.
4. The else if Construct
You’ve seen how the else statement comes into play when you have a test against two possible conditions—either the number is even, else it is odd; either the year is a leap year, else it is not. However, programming decisions that you have to make are not always so black-and-white. Consider the task of writing a program that displays –1 if a number typed in by a user is less than zero, 0 if the number typed in is equal to zero, and 1 if the number is greater than zero. (This is actually an implementation of what is com- monly called the sign function.) Obviously, you must make three tests in this case—to determine if the number that is keyed in is negative, zero, or positive. Our simple if- else construct does not work. Of course, in this case, you could always resort to three separate if statements, but this solution does not always work in general—especially if the tests that are made are not mutually exclusive.
You can handle the situation just described by adding an if statement to your else clause. Because the statement that followed an else can be any valid C program state- ment, it seems logical that it can be another if. Thus, in the general case, you could write
if ( expression 1 )
program statement 1
else
if ( expression 2 )
program statement 2
else
program statement 3
which effectively extends the if statement from a two-valued logic decision to a three- valued logic decision.You can continue to add if statements to the else clauses, in the manner just shown, to effectively extend the decision to an n-valued logic decision.
The preceding construct is so frequently used that it is generally referred to as an else if construct and is usually formatted differently from that shown previously as
if ( expression 1 )
program statement 1
else if ( expression 2 )
program statement 2
else
program statement 3
This latter method of formatting improves the readability of the statement and makes it clearer that a three-way decision is being made.
Program 6.6 illustrates the use of the else if construct by implementing the sign function discussed earlier.
Program 6.6 Implementing the Sign Function
// Program to implement the sign function
#include <stdio.h>
int main (void)
{
int number, sign;
printf (“Please type in a number: “);
scanf (“%i”, &number);
if ( number < 0 )
sign = -1;
else if ( number == 0 )
sign = 0;
else // Must be positive
sign = 1;
printf (“Sign = %i\n”, sign);
return 0;
}
Program 6.6 Output
Please type in a number: 1121
Sign = 1
Program 6.6 Output (Rerun)
Please type in a number: -158
Sign = -1
Program 6.6 Output (Second Rerun)
Please type in a number: 0
Sign = 0
If the number that is entered is less than zero, sign is assigned the value –1; if the num- ber is equal to zero, sign is assigned the value 0; otherwise, the number must be greater than zero, so sign is assigned the value 1.
Program 6.7 analyzes a character that is typed in from the terminal and classifies it as either an alphabetic character (a–z or A–Z), a digit (0–9), or a special character (any- thing else). To read a single character from the terminal, the format characters %c are used in the scanf call.
Program 6.7 Categorizing a Single Character Entered at the Terminal
// Program to categorize a single character that is entered at the terminal
#include <stdio.h>
int main (void)
{
char c;
printf (“Enter a single character:\n”);
scanf (“%c”, &c);
if ( (c >= ‘a’ && c <= ‘z’) || (c >= ‘A’ && c <= ‘Z’) )
printf (“It’s an alphabetic character.\n”);
else if ( c >= ‘0’ && c <= ‘9’ )
printf (“It’s a digit.\n”);
else
printf (“It’s a special character.\n”);
return 0;
}
Program 6.7 Output
Enter a single character:
&
It’s a special character.
Program 6.7 Output (Rerun)
Enter a single character:
8
It’s a digit.
Program 6.7 Output (Second Rerun)
Enter a single character:
B
It’s an alphabetic character.
The first test that is made after the character is read in determines whether the char variable c is an alphabetic character. This is done by testing if the character is either a lowercase letter or an uppercase letter. The former test is made by the expression
( c >= ‘a’ && c <= ‘z’ )
which is TRUE if c is within the range of characters ‘a’ through ‘z’; that is, if c is a lowercase letter. The latter test is made by the expression
( c >= ‘A’ && c <= ‘Z’ )
which is TRUE if c is within the range of characters ‘A’ through ‘Z’; that is, if c is an uppercase letter. These tests work on all computer systems that store characters inside the machine in a format known as ASCII format.1
If the variable c is an alphabetic character, the first if test succeeds and the message It’s an alphabetic character. is displayed. If the test fails, the else if clause is executed. This clause determines if the character is a digit. Note that this test compares the character c against the characters ‘0’ and ‘9’ and not the integers 0 and 9. This is because a character was read in from the terminal, and the characters ‘0’ to ‘9’ are not the same as the numbers 0–9. In fact, on a computer system that uses the ASCII format mentioned previously, the character ‘0’ is actually represented internally as the number 48, the character ‘1’ as the number 49, and so on.
If c is a digit character, the phrase It’s a digit. is displayed. Otherwise, if c is not alphabetic and is not a digit, the final else clause is executed and displays the phrase It’s a special character. Execution of the program is then complete.
You should note that even though scanf is used here to read just a single character, the Enter (or Return) key must still be pressed after the character is typed to send the input to the program. In general, whenever you’re reading data from the terminal, the program doesn’t see any of the data typed on the line until the Enter key is pressed.
For your next example, suppose you want to write a program that allows the user to type in simple expressions of the form
number operator number
The program evaluates the expression and displays the results at the terminal, to two decimal places of accuracy. The operators that you want to have recognized are the nor- mal operators for addition, subtraction, multiplication, and division. Program 6.8 makes use of a large if statement with many else if clauses to determine which operation is to be performed.
Program 6.8 Evaluating Simple Expressions
/* Program to evaluate simple expressions of the form number operator number */
#include <stdio.h>
int main (void)
{
float value1, value2;
char operator;
printf (“Type in your expression.\n”);
scanf (“%f %c %f”, &value1, &operator, &value2);
if ( operator == ‘+’ )
printf (“%.2f\n”, value1 + value2);
else if ( operator == ‘-‘ )
printf (“%.2f\n”, value1 – value2);
else if ( operator == ‘*’ )
printf (“%.2f\n”, value1 * value2);
else if ( operator == ‘/’ )
printf (“%.2f\n”, value1 / value2);
return 0;
}
Program 6.8 Output
Type in your expression.
123.5 + 59.3
182.80
Program 6.8 Output (Rerun)
Type in your expression.
198.7 / 26
7.64
Program 6.8 Output (Second Rerun)
Type in your expression.
89.3 * 2.5
223.25
The scanf call specifies that three values are to be read into the variables value1, operator, and value2.A floating value can be read in with the %f format characters, the same characters used for the output of floating values. This is the format used to read in the value of the variable value1, which is the first operand of your expression.
Next, you want to read in the operator. Because the operator is a character (‘+’, ‘-‘,’*’, or ‘/’) and not a number, you read it into the character variable operator. The %c format characters tell the system to read in the next character from the terminal. The blank spaces inside the format string indicate that an arbitrary number of blank spaces are to be permitted on the input. This enables you to separate the operands from the operator with blank spaces when you type in these values. If you had specified the for- mat string “%f%c%f” instead, no spaces would have been permitted after typing in the first number and before typing in the operator. This is because when the scanf function is reading a character with the %c format characters, the next character on the input, even if it is a blank space, is the character that is read. However, it should be noted that, in gen- eral, the scanf function always ignores leading spaces when it is reading in either a deci- mal or floating-point number. Therefore, the format string “%f %c%f” would have worked just as well in the preceding program.
After the second operand has been keyed in and stored in the variable value2, the program proceeds to test the value of operator against the four permissible operators. When a correct match is made, the corresponding printf statement is executed to dis- play the results of the calculation. Execution of the program is then complete.
A few words about program thoroughness are in order at this point. While the pre- ceding program does accomplish the task that it was set to perform, the program is not really complete because it does not account for mistakes made by the user. For example, what happens if the user types in a ? for the operator by mistake? The program simply “falls through” the if statement and no messages ever appear at the terminal to alert the user that he incorrectly typed in his expression.
Another case that is overlooked is when the user types in a division operation with zero as the divisor.You know by now that you should never attempt to divide a number by zero in C. The program should check for this case.
Trying to predict the ways that a program can fail or produce unwanted results and then taking preventive measures to account for such situations is a necessary part of pro- ducing good, reliable programs. Running a sufficient number of test cases against a pro- gram often points the finger to portions of the program that do not account for certain cases. But it goes further than that. It must become a matter of self-discipline while cod- ing a program to always say “What would happen if …” and to insert the necessary pro- gram statements to handle the situation properly.
Program 6.8A, a modified version of Program 6.8, accounts for division by zero and the keying in of an unknown operator.
Program 6.8A Revising the Program to Evaluate Simple Expressions
/* Program to evaluate simple expressions of the form
value operator value */
#include <stdio.h>
int main (void)
{
float value1, value2;
char operator;
printf (“Type in your expression.\n”);
scanf (“%f %c %f”, &value1, &operator, &value2);
if ( operator == ‘+’ )
printf (“%.2f\n”, value1 + value2);
else if ( operator == ‘-‘ )
printf (“%.2f\n”, value1 – value2);
else if ( operator == ‘*’ )
printf (“%.2f\n”, value1 * value2);
else if ( operator == ‘/’ )
if ( value2 == 0 )
printf (“Division by zero.\n”);
else
printf (“%.2f\n”, value1 / value2);
else
printf (“Unknown operator.\n”);
return 0;
}
Program 6.8A Output
Type in your expression.
123.5 + 59.3
182.80
Program 6.8A Output (Rerun)
Type in your expression.
198.7 / 0
Division by zero.
Program 6.8A Output (Second Rerun)
Type in your expression.
125 $ 28
Unknown operator.
When the operator that is typed in is the slash, for division, another test is made to determine if value2 is 0. If it is, an appropriate message is displayed at the terminal. Otherwise, the division operation is carried out and the results are displayed. Pay careful attention to the nesting of the if statements and the associated else clauses in this case.
The else clause at the end of the program catches any “fall throughs.” Therefore, any value of operator that does not match any of the four characters tested causes this else clause to be executed, resulting in the display of “Unknown operator.”
Source: Kochan Stephen G. (2004), Programming in C: A Complete Introduction to the C Programming Language, Sams; Subsequent edition.