An operator is a symbol that causes C# to take an action. The C# primitive types (e.g., int) support a number of operators such as assignment, increment, and so forth. Their use is highly intuitive, with the possible exception of the assignment operator (=) and the equality operator (==), which are often confused.
Section 3.3, earlier in this chapter, demonstrates the use of the assignment operator. This symbol causes the operand on the left side of the operator to have its value changed to whatever is on the right side of the operator.
C# uses five mathematical operators: four for standard calculations and a fifth to return the remainder in integer division. The following sections consider the use of these operators.
C# offers operators for simple arithmetic: the addition (+), subtraction (), multiplication (*), and division (/) operators work as you might expect, with the possible exception of integer division.
When you divide two integers, C# divides like a child in fourth grade: it throws away any fractional remainder. Thus, dividing 17 by 4 will return the value 4 (17/4 = 4, with a remainder of 1). C# provides a special operator (modulus, %, which is described in the next section) to retrieve the remainder.
Note, however, that C# does return fractional answers when you divide floats, doubles, and decimals.
To find the remainder in integer division, use the modulus operator (%). For example, the statement 17%4 returns 1 (the remainder after integer division).
The modulus operator turns out to be more useful than you might at first imagine. When you perform modulus n on a number that is a multiple of n, the result is zero. Thus 80%10 = 0 because 80 is an even multiple of 10. This fact allows you to set up loops in which you take an action every nth time through the loop, by testing a counter to see if %n is equal to zero. This strategy comes in handy in the use of the for loop, as described earlier in this chapter. The effects of division on integers, floats, doubles, and decimals is illustrated in Example 316.
using System; class Values { static void Main( ) { int i1, i2; float f1, f2; double d1, d2; decimal dec1, dec2; i1 = 17; i2 = 4; f1 = 17f; f2 = 4f; d1 = 17; d2 = 4; dec1 = 17; dec2 = 4; Console.WriteLine("Integer:\t{0}\nfloat:\t\t{1}", i1/i2, f1/f2); Console.WriteLine("double:\t\t{0}\ndecimal:\t{1}", d1/d2, dec1/dec2); Console.WriteLine("\nModulus:\t{0}", i1%i2); } } Output: Integer: 4 float: 4.25 double: 4.25 decimal: 4.25 Modulus: 1
Now consider this line from Example 316:
Console.WriteLine("Integer:\t{0}\nfloat:\t\t{1}\n", i1/i2, f1/f2);
It begins with a call to Console.Writeline( ), passing in this partial string:
"Integer:\t{0}\n
This will print the characters Integer:, followed by a tab (\t), followed by the first parameter ({0}), followed by a newline character (\n). The next string snippet:
float:\t\t{1}\n
is very similar. It prints float:, followed by two tabs (to ensure alignment), the contents of the second parameter ({1}), and then another newline. Notice the subsequent line, as well:
Console.WriteLine("\nModulus:\t{0}", i1%i2);
This time the string begins with a newline character, which causes a line to be skipped just before the string Modulus: is printed. You can see this effect in the output.
A common requirement is to add a value to a variable, subtract a value from a variable, or otherwise change the mathematical value, and then to assign that new value back to the same variable. You might even want to assign the result to another variable altogether. The following two sections discuss these cases respectively.
Suppose you want to increment the mySalary variable by 5000. You can do this by writing:
mySalary = mySalary + 5000;
The addition happens before the assignment, and it is perfectly legal to assign the result back to the original variable. Thus, after this operation completes, mySalary will have been incremented by 5000. You can perform this kind of assignment with any mathematical operator:
mySalary = mySalary * 5000; mySalary = mySalary  5000;
and so forth.
The need to increment and decrement variables is so common that C# includes special operators for selfassignment. Among these operators are +=, =, *=, /=, and %=, which, respectively, combine addition, subtraction, multiplication, division, and modulus with selfassignment. Thus, you can alternatively write the previous examples as:
mySalary += 5000; mySalary *= 5000; mySalary = 5000;
The effect of this is to increment mySalary by 5000, multiply mySalary by 5000, and subtract 5000 from the mySalary variable, respectively.
Because incrementing and decrementing by 1 is a very common need, C# (like C and C++ before it) also provides two special operators. To increment by 1, use the ++ operator, and to decrement by 1, use the  operator.
Thus, if you want to increment the variable myAge by 1 you can write:
myAge++;
To complicate matters further, you might want to increment a variable and assign the results to a second variable:
firstValue = secondValue++;
The question arises: do you want to assign before you increment the value, or after? In other words, if secondValue starts out with the value 10, do you want to end with both firstValue and secondValue equal to 11, or do you want firstValue to be equal to 10 (the original value) and secondValue to be equal to 11?
C# (again, like C and C++) offer two flavors of the increment and decrement operators: prefix and postfix. Thus you can write:
firstValue = secondValue++; // postfix
which will assign first, and then increment (firstValue=10, secondValue=11). You can also write:
firstValue = ++secondValue; // prefix
which will increment first, and then assign (firstValue=11, secondValue=11).
It is important to understand the different effects of prefix and postfix, as illustrated in Example 317.
using System; class Values { static void Main( ) { int valueOne = 10; int valueTwo; valueTwo = valueOne++; Console.WriteLine("After postfix: {0}, {1}", valueOne, valueTwo); valueOne = 20; valueTwo = ++valueOne; Console.WriteLine("After prefix: {0}, {1}", valueOne, valueTwo); } } Output: After postfix: 11, 10 After prefix: 21, 21
Relational operators are used to compare two values, and then return a Boolean (true or false). The greaterthan operator (>), for example, returns true if the value on the left of the operator is greater than the value on the right. Thus, 5 > 2 returns the value true, while 2 > 5 returns the value false.
The relational operators for C# are shown in Table 33. This table assumes two variables: bigValue and smallValue, in which bigValue has been assigned the value 100 and smallValue the value 50.
Name 
Operator 
Given this statement 
The expression evaluates to 

