Which Is Bigger: Using Relational Operators and Expressions

I l @ ve RuBoard

Which Is Bigger: Using Relational Operators and Expressions

Because while loops often rely on test expressions that make comparisons, comparison expressions merit a closer look. Such expressions are termed relational expressions , and the operators that appear in them are called relational operators . You have used several already, and Table 6.1 gives a complete list of C relational operators. This table pretty much covers all the possibilities for numerical relationships. ( Numbers , even complex ones, are less complex than humans .)

Table  6.1. Relational operators.
Operator Meaning
< Is less than
<= Is less than or equal to
== Is equal to
<= Is greater than or equal to
> Is greater than
!= Is not equal to

The relational operators are used to form the relational expressions used in while statements and in other C statements that we'll discuss later. These statements check to see whether the expression is true or false. Here are three unrelated statements containing examples of relational expressions. The meaning, we hope, is clear.

 while (number < 6) {     printf("Your number is too small.\n");     scanf("%d", &number); } while (ch != '$') {      count++;      scanf("%c", &ch); } while (scanf("%f", &num) == 1)     sum = sum + num; 

Note in the second example that the relational expressions can be used with characters , too. The machine code (which we have been assuming is ASCII) is used for the comparison. However, you can't use the relational operators to compare strings. Chapter 11, "Character Strings and String Functions," will show you what to use for strings.

The relational operators can be used with floating-point numbers, too. Beware, though; you should limit yourself to using only < and > in floating-point comparisons. The reason is that round-off errors can prevent two numbers from being equal, even though logically they should be. For example, certainly the product of 3 and 1/3 is 1.0. If you express 1/3 as a six-place decimal fraction, the product is .999999, which is not quite equal to 1. The fabs() function, declared in the math.h header file, can be handy for floating-point tests. This function returns the absolute value of a floating-point value, that is, the value without the algebraic sign. For example, you could test whether a number was close to a desired result with something like this:

 #include <math.h> #include <stdio.h> ... const double ANSWER = 3.14159; double response; printf("What is the value of pi?\n"); scanf("%lf", &response); while (fabs(response - ANSWER) > 0.0001) {     printf("Try again!\n");     scanf("%lf", &response); } 

This loop continues to elicit a response until the user gets within 0.0001 of the correct value.

Each relational expression is judged to be "true" or "false" (but never "maybe"). This raises an interesting question.

What Is Truth?

You can answer this age-old question, at least as far as C is concerned . Recall that an expression in C always has a value. This is true even for relational expressions, as the example in Listing 6.5 shows. In it, you print the values of two relational expressions, one true and one false.

Listing 6.5 The t_and_f.c program.
 /* t_and_f.c -- true and false values in C */ #include <stdio.h> int main(void) {   int true, false;   true = (10 > 2);    /* value of a true relationship  */   false = (10 == 2);  /* value of a false relationship */   printf("true = %d; false = %d \n", true, false);   return 0; } 

Listing 6.5 assigns the values of two relational expressions to two variables . Being straightforward, it assigns true the value of a true expression, and false the value of a false expression. Running the program produces the following simple output:

 true = 1; false = 0 

Aha! For C, a true expression has the value 1 , and a false expression has the value . Indeed, some C programs use the following construction for loops that are meant to run forever because 1 always is true:

 while (1) {   ... } 

What Else Is True?

If you can use a 1 or a as a while statement test expression, can you use other numbers? If so, what happens? Let's experiment by trying the program in Listing 6.6.

Listing 6.6 The truth.c program.
 /* truth.c -- what values are true? */ #include <stdio.h> int main(void) {   int n = 3;   while (n)        printf("%d\n", n--);   n = -3;   while (n)        printf("%2d\n", n++);   return 0; } 

Here are the results:

 3 2 1 -3 -2 -1 

The first loop executes when n is 3 , 2 , and 1 , but terminates when n is . Similarly, the second loop executes when n is -3 , -2 , and -1 , but terminates when n is . More generally , all nonzero values are regarded as "true," and only is recognized as "false." C has a very tolerant notion of truth!

Alternatively, you can say that a while loop executes as long as its test condition evaluates to nonzero. This puts test conditions on a numeric basis instead of a true-false basis. Keep in mind that relational expressions evaluate to 1 if true and to if false, so such expressions really are numeric.

Many programmers make use of this property of test conditions. For example, the phrase while (goats != 0) can be replaced by while (goats) because the expression (goats != 0) and the expression (goats) both become , or false, only when goats has the value . We think that the second form is not as clear in meaning as the first, but many C programmers prefer the second form. The popular thought has been that the second form is more efficient because it requires fewer computer processing operations when the program runs, but some compilers are clever enough to use the same efficient code for either form. The current tendency is to try for clear code and leave it to clever compilers to maximize the efficiency.

Troubles with Truth

C's tolerant notion of truth can lead to trouble. For example, let's make one subtle change in Listing 6.1, producing the program shown in Listing 6.7.

