OverIQ.com

Logical Operators in C

Last updated on July 27, 2020


Logical operators are used to evaluate two or more conditions. In General, Logical operators are used to combine relational expressions, but they are not limited to just relational expression you can use any kind of expression even constants. If the result of the logical operator is true then 1 is returned otherwise 0 is returned.

There are three types of logical operators:

Operator Meaning
&& AND operator
|| OR operator
! NOT operator

The AND ( && ) and OR ( || ) are binary operator while NOT ( ! ) is a unary operator.

Before we start explaining && operator, keep in mind that - In C, all non-zero values are considered as true ( 1 ) while 0 is considered as false.

AND (&&) operator #

This operator gives the net result of true (i.e 1) if both operands are true, otherwise false (i.e 0).

Operand 1 Operand 2 Result
true true true
true false false
false true false
false false false

Let's take an example:

int a = 12, b = 3;

Suppose we have the following logical expression:

(a==12) && (b<5)

In the above expression both the conditions a == 12 and b < 5 are true, therefore the whole expression is true. As a result, the value of the whole logical expression is 1.

Parentheses are added to the above expression just for the sake of readability. It doesn't alter the order of operation in any way. So the expression:

(a<12) && (b<5)

is equivalent to:

a < 12 && b < 5

Certainly, the former expression is much more readable than the latter one.

Consider some more examples:

Expression Intermediate Expression Result
(a==4) && (b==2) false && false => false 0
(a>100) && (b<10) false && true => false 0
a && b true && true => true 1
a && 0 true && false => false 0

Pay special attention to the last two examples, as discussed, operands in a logical expression can be any expression, variables or constants.

Here is the most important thing about the && operator.

In && (AND) operator if the first operand evaluates to false, then the second operand in not evaluated at all.

Consider the following example:

1
2
int a = 12;
(a==11) && (a++);

In the above expression a==11 is false, so the right operand a++ is not evaluated at all. The following program demonstrates this concept:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include<stdio.h>

int main()
{
    int a = 12, result;

    printf("Initial value of a = %d\n", a);

    // result of the logical expression is stored in result
    result = (a==11) && (a++); 

    printf("Final value of a = %d\n", a);
    printf("Result of logical expression = %d\n", result);

    // Signal to operating system everything works fine
    return 0;
}

Expected Output:

1
2
3
Initial value of a = 12
Final value of a = 12
Result of logical expression = 0

If the condition a==11 had been true then the value of a would have been incremented by 1.

OR (||) operator #

This operator gives the net result of true (i.e 1) if at least one operand is true, otherwise false.

Operand 1 Operand 2 Result
true true true
true false true
false true true
false false false

Let's take an example:

int a = 10, b = 9;

Suppose we have the following logical expression:

(a<12) || (b<5)

In the above expression a < 12 is true while b < 5 is false. Therefore the whole expression evaluates to true and the value of the logical expression is 1.

Consider some more examples:

Expression Intermediate Expression Result
(a==4) || (b==2) false || false => false 0
(a>10) || (b<10) false || true => true 1
a || b true || true => true 1
a || 12.12 true || true => true 1

Note that the parentheses are used in above two expression to improve readability, certainly the expression (a==4) && (b==2) is more readable than a==4 && b==2.

Notice that in the last statement second operand is of type double which is perfectly acceptable.

The most important thing about the OR(||) operator is that if the first operand evaluates to true, then the second operator is not evaluated. Consider the following example:

1
2
int a = 10;
(a==10) || (a--);

In the above expression a==10 is true, so the expression a-- is not evaluated and the result of the overall expression is 1. The following program demonstrates this concept:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include<stdio.h>

int main()
{
    int a = 10, result;

    printf("Initial value of a = %d\n", a);

    // result of the logical expression is stored in result
    result = (a==10) || (a--); 

    printf("Final value of a = %d\n", a);
    printf("Result of logical expression = %d\n", result);

    // Signal to operating system everything works fine
    return 0;
}

Expected Output:

1
2
3
Initial value of a = 10
Final value of a = 10
Result of logical expression = 1

If the condition a==10 had been false, then the value of a would be decremented by 1.

!(NOT) operator #

The ! (not) operator negates the value of the condition. If the condition is false then it becomes true, if it is true then it becomes false. Unlike && (AND) and || (OR) operator, the ! (NOT) operator is unary.

Operand Result
true false
false true

Let's take an example:

int a = 10, b = 9;

Suppose we have the following logical expression.

!(a > 5)

As we can see, the condition a > 5 is true. And !(NOT) operator negates the value of the condition, so the result of the overall expression is false i.e 0.

Here are some more examples:

Expression Intermediate Expression Result
!(a==4) !false => true 1
!(a || b) !true => false 0
!(a && b) !true => false 0
!(a > b) !true => false 0

Note: To use relational and logical to its full potential you must first master if-else statements and loops. If-else statements and loop are discussed in detail in If… else statements in C and The while loop in C chapters, respectively.

The following program demonstrates the NOT(!) operator in action:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include<stdio.h>

int main()
{
    int a = 100, result;
    printf("Initial value of a = %d\n", a);

    // result of the logical expression is stored in result
    result = (a>10); 

    printf("Is a > 10 : %d\n", result);
    printf("After applying not operator\n");
    printf("Is a > 10 : %d\n", !result);

    // Signal to operating system everything works fine
    return 0;
}

Expected Output:

1
2
3
4
Initial value of a = 100
Is a > 10 : 1
After applying not operator
Is a > 10 : 0

Precedence #

Among logical operators, the NOT (!) operator has the highest precedence and it associates from right to left. The precedence of AND (&&) operator is higher than OR (||) operator and they both associates from left to right (see the full precedence table).

Let's now solve some expressions involving logical operators. Example 1:

1
2
int age = 10, height = 45;
(age < 12 && height < 48) || (age > 65 && height > 72);

Solution: In this case, the order of evaluation of operators will be parentheses ( () ), relational operators (<, >), AND ( && ) operator, OR ( || ) operator.

1
2
3
4
5
6
7
(age < 12 && height < 48) || (age > 65 && height > 72)
=> (10 < 12 && 45 < 48) || (10 > 65 && 45 > 72)
=> (1 && 1) || (10 > 65 && 45 > 72)
=> 1 || (10 > 65 && 45 > 72)
=> 1 || (0 && 0)
=> 1 || 0 
=> 1

Example 2:

1
2
int year = 2000;
(year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0);

Solution: In this case, the order of evaluation of operators will be parentheses ( () ), Modular division (%), Relational operators (==, !=) AND ( && ) operator, OR ( || ) operator.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
(year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0)
=> (2000 % 4 == 0 && 2000 % 100 != 0 ) || (2000 % 400 == 0)
=> (0 == 0 && 2000 % 100 != 0 ) || (2000 % 400 == 0)
=> (0 == 0 && 0 != 0 ) || (2000 % 400 == 0)
=> (1 && 0 != 0 ) || (2000 % 400 == 0)
=> (1 && 0 ) || (2000 % 400 == 0)
=> 0 || (2000 % 400 == 0)
=> 0 || (0 == 0)
=> 0 || 1
=> 1