Equals 
== 
bigValue == 100 bigValue == 80 
true false 
Not equals 
!= 
bigValue != 100 bigValue != 80 
false true 
Greater than 
> 
bigValue > smallValue 
true 
Greater than or equals 
>= 
bigValue >= smallValue smallValue >= bigValue 
true false 
Less than 
< 
bigValue < smallValue 
false 
Less than or equals 
<= 
smallValue <= bigValue bigValue <= smallValue 
true false 
Each of these relational operators acts as you might expect. However, take note of the equals operator (==), which is created by typing two equal signs (=) in a row (i.e., without any space between them); the C# compiler treats the pair as a single operator.
The C# equality operator (==) tests for equality between the objects on either side of the operator. This operator evaluates to a Boolean value (true or false). Thus, the statement:
myX == 5;
evaluates to true if and only if myX is a variable whose value is 5.

If statements (discussed earlier in this chapter) test whether a condition is true. Often you will want to test whether two conditions are both true, or whether only one is true, or none is true. C# provides a set of logical operators for this, as shown in Table 34. This table assumes two variables, x and y, in which x has the value 5 and y the value 7.
Name 
Operator 
Given this statement 
The expression evaluates to 

and 
&& 
(x == 3) && (y == 7) 
false 
or 
 
(x == 3)  (y == 7) 
true 
not 
! 
! (x == 3) 
true 
The and operator tests whether two statements are both true. The first line in Table 34 includes an example that illustrates the use of the and operator:
(x == 3) && (y == 7)
The entire expression evaluates false because one side (x == 3) is false.
With the or operator, either or both sides must be true; the expression is false only if both sides are false. So, in the case of the example in Table 34:
(x == 3)  (y == 7)
the entire expression evaluates true because one side (y==7) is true.
With a not operator, the statement is true if the expression is false, and vice versa. So, in the accompanying example:
! (x == 3)
the entire expression is true because the tested expression (x==3) is false. (The logic is "it is true that it is not true that x is equal to 3.")
ShortCircuit EvaluationConsider the following code snippet: int x = 8; if ((x == 8)  (y == 12)) The if statement here is a bit complicated. The entire if statement is in parentheses, as are all if statements in C#. Thus, everything within the outer set of parentheses must evaluate true for the if statement to be true. Within the outer parentheses are two expressions (x==8) and (y==12), which are separated by an or operator (). Because x is 8, the first term (x==8) evaluates true. There is no need to evaluate the second term (y==12). It doesn't matter whether y is 12, the entire expression will be true. Similarly, consider this snippet: int x = 8; if ((x == 5) && (y == 12)) Again, there is no need to evaluate the second term. Because the first term is false, the and must fail. (Remember, for an and statement to evaluate true, both tested expressions must evaluate true.) In cases such as these, the C# compiler will shortcircuit the evaluation; the second test will never be performed. 
The compiler must know the order in which to evaluate a series of operators. For example, if I write:
myVariable = 5 + 7 * 3;
there are three operators for the compiler to evaluate (=, +, and *). It could, for example, operate left to right, which would assign the value 5 to myVariable, then add 7 to the 5 (12) and multiply by 3 (36)but of course then it would throw that 36 away. This is clearly not what is intended.
The rules of precedence tell the compiler which operators to evaluate first. As is the case in algebra, multiplication has higher precedence than addition, so 5+7*3 is equal to 26 rather than 36. Both addition and multiplication have higher precedence than assignment, so the compiler will do the math, and then assign the result (26) to myVariable only after the math is completed.
In C#, parentheses are also used to change the order of precedence much as they are in algebra. Thus, you can change the result by writing:
myVariable = (5+7) * 3;
Grouping the elements of the assignment in this way causes the compiler to add 5+7, multiply the result by 3, and then assign that value (36) to myVariable. Table 35 summarizes operator precedence in C#.
Category 
Operators 

