Page 152 - Introduction to Programming with Java: A Problem Solving Approach
P. 152
118 Chapter 4 Control Statements
There are three main categories of errors—compile-time errors, runtime errors, and logic errors. A compile-time error is an error that is identified by the compiler during the compilation process. A runtime error is an error that occurs while a program is running and it causes the program to terminate abnormally. The compiler generates an error message for a compile-time error, and the Java Virtual Machine (JVM) generates an error message for a runtime error. Unfortunately, there are no error messages for a logic error. It’s up to the programmer to fix logic errors by analyzing the output and thinking carefully about the code.
4.6 ! Logical Operator
Now it’s time to consider the logical “not” operator (!). Assume that you have a char variable named resp that contains (1) a lowercase or uppercase ‘q’ if the user wants to quit or (2) some other character if the user wants to continue. This time, the goal is to print “Let’s get started. . . .” if resp contains anything other than a lowercase or uppercase “q.” You could use an “if, else” statement with an empty “if” block like this:
if (resp == 'q' || resp == 'Q')
{}
else
{
System.out.println("Let's get started. . . .");
.. .
But this is not very elegant. ProgArapmmaegrsoftenPusDe tFhe terEmnelehgaantntocdeescribe code that is well written and has “beauty.” More specifically, elegant code is easy to understand, easy to update, robust, reasonably compact, and efficient. The above code’s empty “if” block is inelegant because it’s not compact. If you ever have an empty “if” block with a nonempty “else” block, you should try to rewrite it as just an “if” block with no “else” block. The trick is to invert the if statement’s condition. In the above example, that means testing for the absence of lowercase or uppercase ‘q’ rather than the presence of lowercase or uppercase ‘q.’ To test for the absence of lowercase or uppercase ‘q,’ use the ! operator.
The ! operator changes true values into false values and vice versa. This true-to-false, false-to-true toggling functionality is referred to as a “not” operation, and that’s why the ! operator is called the “not” operator. Since we want to print “Let’s get started. . . .” if the above if statement’s condition is not true, we insert ! at the left of the condition like this:
if (!(resp == 'q' || resp == 'Q'))
{
System.out.println("Let's get started. . . .");
.. .
Note that the ! is inside one set of parentheses and outside another set. Both sets of parentheses are re- quired. The outer parentheses are necessary because the compiler requires parentheses around the entire condition. The inner parentheses are also necessary because without them, the ! operator would operate on the resp variable instead of on the entire condition. Why? Because the operator precedence table (Fig- ure 4.6) shows that the ! operator has higher precedence than the == and || operators. The way to force the == and || operators to be executed first is to put them inside parentheses.
Don’t confuse the ! (not) operator with the != (inequality) operator. The ! operator returns the oppo- site value of the given expression (a true expression returns false and a false expression returns true). The != operator asks a question—are the two expressions unequal?