We all face situations in real-life where the action that we carry out is based on multiple conditions. For example, I will join a

company if the company allocates a metro location, gives me a good pay package and permits a joining period of 4 weeks. In programming too action performed may be based on result of multiple conditions. Such programming situations can be handled elegantly using Logical Operators. This chapter also explores the use of another type of operators called Conditional Operators.

Use of Logical Operators

C allows usage of three logical operators, namely, &&, || and !. These are to be read as ‘AND’, ‘OR’ and ‘NOT’, respectively.

There are several things to note about these logical operators. Most obviously, two of them are composed of double symbols: || and &&. Don’t use the single symbol | and &. These single symbols also have a meaning. They are bitwise operators, which we would examine in Chapter 21.

The first two operators, && and ||, allow two or more conditions to be combined in an if statement. Let us see how they are used in a program. Consider the following example:

Example 4.1:

The marks obtained by a student in 5 different subjects are input through the keyboard. The student gets a division as per the following rules:

Percentage above or equal to 60 - First division Percentage between 50 and 59 - Second division Percentage between 40 and 49 - Third division Percentage less than 40 - Fail

Write a program to calculate the division obtained by the student.

There are two ways in which we can write a program for this example. These methods are given below.

/* Method – I */

 # include <stdio.h>
  int main( )
   {
     int m1, m2, m3, m4, m5, per ;
     printf ( "Enter marks in five subjects " ) ;
     scanf ( "%d %d %d %d %d", &m1, &m2, &m3, &m4, &m5 ) ;
     per = ( m1 + m2 + m3 + m4 + m5 ) * 100 / 500 ;
      if ( per >= 60 )
       printf ( "First division\\n" ) ;
      else
       {
        if ( per >= 50 )
        printf ( "Second division\\n" ) ;
        else
        {
            if ( per >= 40 )
            printf ( "Third division\\n" ) ;
            else printf ( "Fail\\n" ) ;
        }
       }
       return 0 ;
    }

This is a straight-forward program. Observe that the program uses nested if-elses. Though the program works fine, it has three disadvantages:

All these three problems can be eliminated by usage of ‘Logical Operators’. The following program illustrates this:

/* Method – II */

 # include <stdio.h>
  int main( )
  {
    int m1, m2, m3, m4, m5, per ;
    printf ( "Enter marks in five subjects " ) ;
    scanf ( "%d %d %d %d %d", &m1, &m2, &m3, &m4, &m5 ) ;
    per = ( m1 + m2 + m3 + m4 + m5 ) / 500 * 100 ;
     if ( per >= 60 )
     {
      printf ( "First division\\n" ) ;
     }
     if ( ( per >= 50 ) && ( per < 60 ) )
     {
      printf ( "Second division\\n" ) ;
     }
     if ( ( per >= 40 ) && ( per < 50 ) )
     {
      printf ( "Third division\\n" ) ;
     }
     if ( per < 40 )
     {
      printf ( "Fail\\n" ) ;
     }
     return 0 ;
  }

As can be seen from the second if statement, the && operator is used to combine two conditions. ‘Second division’ gets printed if both the conditions evaluate to true. If one of the conditions evaluate to false then the whole thing is treated as false.

Two distinct advantages can be cited in favor of this program:

There is a negative side to the program too. Even if the first condition turns out to be true, still all other conditions are checked. This will

increase the time of execution of the program. This can be avoided using the else if clause discussed in the next section.

The else if Clause

There is one more way in which we can write program for Example 4.1. This involves usage of else if blocks as shown below.

/* else if ladder demo */


# include <stdio.h>

int main( )
{
int m1, m2, m3, m4, m5, per ;
per = ( m1+ m2 + m3 + m4+ m5 ) / 500 * 100 ;
if ( per >= 60 )
printf ( "First division\\n" ) ;
else if ( per >= 50 )
printf ( "Second division\\n" ) ;
else if ( per >= 40 )
printf ( "Third division\\n" ) ;
else printf ( "fail\\n" ) ;
return 0 ;
}


You can note that this program reduces the indentation of the statements. In this case, every **else** is associated with its previous **if**. The last **else** goes to work only if all the conditions fail. Also, if a condition is satisfied, other conditions below it are not checked. Even in **else if** ladder, the last **else** is optional.

## Using of Logical Operation -Yes / No Problem

Another place where logical operators are useful is when we want to write programs for complicated logics that ultimately boil down to only two answers. For example, consider the following example:

**Example 4.2:** A company insures its drivers in the following cases:

- If the driver is married.
- If the driver is unmarried, male & above 30 years of age.
- If the driver is unmarried, female & above 25 years of age.

