The ! Operator
So far we have used only the logical operators && and ||. The third logical operator is the NOT operator, written as !. This operator reverses the result of the expression it operates on. For example, if the expression evaluates to a non-zero value, then applying ! operator to it results into a 0. Vice versa, if the expression evaluates to zero then on applying ! operator to it makes it 1, a non-zero value. The final result (after applying !) 0 or 1 is considered to be false or true respectively. Here is an example of the NOT operator applied to a relational expression.
! ( y < 10 )
This means “not y less than 10”. In other words, if y is less than 10, the expression will be false, since ( y < 10 ) is true. We can express the same condition as ( y >= 10 ).
The NOT operator is often used to reverse the logical value of a single variable, as in the expression
if ( ! flag )
This is another way of saying
if ( flag == 0 )
Does the NOT operator sound confusing? Avoid it if you want, as the same thing can be achieved without using the NOT operator.
Hierarchy of Operators Revisited
Since we have now added the logical operators to the list of operators we know, it is time to review these operators and their priorities. Figure 2.7 summarizes the operators we have seen so far. The higher the position of an operator is in the table, higher is its priority. (A full-fledged precedence table of operators is given in Appendix A.)
Operators
Type
!
Logical NOT
* / %
Arithmetic and modulus
+ -
Arithmetic
< > <= >=
Relational
== !=
Relational
&&
Logical AND
||
Logical OR
=
Assignment
Figure 2.7
A Word of Caution
What will be the output of the following program:
main( )
{
int i ;
printf ( "Enter value of i " ) ;
scanf ( "%d", &i ) ;
if ( i = 5 )
printf ( "You entered 5" ) ;
else
printf ( "You entered something other than 5" ) ;
}
And here is the output of two runs of this program...
Enter value of i 200
You entered 5
Enter value of i 9999
You entered 5
Surprising? You have entered 200 and 9999, and still you find in either case the output is ‘You entered 5’. This is because we have written the condition wrongly. We have used the assignment operator = instead of the relational operator ==. As a result, the condition gets reduced to if ( 5 ), irrespective of what you supply as the value of i. And remember that in C ‘truth’ is always non-zero, whereas ‘falsity’ is always zero. Therefore, if ( 5 ) always evaluates to true and hence the result.
Another common mistake while using the if statement is to write a semicolon (;) after the condition, as shown below:
main( )
{
int i ;
printf ( "Enter value of i " ) ;
scanf ( "%d", &i ) ;
if ( i == 5 ) ;
printf ( "You entered 5" ) ;
}
The ; makes the compiler to interpret the statement as if you have written it in following manner:
if ( i == 5 )
;
printf ( "You entered 5" ) ;
Here, if the condition evaluates to true the ; (null statement, which does nothing on execution) gets executed, following which the printf( ) gets executed. If the condition fails then straightaway the printf( ) gets executed. Thus, irrespective of whether the condition evaluates to true or false the printf( ) is bound to get executed. Remember that the compiler would not point out this as an error, since as far as the syntax is concerned nothing has gone wrong, but the logic has certainly gone awry. Moral is, beware of such pitfalls.
The following figure summarizes the working of all the three logical operators.
Operands