The C language provides three logical operators that can be used to join relational and equality expressions and form complex Boolean expressions, i. e., expressions with operands having true or false values. These operators include logical AND (&&), logical OR (||) and logical NOT (!). They are summarized in Table.
Note that the logical not (!) is a unary prefix operator. It is used, as in ! expr, where expr is a relational expression. The other two operators are binary infix operators. They are used, as in expr1 op expr2, where expr1 and expr2 are relational expressions.
Logical operators in the C language
Operator | Meaning | Example | Associativity |
! | Logical not | ! (a < 0) | Right to left |
&& | Logical and | (a >= 0) && (a <= 100) | Left to right |
|| | Logical or | (a < 0) || (a > 100) |
As the logical AND(&&) operator is a binary infix operator, it is used, as in expr1 && expr2 where expr1 and expr2 are relational expressions. This expression evaluates as true, i. e., 1 if both expr1 and expr2 are true; otherwise, it evaluates as false. Consider the expression
(a >= 0) && (a <= 100)
This expression evaluates as true if both the relational expressions (a >= 0) and (a <= 100) are true, i.e., if the value of variable a is in the range 0 to 100 (both inclusive); otherwise, it evaluates as false, i. e., 0.
The logical or ( ||) operator is also a binary infix operator. It is used, as in
expr1 || expr2
where exprl and expr2 are relational expressions. This expression evaluates as true, i. e., 1 if either exprl or expr2 is true (or both of them are true); otherwise, it evaluates as false.
Consider the expression
(a < 0) || (a > 100)
This expression evaluates as true if the value of variable a is less than zero or greater than 100, i. e., outside the range 0 to 100; otherwise, it evaluates as false, i. e., 0.
The logical not ( !) operator performs logical complement operation. This is a unary prefix operator and is used, as in
! expr
This expression evaluates as true if expression expr is false, and false otherwise. Consider the expression
! (a < 0)
If the value of variable a is less than zero, this expression evaluates as false; otherwise, it evaluates as true. Note that this expression is equivalent to the relational expression a >= 0.
Consider another expression given below.
! ((a < 0) || (a > 100))
If the value of variable a is outside 0 to 100, the expression (a < 0: || (a > 100) evaluates as true and the given expression evaluates as false. On the other hand, if the value of a is in the range 0 ... 100, the above expression evaluates as true. Thus, the above expression is equivalent to the expression (a >= 0) & & (a <= 100) .
Table summarizes the precedence and associativity of logical operators along with the other operators including arithmetic, relational, equality and assignment operators. We know that unary operators have the highest precedence followed by arithmetic (multiplicative and additive), relational and equality operators.
As logical not ( ! ) is a unary operator, it has highest precedence (same as other unary operators) and right-to-left associativity. The precedence of the logical operators && and || is lower than the arithmetic, relational and equality operators but higher than the assignment operators. Note that the logical and(&&) operator has higher precedence than the logical or (||) operator. Also, note that & & and || operators have left-to-right associativity.
While evaluating Boolean expressions, the operators are bound to operands in the order of their precedence and associativity as shown in Table. Balanced parentheses can be used to alter the order in which the operands are bound to operands.
Table Precedence and associativity of arithmetic, relational, equality, logical, conditional evaluation, assignment and comma operators in the C language
Operator group | Operators | Associativity |
Unary | ! + - ++ -- (type) | Right to left |
Multiplicative | * / % | Left to right |
Additive | + - | |
Relational | < > <= >= | |
Equality | == != | |
Logical and | && | |
Logical or | || | |
Conditional Expression | ? : | Right to left |
Assignment | = += -= *= /= %= | |
Comma | ' | Left to right |
We have seen earlier that the C language does not specify the order of evaluation of expressions. However, the logical and (&&) and logical not (||) operators are exception to this rule and are always evaluated left-to-right.
The evaluation of an expression of the form expr1 & & expr2 is done as follows: Initially expression expr1 is evaluated. If it evaluates as false, the entire expression will evaluate as false irrespective of the value of expression expr2. Hence, expression expr2 is not evaluated. This is sometimes referred to as short-circuit evaluation. However, if expression expr1 evaluates as true, the value of the entire expression depends on the value of expression expr2. Hence, expression expr2 is evaluated next and the value of the entire expression is determined. Note that in expr1 && expr2, expr1 is guaranteed to evaluate before expr2.
The evaluation of an expression of the form expr1 || expr2 is also done in a similar way: Initially expression expr1 is evaluated. If it evaluates as true, the entire expression will evaluate as true irrespective of the value of expression expr2. Hence, expression expr2 is not evaluated. However, if expression expr1 evaluates as false, the value of the entire expression depends on the value of expr2. Hence, expr2 is evaluated next and the value of the entire expression is determined. Note that in expr 1 || expr 2, expr1 is guaranteed to evaluate before expr2.
Assume that variables a,b and ch are declared and initialized as shown below.
int a = 3, b = 5;
char ch= 'G';
Consider a simple Boolean expression given below.
a >= 0 && a <= 10
In this expression, the operators >= and <= have higher precedence than operator && and are bound to operands from left to right. Subsequently, the operator && is bound to its operands, i.e., relational expressions a>= 0 and a<= 10. During the evaluation of this expression, sub expression a>= 0 is evaluated first as true. Now the value of the given expression depends on sub-expression a <= 10 and it is evaluated next. Since it evaluates as true, the value of the given expression is true. The order of operator binding and evaluation is shown below.
Note that we can make the given expression more readable by including redundant parentheses as
(a >= 0) && (a <= 100).
Now consider another Boolean expression given below.
a + b <= 10 || a * b < 25
This expression contains two relational expressions joined by the || operator. The operators in this expression are bound to operands in order shown below on the left-hand side. During evaluation, sub-expression a + b <= 10 is evaluated first as true. Now the value of the given expression is true irrespective of the value of sub-expression a* b < 25. Hence, it is not evaluated.
Note that the readability of the given expression can be improved by adding redundant
Parenthesis as (a + b <= 10) || (a * b < 25).
Finally, consider a more involved Boolean expression given below.
! (ch>= 'A' && ch<= 'Z' || ch>= 'a' && ch<= 'z')
The order in which operands in this expression are bound to operands is shown below. Note that all the operators in the pair of parentheses are considered first followed by the ! operator.
As the & & operator has higher precedence than the || operator, the given expression is equivalent to the following parenthesized expression:
! ( (ch >= 'A' && ch <= 'Z') ||(ch >= 'a' && ch <= 'z') )
Let us denote the left operand of the || operator (i. e., ch >= 'A' & & ch <= 'z ') as op1 and the right operand as op2. Thus, the given expression is of the form ! (op1 || op2):
The evaluation of this expression proceeds as follows: First, operand op1 is evaluated. If the left operand of the && operator in op1 , i.e., ch >= 'A' evaluates as false, the value of opl is false (right operand of the & & operator is not evaluated); otherwise, the right operand of the & & operator (i. e., ch <= 'z ') is evaluated to determine the value of op1. Next, if the value of expression op1 is true, the value of the || operation is true (op2 is not evaluated). Otherwise, the right hand side operand of the || operator, i. e., op2 is evaluated to determine the outcome of the || operator. Finally, the logical not (!) operator is evaluated. The evaluation of the complete expression is shown below for a given value of ch, i.e., 'G'.
Observe that op1 evaluates as true if variable ch contains an uppercase letter and op2 evaluates as true if ch contains a lowercase letter. Thus, the expression within the pair of parentheses evaluates as true if variable ch contains a letter (either uppercase or lowercase). The given expression thus, evaluates. as false if variable ch contains a letter; otherwise, it evaluates as true. Thus, for the given value of variable ch, the expression evaluates as false.
Dinesh Thakur holds an B.SC (Computer Science), MCSE, MCDBA, CCNA, CCNP, A+, SCJP certifications. Dinesh authors the hugely popular Computer Notes blog. Where he writes how-to guides around Computer fundamental , computer software, Computer programming, and web apps. For any type of query or something that you think is missing, please feel free to Contact us.
Search Content
Popular Article
Basic Courses
Advance Courses