Relational and Logical Operators


In the terms relational operator and logical operator, relational refers to the relationships that values can have with one another, and logical refers to the ways in which true and false values can be connected together. Since the relational operators produce true or false results, they often work with the logical operators. For this reason they will be discussed together here.

The relational operators are as follows:

Operator

Meaning

= =

Equal to

!=

Not equal to

>

Greater than

<

Less than

>=

Greater than or equal to

<=

Less than or equal to

The logical operators are shown next:

Operator

Meaning

&

AND

|

OR

^

XOR (exclusive OR)

||

Short-circuit OR

&&

Short-circuit AND

!

NOT

The outcome of the relational and logical operators is a bool value.

In C#, all objects can be compared for equality or inequality using = = and !=. However, the comparison operators, <, >, <=, or >=, can be applied only to those types that support an ordering relationship. Therefore, all of the relational operators can be applied to all numeric types. However, values of type bool can only be compared for equality or inequality, since the true and false values are not ordered. For example, true > false has no meaning in C#.

For the logical operators, the operands must be of type bool, and the result of a logical operation is of type bool. The logical operators, &, |, ^, and !, support the basic logical operations AND, OR, XOR, and NOT, according to the following truth table:

p

q

p&q

p|q

p^q

!p

False

False

False

False

False

True

True

False

False

True

True

False

False

True

False

True

True

True

True

True

True

True

False

False

As the table shows, the outcome of an exclusive OR operation is true when exactly one and only one operand is true.

Here is a program that demonstrates several of the relational and logical operators:

 // Demonstrate the relational and logical operators, using System; class RelLogOps {   public static void Main() {     int i, j;     bool b1, b2;     i = 10;     j = 11;     if(i < j) Console.WriteLine("i < j");     if(i <= j) Console.WriteLine("i <= j");     if(i != j) Console.WriteLine("i != j");     if(i == j) Console.WriteLine("this won't execute");     if(i >= j) Console.WriteLine("this won't execute");     if(i > j) Console.WriteLine("this won't execute");     b1 = true;     b2 = false;     if(b1 & b2) Console.WriteLine("this won't execute");     if(!(b1 & b2)) Console.WriteLine("!(b1 & b2) is true");     if(b1 b2) Console.WriteLine("b1 | b2 is true");     if(b1 ^ b2) Console.WriteLine("b1 ^ b2 is true");   }  }

The output from the program is shown here:

 i < j i <= j i != j ! (b1 & b2) is true b1 | b2 is true b1 ^ b2 is true   

The logical operators provided by C# perform the most commonly used logical operations. However, there are several other operations defined by the rules for formal logic. These other logical operations can be constructed using the logical operators supported by C#. Thus, C# supplies a set of logical operators sufficient to construct any other logical operation. For example, another logical operation is implication. Implication is a binary operation in which the outcome is false only when the left operand is true and the right operand is false. (The implication operation reflects the idea that true cannot imply false.) Thus, the truth table for the implication operator is shown here:

p

q

p implies q

True

True

True

True

False

False

False

False

True

False

True

True

The implication operation can be constructed using a combination of the ! and the I operator, as shown here:

 !p | q

The following program demonstrates this implementation:

 // Create an implication operator in C#. using System; class Implication {   public static void Main() {     bool p=false, q=false;     int i, j;     for(i =0; i < 2; i++) {       for(j = 0; j < 2; j++) {         if (i==0) p = true;         if (i==1) p = false;         if (j==0) q = true;         if (j==1) q = false;         Console .WriteLine ("p is " + p + '' q is " + q);         if(!p | q) Console.WriteLine(p + implies " + q +                     " is " + true);         Console.WriteLine();       }     }   } }

The output is shown here:

 p is True, q is True True implies True is True p is True, q is False p is False, q is True False implies True is True p is False, q is False False implies False is True

Short-Circuit Logical Operators

C# supplies special short-circuit versions of its AND and OR logical operators that can be used to produce more efficient code. To understand why, consider the following: In an AND operation, if the first operand is false, the outcome is false no matter what value the second operand has. In an OR operation, if the first operand is true, the outcome of the operation is true no matter what the value of the second operand. Thus, in these two cases there is no need to evaluate the second operand. By not evaluating the second operand, time is saved and more efficient code is produced.

The short-circuit AND operator is && and the short-circuit OR operator is | |. As described earlier, their normal counterparts are & and |. The only difference between the normal and short-circuit versions is that the normal operands will always evaluate each operand, but short-circuit versions will evaluate the second operand only when necessary.

Here is a program that demonstrates the short-circuit AND operator. The program determines if the value in d is a factor of n. It does this by performing a modulus operation. If the remainder of n / d is zero, then d is a factor. However, since the modulus operation involves a division, the short-circuit form of the AND is used to prevent a divide-by-zero error.

 // Demonstrate the short-circuit operators, using System; class SCops {   public static void Main() {     int n, d;          n = 10;     d = 2;     if(d != 0 && (n % d) == 0)       Console.WriteLine(d + " is a factor of " + n);            d = 0; // now, set d to zero          // Since d is zero, the second operand is not evaluated,     if(d != 0 && (n % d) == 0)       Console.WriteLine(d + " is a factor of " + n);            /* Now, try the same thing without short-circuit operator.        This will cause a divide-by-zero error. */     if(d != 0 & (n % d) == 0)       Console.WriteLine(d + " is a factor of " + n);   } } 

To prevent a divide-by-zero error, the if statement first checks to see if d is equal to zero. If it is, the short-circuit AND stops at that point and does not perform the modulus division. Thus, in the first test, d is 2 and the modulus operation is performed. The second test fails because d is set to zero, and the modulus operation is skipped, avoiding a divide-by-zero error. Finally, the normal AND operator is tried. This causes both operands to be evaluated, which leads to a runtime error when the division-by-zero occurs.

Since the short-circuit operators are, in some cases, more efficient than their normal counterparts, you might be wondering why C# still offers the normal AND and OR operators. The answer is that in some cases you will want both operands of an AND or OR operation to be evaluated because of the side effects produced. Consider the following:

 // Side effects can be important, using System; class SideEffects {   public static void Main() {     int i;     bool someCondition = false;     i = 0;     /* Here, i is still incremented even though        the if statement fails. */     if(someCondition & (++i < 100))        Console.WriteLine("this won't be displayed");     Console.WriteLine("if statement executed: " + i); // displays 1     /* In this case, i is not incremented because        the short-circuit operator skips the increment. */     if(someCondition && (++i < 100))       Console.WriteLine("this won't be displayed");     Console.WriteLine("if statement executed: " + i); // still 1 !!   } }

First, notice that the bool variable someCondition is initialized to false. Next, examine each if statement. As the comments indicate, in the first if statement, i is incremented despite the fact that someCondition is false. When the & is used, as it is in the first if, the expression on the right side of the & is evaluated no matter what value the expression on the left has. However, in the second if statement, the short-circuit operator is used. In this case, the variable i is not incremented because the left operand, someCondition, is false, which causes the expression on the right to be skipped. The lesson here is that if your code expects the right-hand operand of an AND or OR operation to be evaluated, then you must use C#'s non-short-circuit forms of these operations.

One other point: The short-circuit AND is also known as the conditional-AND, and the short-circuit OR is also called the conditional-OR.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

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