In all other cases, the driver is not insured. If the marital status, sex and age of the driver are the inputs, write a program to determine whether the driver should be insured or not.

Here after checking a complicated set of instructions the final output of the program would be one of the twoeither the driver should be insured or the driver should not be insured. As mentioned above, since these are the only two outcomes this problem can be solved using logical operators. But before we do that, let us write a program that does not make use of logical operators.

/* Insurance of driver - without using logical operators */

```c
 # include <stdio.h>
 int main( )
 {
     char sex, ms ;
     int age ;
     printf ( "Enter age, sex, marital status " ) ;
     scanf ( "%d %c %c", &age, &sex, &ms ) ;
     if ( ms == 'M' )
     printf ( "Driver should be insured\\n" ) ;
     else
     {
         if ( sex == 'M' )
         {
             if ( age > 30 )
              printf ( "Driver should be insured\\n" ) ;
            else
             printf ( "Driver should not be insured\\n" ) ;
         }
         else
         {
             if ( age > 25 )
              printf ( "Driver should be insured\\n" ) ;
             else
              printf ( "Driver should not be insured\\n" ) ;
         }
     }
  return 0 ;
}

From the program it is evident that we are required to match several ifs and elses and several pairs of braces. In a more real-life situation there would be more conditions to check leading to the program creeping to the right. Let us now see how to avoid these problems by using logical operators.

As mentioned above, in this example, we expect the answer to be either ‘Driver should be insured’ or ‘Driver should not be insured’. If we list down all those cases in which the driver is insured, then they would be:

Since all these cases lead to the driver being insured, they can be combined together using && and || as shown in the program below.

/* Insurance of driver - using logical operators */

# include <stdio.h>
int main( )
{
   char sex, ms ;
   int age ;
   printf ( "Enter age, sex, marital status " ) ;
   scanf ( "%d %c %c", &age, &sex, &ms ) ;
   if ( ( ms == 'M') || ( ms == 'U' && sex == 'M' && age > 30 ) || ( ms == 'U' && sex == 'F' && age > 25 ) )
   printf ( "Driver should be insured\\n" ) ;
   else
    printf ( "Driver should not be insured\\n" ) ;
   return 0 ;
 }

In this program, it is important to note that:

Thus, we can conclude that the && and || are useful in the following programming situations:

In some programming situations we may combine the usage of if— else if—else and logical operators. This is demonstrated in the following program.

Example 4.3: Write a program to calculate the salary as per the following table:

Gender Years of Service Qualifications Salary
Male >=10 Post-Graduate 15000
>=10 Graduate 10000
<10 Post-Graduate 10000
<10 Graduate 7000
Female >=10 Post-Graduate 12000
>=10 Graduate 9000
<10 Post-Graduate 10000
<10 Graduate 6000

Figure 4.1

# include <stdio.h>
int main( )
{
    char g ;
    int yos, qual, sal = 0 ;
    printf ( "Enter Gender, Years of Service and Qualifications ( 0 = G, 1 = PG ):" ) ;
    scanf ( "%c%d%d", &g, &yos, &qual ) ;
    if ( g == 'm' && yos >= 10 && qual == 1 )
     sal = 15000 ;
    else if ( ( g == 'm' && yos >= 10 && qual == 0 ) || ( g == 'm' && yos < 10 && qual == 1 ) )
     sal = 10000 ;
    else if ( g == 'm' && yos < 10 && qual == 0 )
    sal = 7000 ;
    else if ( g == 'f' && yos >= 10 && qual == 1 )
    sal = 12000 ;
    else if ( g == 'f' && yos >= 10 && qual == 0 )
    sal = 9000  ;
    else if ( g == 'f' && yos < 10 && qual == 1 )
    sal = 10000 ;
    else if ( g == 'f' && yos < 10 && qual == 0 )
    sal = 6000 ;
    printf ( "\\nSalary of Employee = %d\\n", sal ) ;
    return 0 ;
 }

I hope you can follow the implementation of this program on your own.

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 4.2 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 B.)

|

Operands Results

x y !x !y x && y x || y

0 0 1 1 0 0

0 non-zero 1 0 0 1

non-zero 0 0 1 0 1

non-zero non-zero 0 0 1 1

Figure 4.2

A Word of Caution Can you guess what will be the output of the following program?

# include <stdio.h>
int main( )
{
    int i ;
     printf ( "Enter value of i " ) ;
     scanf ( "%d", &i ) ;
     if ( i = 5 )
      printf ( "You entered 5\\n" ) ;
     else
      printf ( "You entered something other than 5\\n" ) ;
     return 0 ;
}

Well, 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

Surprised? 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.

# include <stdio.h>
int main( )
{
    int i ;
    printf ( "Enter value of i " ) ;
    scanf ( "%d", &i ) ;
    if ( i == 5 ) ;
    printf ( "You entered 5\\n" ) ;
    return 0 ;
}

The ; makes the compiler to interpret the statement as if you have written it in following manner:

if (i == 5);
printf("You entered 5\\n");

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. So, irrespective of whether the condition evaluates to true or false, printf( ) is bound to get executed. Remember that 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.

Operators Type
! Logical NOT
* / % Arithmetic and modulus
+ - Arithmetic
<> <= >= Relational
== != Relational
&& Logical AND
logical OR
= Assignment

Figure 4.3

The Conditional Operators

The conditional operators ? and : are sometimes called ternary operators since they take three arguments. In fact, they form a kind of foreshortened if-then-else. Their general form is,

expression 1 ? expression 2 : expression 3

What this expression says is: “if expression 1 is true (that is, if its value is non-zero), then the value returned will be expression 2, otherwise the value returned will be expression 3”. Let us understand this with the help of a few examples.

This statement will store 3 in y if x is greater than 5, otherwise it will store 4 in y.

The equivalent if-else form would be,

if ( x > 5 )
 y = 3 ;
else y = 4 ;
char a ;
int y ;
scanf ( "%c", &a ) ;
y = ( a >= 65 && a <= 90 ? 1 : 0 ) ;

Here 1 would be assigned to y if a >=65 && a <=90 evaluates to true, otherwise 0 would be assigned.

The following points may be noted about the conditional operators:

Ex.:

int i ;
scanf ( "%d", &i ) ;
( i == 1 ? printf ( "Amit" ) : printf ( "All and sundry" ) ) ;
 Ex.:
char a = 'z' ;
printf ( "%c", ( a >= 'a' ? a : '!' ) ) ;

int big, a, b, c ; big = ( a > b ? ( a > c ? 3: 4 ) : ( b > c ? 6: 8 ) ) ;

a > b ? g = a : g = b ;

This will give you an error ‘Lvalue Required’. The error can be overcome by enclosing the statement in the : part within a pair of parentheses. This is shown below.

a > b ? g = a : ( g = b ) ;

In absence of parentheses, the compiler believes that b is being assigned to the result of the expression to the left of second =. Hence it reports an error.

The limitation of the conditional operators is that after the ? or after the : , only one C statement can occur. In practice, rarely does this requirement exist. Therefore, in serious C programming, conditional operators aren’t as frequently used as the if-else.

Summary

Exercise

[A] If a = 10, b = 12, c = 0, find the values of the expressions in the following table:

Expression

a != 6 && b > 5 a == 9 || b < 3 ! ( a < 10 ) ! ( a > 5 && c ) 5 && c != 8 || !c

[B] What will be the output of the following programs: -(1)

# include <stdio.h>
int main( )
{
     int i = 4, z = 12 ;
     if ( i = 5 || z > 50 )
     printf ( "Dean of students affairs\\n" ) ;
     else
     printf ( "Dosa\\n" ) ;
     return 0 ;
}

-(2)

#include <stdio.h>
int main( )
{
    int i = 4, j = -1, k = 0, w, x, y, z ;
    w = i || j || k ; x = i && j && k ; y = i || j && k ; z = i && j || k ;
    printf ( "w = %d x = %d y = %d z = %d\\n", w, x, y, z ) ;
    return 0 ;
 }

-(3)

# include <stdio.h>
int main( )
{
    int x = 20, y = 40, z = 45 ;
    if ( x > y && x > z )
    printf ( "biggest = %d\\n", x ) ;
    else if ( y > x && y > z )
    printf ( "biggest = %d\\n", y ) ;
    else if ( z > x && z > y )
    printf ( "biggest = %d\\n", z ) ;
    return 0 ;
}

-(4)

# include <stdio.h>
int main( )
{
     int i = -1, j = 1, k, l ;
     k = !i && j ; l = !i || j ;
     printf ( "%d %d\\n", i, j ) ;
     return 0 ;
}

-(5)

# include <stdio.h>
int main( )
{
     int i = -4, j, num ;
      j = ( num < 0 ? 0 : num * num ) ;
      printf ( "%d\\n", j ) ;
      return 0 ;
}

-(6)

# include <stdio.h>
int main( )
{
     int k, num = 30 ;
     k = ( num > 5 ? ( num <= 10 ? 100 : 200 ) : 500 ) ;
     printf ( "%d\\n", num ) ;
     return 0 ;
}

[C] Point out the errors, if any, in the following programs:

-(1)

# include <stdio.h>
int main( )
{
     int code, flag ;
     if ( code == 1 & flag == 0 )
     printf ( "The eagle has landed\\n" ) ;
     return 0 ;
}

-(2)

# include <stdio.h>
int main( )
{
    char spy = 'a', password = 'z' ;
    if ( spy == 'a' or password == 'z' )
    printf ( "All the birds are safe in the nest\\n" ) ;
    return 0 ;
 }

-(3)

# include <stdio.h>
int main( )
{
    int i = 10, j = 20 ;
    if ( i = 5 ) && if ( j = 10 )
    printf ( "Have a nice day\\n" ) ;
    return 0 ;
 }

-(4)

# include <stdio.h>
int main( )
{
    int x = 10, y = 20 ;
    if ( x >= 2 and y <= 50 )
    printf ( "%d\\n", x ) ;
    return 0 ;
 }

-(5)

# include <stdio.h>
int main( )
{
     int x = 2 ;
     if ( x == 2 && x != 0 ) ;
     printf ( "Hello\\n" ) ;
     else printf ( "Bye\\n" ) ;
     return 0 ;
}

-(6)

# include <stdio.h>
int main( )
{
     int i = 10, j = 10 ;
     if ( i && j == 10 )
     printf ( "Have a nice day\\n" ) ;
     return 0 ;
}

-(7)

# include <stdio.h>
int main( )
{
     int j = 65 ;
     printf ( "j >= 65 ? %d : %c\\n", j ) ;
     return 0 ;
}

-(8)

# include <stdio.h>
int main( )
{
     int i = 10, j ;
     i >= 5 ? j = 10 : j = 15 ;
     printf ( "%d %d\\n", i, j ) ;
     return 0 ;
}

-(9)

# include <stdio.h>
int main( )
{
     int a = 5, b = 6 ;
     ( a == b ? printf ( "%d\\n", a ) ) ;
      return 0 ;
}

-(10)

# include <stdio.h>
int main( )
{
     int n = 9 ;
     ( n == 9 ? printf ( "Correct\\n" ) ; : printf ( "Wrong\\n" ) ; ) ;
      return 0 ;
}

[D] Attempt the following:

The following table shows the range of ASCII values for various characters:

Characters

A – Z a – z 0 – 9 special symbols

ASCII Values

65 – 90 97 – 122 48 – 57 0 - 47, 58 - 64, 91 - 96, 123 - 127

The grades are as follows:

Grade is 10 if all three conditions are met Grade is 9 if conditions (i) and (ii) are met Grade is 8 if conditions (ii) and (iii) are met Grade is 7 if conditions (i) and (iii) are met Grade is 6 if only one condition is met Grade is 5 if none of the conditions are met

Write a program, which will require the user to give values of hardness, carbon content and tensile strength of the steel under consideration and output the grade of the steel.

Boxer Class

Flyweight Bantamweight Featherweight Middleweight Heavyweight

Weight in Pounds

< 115 115 - 121 122 - 153 154 – 189 >= 190

 255/,255/,255/Re BlueGreendMaxWhite

Note that if the RGB values are all 0, then the CMY values are all 0 and the K value is 1.

Sun Sign

Capricorn Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius

From - To

December 22 - January 19 January 20 - February 17 February 18 - March 19 March 20 - April 19 April 20 - May 20 May 21 - June 20 June 21 - July 22 July 23 - August 22 August 23 - September 22 September 23 - October 22 October 23 - November 21 November 22 - December 21

 

  

  

White

dWhite Cyan

255/Re

 

  

  

White

GreenWhite Magenta

255/

 

  

  

White

BlueWhite Yellow

255/

WhiteBlack 1

BMI Category

Starvation Anorexic Underweight Ideal Overweight Obese Morbidly Obese

BMI

< 15 15.1 to 17.5 17.6 to 18.5 18.6 to 24.9 25 to 25.9 30 to 30.9 >= 40

[E] Attempt the following:

(1) Whether the character entered through the keyboard is a lower case alphabet or not.

(2) Whether a character entered through the keyboard is a special symbol or not.

# include <stdio.h>
int main( )
{
     float sal ;
     printf ( "Enter the salary" ) ;
     scanf ( "%f", &sal ) ;
     if ( sal >= 25000 && sal <= 40000 )
      printf ( "Manager\\n" ) ;
     else if ( sal >= 15000 && sal < 25000 )
      printf ( "Accountant\\n" ) ;
     else
     printf ( "Clerk\\n" ) ;
    return 0 ;
}

Classes
Quiz
Videos
References
Books