Primary 
(x) x.y x>y f(x) a[x] x++ x new typeof sizeof checkeduncheckedstackalloc 
Unary 
+  ! ~ ++x  x (T)x *x &x 
Multiplicative 
* / % 
Additive 
+  
Shift 
<< >> 
Relational 
< > <= >= is as 
Equality 
== != 
Logical AND 
& 
Logical XOR 
^ 
Logical OR 
 
Conditional AND 
&& 
Conditional OR 
 
Conditional 
?: 
Assignment 
= *= /= %= += = <<= >>= &= ^= = 
In some complex equations you might need to nest your parentheses to ensure the proper order of operations. Let's assume I want to know how many seconds my family wastes each morning. It turns out that the adults spend 20 minutes over coffee each morning and 10 minutes reading the newspaper. The children waste 30 minutes dawdling and 10 minutes arguing.
Here's my algorithm:
(((minDrinkingCoffee + minReadingNewspaper )* numAdults ) + ((minDawdling + minArguing) * numChildren)) * secondsPerMinute.
Although this works, it is hard to read and hard to get right. It's much easier to use interim variables:
wastedByEachAdult = minDrinkingCoffee + minReadingNewspaper; wastedByAllAdults = wastedByEachAdult * numAdults; wastedByEachKid = minDawdling + minArguing; wastedByAllKids = wastedByEachKid * numChildren; wastedByFamily = wastedByAllAdults + wastedByAllKids; totalSeconds = wastedByFamily * 60;
The latter example uses many more interim variables, but it is far easier to read, understand, and (most important) debug. As you step through this program in your debugger, you can see the interim values and make sure they are correct.
Although most operators require one term (e.g., myValue++) or two terms (e.g., a+b), there is one operator that has three: the ternary operator (?:).
conditionalexpression ? expression1 : expression2
This operator evaluates a conditional expression (an expression that returns a value of type bool), and then invokes either expression1 if the value returned from the conditional expression is true, or expression2 if the value returned is false. The logic is "if this is true, do the first; otherwise do the second." Example 318 illustrates.
using System; class Values { static void Main( ) { int valueOne = 10; int valueTwo = 20; int maxValue = valueOne > valueTwo ? valueOne : valueTwo; Console.WriteLine("ValueOne: {0}, valueTwo: {1}, maxValue: {2}", valueOne, valueTwo, maxValue); } } Output: ValueOne: 10, valueTwo: 20, maxValue: 20
In Example 318, the ternary operator is being used to test whether valueOne is greater than valueTwo. If so, the value of valueOne is assigned to the integer variable maxValue; otherwise the value of valueTwo is assigned to maxValue.