Listing 6.7 The trouble.c program.
 /* trouble.c -- misuse of = */ #include <stdio.h> int main(void) {   long num;   long sum = 0L;   int status;   printf("Please enter an integer to be summed. ");   printf("Enter q to quit.\n");   status = scanf("%ld", &num);   while (status = 1)   {         sum = sum + num;         printf("Please enter next integer to be summed. ");         printf("Enter q to quit.\n");         status = scanf("%ld", &num);   }   printf("Those integers sum to %ld\n", sum);   return 0; } 

Running Listing 6.7 produces output like the following:

 Please enter an integer to be summed. Enter q to quit.  20  Please enter next integer to be summed. Enter q to quit.  5  Please enter next integer to be summed. Enter q to quit.  30  Please enter next integer to be summed. Enter q to quit.  q  Please enter next integer to be summed. Enter q to quit. Please enter next integer to be summed. Enter q to quit. Please enter next integer to be summed. Enter q to quit. Please enter next integer to be summed. Enter q to quit. 

(And so on until you kill the program.)

This troublesome example made a change in the while test condition, replacing status == 1 with status = 1 . The second statement is an assignment statement, so it gives status the value 1 . Furthermore, the value of an assignment statement is the value of the left side, so status = 1 has the same numerical value of 1 . So for all practical purposes, the while loop is the same as using while (1) ; that is, it is a loop that never quits. You enter q , and status is set to , but the loop test resets status to 1 and starts another cycle.

You might wonder why, because the program keeps looping, the user doesn't get a chance to type in any more input after entering q . When scanf() fails to read the specified form of input, it leaves the nonconforming input in place to be read the next time. When scanf() tries to read the q as an integer and fails, therefore, it leaves the q there. During the next loop cycle, scanf() attempts to read where it left off the last time: at the q once again. Once again, scanf() fails to read the q as an integer, so not only does this example set up an infinite loop, it also creates a loop of infinite failure, a daunting concept. It is fortunate that computers, as yet, lack feelings. Following stupid instructions eternally is no better or worse to a computer than successfully predicting the stock market for the next ten years .

Don't use = for == . Some computer languages (BASIC, for example) do use the same symbol for both the assignment operator and the relational equality operator, but the two operations are quite different (see Figure 6.2). The assignment operator assigns a value to the left-hand variable. The relational equality operator, however, checks to see whether the left-hand and right-hand sides are already equal. It doesn't change the value of the left-hand variable, if one is present.

Figure 6.2. The relational operator == and the assignment operator =.
graphics/06fig02.jpg
 canoes = 5            <--Assigns the value 5 to canoes canoes == 5           <--Checks to see whether canoes has the value 5 

Be careful about using the correct operator. A compiler will let you use the wrong form, yielding results other than what you expect.

To sum up, the relational operators are used to form relational expressions. Relational expressions have the value 1 if true and 0 if false. Statements (such as while and if ) that normally use relational expressions as tests can use any expression as a test, with non-zero values recognized as "true" and zero values as "false."

Precedence of Relational Operators

The precedence of the relational operators is less than that of the arithmetic operators, including + and - , and greater than that of assignment operators. This means, for example, that

 x > y + 2 

means the same as

 x > (y + 2) 

and that

 x = y > 2 

means

 x = (y > 2) 

That is, x is assigned 1 if y is greater than 2 and is otherwise ; x is not assigned the value of y .

The relational operators are themselves organized into two different priorities.

 Higher-priority group:      <   <=   >   >= Lower-priority group:       ==         != 

Like most other operators, the relational operators associate from left to right. Therefore,

 ex != wye == zee 

is the same as

 (ex != wye) == zee 

First, C checks to see if ex and wye are unequal . Then the resulting value of 1 or (true or false) is compared to the value of zee . We don't anticipate using this sort of construction, but we feel it is our duty to point out such sidelights.

Table 6.2 shows the priorities of the operators introduced so far, and Appendix B, "C Operators," has a complete precedence ranking of all operators.

Table  6.2. Operator precedence.
Operators (From High to Low Precedence) Associativity
() L-R
- + ++ -- sizeof (type) (all unary) R-L
* / % L-R
+ - L-R
< > <= >= L-R
== != L-R
= R-L

Summary: The while Statement

Keyword:

 while 

General Comments:

The while statement creates a loop that repeats until the test expression becomes false, or zero. The while statement is an entry-condition loop; that is, the decision to go through one more pass of the loop is made before the loop is traversed. Therefore, it is possible that the loop is never traversed. The statement part of the form can be a simple statement or a compound statement.

Form:

 while      (expression)              statement 

The statement portion is repeated until the expression becomes false or zero.

Examples:

 while (n++ < 100)    printf(" %d %d\n" ,n, 2 * n + 1); /* single statement */    while (fargo < 1000) {                               /* compound statement */    fargo = fargo + step;    step = 2 * step; 

Summary: Relational Operators and Expressions

Relational Operators:

Each relational operator compares the value at its left to the value at its right.

< Is less than
<= Is less than or equal to
== Is equal to
>= Is greater than or equal to
> Is greater than
!= Is unequal to

Relational Expressions:

A simple relational expression consists of a relational operator with an operand on each side. If the relation is true, the relational expression has the value 1. If the relation is false, the relational expression has the value 0.

Examples:

 5 > 2 is true and has the value 1. (2 + a) == a is false and has the value 0. 
I l @ ve RuBoard


C++ Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 314
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net