# Working with Variables, Operators, and Expressions in Microsoft Visual C#

- By John Sharp
- 11/18/2015

## Using arithmetic operators

C# supports the regular arithmetic operations you learned in your childhood: the plus sign (+) for addition, the minus sign (–) for subtraction, the asterisk (*) for multiplication, and the forward slash (/) for division. The symbols +, –, *, and / are called *operators* because they “operate” on values to create new values. In the following example, the variable *moneyPaidToConsultant* ends up holding the product of 750 (the daily rate) and 20 (the number of days the consultant was employed):

long moneyPaidToConsultant; moneyPaidToConsultant = 750 * 20;

### Operators and types

Not all operators are applicable to all data types. The operators that you can use on a value depend on the value’s type. For example, you can use all the arithmetic operators on values of type *char, int, long, float, double*, or *decimal*. However, with the exception of the plus operator (+), you can’t use the arithmetic operators on values of type *string*, and you cannot use any of them with values of type *bool*. So, the following statement is not allowed because the *string* type does not support the minus operator (subtracting one string from another is meaningless):

// compile-time error Console.WriteLine("Gillingham" - "Forest Green Rovers");

However, you can use the + operator to concatenate string values. You need to be careful because this can have unexpected results. For example, the following statement writes “431” (not “44”) to the console:

Console.WriteLine("43" + "1");

You should also be aware that the type of the result of an arithmetic operation depends on the type of the operands used. For example, the value of the expression 5.0/2.0 is 2.5; the type of both operands is *double*, so the type of the result is also *double*. (In C#, literal numbers with decimal points are always *double*, not *float*, to maintain as much accuracy as possible.) However, the value of the expression 5/2 is 2. In this case, the type of both operands is *int*, so the type of the result is also *int*. C# always rounds toward zero in circumstances like this. The situation gets a little more complicated if you mix the types of the operands. For example, the expression 5/2.0 consists of an *int* and a *double*. The C# compiler detects the mismatch and generates code that converts the *int* into a *double* before performing the operation. The result of the operation is therefore a *double* (2.5). However, although this works, it is considered poor practice to mix types in this way.

C# also supports one less-familiar arithmetic operator: the *remainder*, or *modulus*, operator, which is represented by the percent sign (%). The result of *x % y* is the remainder after dividing the value *x* by the value *y*. So, for example, 9 % 2 is 1 because 9 divided by 2 is 4, remainder 1.

### Examining arithmetic operators

The following exercise demonstrates how to use the arithmetic operators on *int* values.

Run the MathsOperators project

- Start Visual Studio 2015 if it is not already running.
- Open the MathsOperators project, located in the \Microsoft Press\VCSBS\Chapter 2\MathsOperators folder in your Documents folder.
On the Debug menu, click Start Debugging.

The following form appears:

- In the Left Operand box, type
**54**. In the Right Operand box, type

**13**.You can now apply any of the operators to the values in the text boxes.

Click the – Subtraction option, and then click Calculate.

The text in the Expression box changes to 54 – 13, but the value 0 appears in the Result box; this is clearly wrong.

Click the / Division option, and then click Calculate.

The text in the Expression box changes to 54/13, and again the value 0 appears in the Result box.

Click the % Remainder button, and then click Calculate.

The text in the Expression box changes to 54 % 13, but, once again, the value 0 appears in the Result text box. Test other combinations of numbers and operators; you will find that they all currently yield the value 0.

- When you have finished, return to Visual Studio and then, on the Debug menu, click Stop Debugging.

As you might have guessed, none of the calculations is currently implemented by the MathsOperators application. In the next exercise, you will correct this.

Perform calculations in the MathsOperators application

- Display the MainPage.xaml form in the Design View window. (In Solution Explorer, in the MathsOperators project, double-click the file MainPage.xaml.)
On the View menu, point to Other Windows, and then click Document Outline.

The Document Outline window appears, showing the names and types of the controls on the form. The Document Outline window provides a simple way to locate and select controls on a complex form. The controls are arranged in a hierarchy, starting with the

*Page*that constitutes the form. As mentioned in Chapter 1, a Universal Windows Platform (UWP) app page contains a*Grid*control, and the other controls are placed within this*Grid*. If you expand the Grid node in the Document Outline window, the other controls appear, starting with another*Grid*(the outer*Grid*acts as a frame, and the inner*Grid*contains the controls that you see on the form). If you expand the inner*Grid*, you can see each of the controls on the form.If you click any of these controls, the corresponding element is highlighted in the Design View window. Similarly, if you select a control in the Design View window, the corresponding control is selected in the Document Outline window. (To see this in action, pin the Document Outline window in place by deselecting the Auto Hide button in the upper-right corner of the Document Outline window.)

On the form, click the two

*TextBox*controls in which the user types numbers. In the Document Outline window, verify that they are named*lhsOperand*and*rhsOperand*.When the form runs, the

*Text*property of each of these controls holds the values that the user enters.- Toward the bottom of the form, verify that the
*TextBlock*control used to display the expression being evaluated is named*expression*and that the*TextBlock*control used to display the result of the calculation is named*result*. - Close the Document Outline window.
- On the View menu, click Code to display the code for the MainPage.xaml.cs file in the Code and Text Editor window.
In the Code and Text Editor window, locate the

*addValues*method. It looks like this:private void addValues() { int lhs = int.Parse(lhsOperand.Text); int rhs = int.Parse(rhsOperand.Text); int outcome = 0; // TODO: Add rhs to lhs and store the result in outcome expression.Text = $"{lhsOperand.Text} + {rhsOperand.Text}"; result.Text = outcome.ToString(); }

The first statement in this method declares an

*int*variable called*lhs*and initializes it with the integer corresponding to the value typed by the user in the lhsOperand box. Remember that the*Text*property of a*TextBox*control contains a string, but*lhs*is an*int*, so you must convert this string to an integer before you can assign it to*lhs*. The*int*data type provides the*int.Parse*method, which does precisely this.The second statement declares an

*int*variable called*rhs*and initializes it to the value in the rhsOperand box after converting it to an*int*.The third statement declares an

*int*variable called*outcome*.A comment stating that you need to add

*rhs*to*lhs*and store the result in*outcome*follows. This is the missing bit of code that you need to implement, which you will do in the next step.The fifth statement uses string interpolation to construct a string that indicates the calculation being performed and assigns the result to the

*expression.Text*property. This causes the string to appear in the Expression box on the form.The final statement displays the result of the calculation by assigning it to the

*Text*property of the Result box. Remember that the*Text*property is a string, and the result of the calculation is an*int*, so you must convert the*int*to a string before assigning it to the*Text*property. Recall that this is what the*ToString*method of the*int*type does.Below the comment in the middle of the

*addValues*method, add the following statement (shown below in bold):private void addValues() { int lhs = int.Parse(lhsOperand.Text); int rhs = int.Parse(rhsOperand.Text); int outcome = 0; // TODO: Add rhs to lhs and store the result in outcome

**outcome = lhs + rhs;**expression.Text = $"{lhsOperand.Text} + {rhsOperand.Text}"; result.Text = outcome.ToString(); }This statement evaluates the expression

*lhs*+*rhs*and stores the result in*outcome*.Examine the

*subtractValues*method. You should see that it follows a similar pattern. Here you need to add the statement to calculate the result of subtracting*rhs*from*lhs*and store it in*outcome*. Add the following statement (in bold) to this method:private void subtractValues() { int lhs = int.Parse(lhsOperand.Text); int rhs = int.Parse(rhsOperand.Text); int outcome = 0; // TODO: Subtract rhs from lhs and store the result in outcome

**outcome = lhs - rhs;**expression.Text = $"{lhsOperand.Text} - {rhsOperand.Text}"; result.Text = outcome.ToString(); }Examine the

*multiplyValues*,*divideValues*, and*remainderValues*methods. Again, they are all missing the crucial statement that performs the specified calculation. Add the appropriate statements to these methods (shown in bold).private void multiplyValues() { int lhs = int.Parse(lhsOperand.Text); int rhs = int.Parse(rhsOperand.Text); int outcome = 0; // TODO: Multiply lhs by rhs and store the result in outcome

**outcome = lhs * rhs;**expression.Text = $"{lhsOperand.Text} * {rhsOperand.Text}"; result.Text = outcome.ToString(); } private void divideValues() { int lhs = int.Parse(lhsOperand.Text); int rhs = int.Parse(rhsOperand.Text); int outcome = 0; // TODO: Divide lhs by rhs and store the result in outcome**outcome = lhs / rhs;**expression.Text = $"{lhsOperand.Text} / {rhsOperand.Text}"; result.Text = outcome.ToString(); } private void remainderValues() { int lhs = int.Parse(lhsOperand.Text); int rhs = int.Parse(rhsOperand.Text); int outcome = 0; // TODO: Work out the remainder after dividing lhs by rhs and store the result in outcome**outcome = lhs % rhs;**expression.Text = $"{lhsOperand.Text} % {rhsOperand.Text}"; result.Text = outcome.ToString(); }

Test the MathsOperators application

- On the Debug menu, click Start Debugging to build and run the application.
Type

**54**in the Left Operand box, type**13**in the Right Operand box, click the + Addition option, and then click Calculate.The value 67 should appear in the Result box.

- Click the – Subtraction option, and then click Calculate. Verify that the result is now 41.
- Click the * Multiplication option, and then click Calculate. Verify that the result is now 702.
Click the / Division option, and then click Calculate. Verify that the result is now 4.

In real life, 54/13 is 4.153846 recurring, but this is not real life—this is C# performing integer division. When you divide one integer by another integer, the answer you get back is an integer, as explained earlier.

Click the % Remainder option, and then click Calculate. Verify that the result is now 2.

When dealing with integers, the remainder after dividing 54 by 13 is 2; (54 – ((54/13) * 13)) is 2. This is because the calculation rounds down to an integer at each stage. (My high school math teacher would be horrified to be told that (54/13) * 13 does not equal 54!)

- Return to Visual Studio and stop debugging.

### Controlling precedence

*Precedence* governs the order in which an expression’s operators are evaluated. Consider the following expression, which uses the + and * operators:

2 + 3 * 4

This expression is potentially ambiguous: do you perform the addition first or the multiplication? The order of the operations matters because it changes the result:

- If you perform the addition first, followed by the multiplication, the result of the addition (2 + 3) forms the left operand of the * operator, and the result of the whole expression is 5 * 4, which is 20.
- If you perform the multiplication first, followed by the addition, the result of the multiplication (3 * 4) forms the right operand of the + operator, and the result of the whole expression is 2 + 12, which is 14.

In C#, the multiplicative operators (*, /, and %) have precedence over the additive operators (+ and –), so in expressions such as 2 + 3 * 4, the multiplication is performed first, followed by the addition. The answer to 2 + 3 * 4 is therefore 14.

You can use parentheses to override precedence and force operands to bind to operators in a different way. For example, in the following expression, the parentheses force the 2 and the 3 to bind to the + operator (making 5), and the result of this addition forms the left operand of the * operator to produce the value 20:

(2 + 3) * 4

### Using associativity to evaluate expressions

Operator precedence is only half the story. What happens when an expression contains different operators that have the same precedence? This is where *associativity* becomes important. Associativity is the direction (left or right) in which the operands of an operator are evaluated. Consider the following expression that uses the / and * operators:

4 / 2 * 6

At first glance, this expression is potentially ambiguous. Do you perform the division first or the multiplication? The precedence of both operators is the same (they are both multiplicative), but the order in which the operators in the expression are applied is important because you can get two different results:

- If you perform the division first, the result of the division (4/2) forms the left operand of the * operator, and the result of the whole expression is (4/2) * 6, or 12.
- If you perform the multiplication first, the result of the multiplication (2 * 6) forms the right operand of the / operator, and the result of the whole expression is 4/(2 * 6), or 4/12.

In this case, the associativity of the operators determines how the expression is evaluated. The * and / operators are both left associative, which means that the operands are evaluated from left to right. In this case, 4/2 will be evaluated before multiplying by 6, giving the result 12.

### Associativity and the assignment operator

In C#, the equal sign (=) is an operator. All operators return a value based on their operands. The assignment operator *=* is no different. It takes two operands: the operand on the right side is evaluated and then stored in the operand on the left side. The value of the assignment operator is the value that was assigned to the left operand. For example, in the following assignment statement, the value returned by the assignment operator is 10, which is also the value assigned to the variable *myInt*:

int myInt; myInt = 10; // value of assignment expression is 10

At this point, you might be thinking that this is all very nice and esoteric, but so what? Well, because the assignment operator returns a value, you can use this same value with another occurrence of the assignment statement, like this:

int myInt; int myInt2; myInt2 = myInt = 10;

The value assigned to the variable *myInt2* is the value that was assigned to *myInt*. The assignment statement assigns the same value to both variables. This technique is useful if you want to initialize several variables to the same value. It makes it very clear to anyone reading your code that all the variables must have the same value:

myInt5 = myInt4 = myInt3 = myInt2 = myInt = 10;

From this discussion, you can probably deduce that the assignment operator associates from right to left. The rightmost assignment occurs first, and the value assigned propagates through the variables from right to left. If any of the variables previously had a value, it is overwritten by the value being assigned.

You should treat this construct with caution, however. One frequent mistake that new C# programmers make is to try to combine this use of the assignment operator with variable declarations. For example, you might expect the following code to create and initialize three variables with the same value (10):

int myInt, myInt2, myInt3 = 10;

This is legal C# code (because it compiles). What it does is declare the variables *myInt, myInt2*, and *myInt3* and initialize *myInt3* with the value 10. However, it does not initialize *myInt* or *myInt2*. If you try to use *myInt* or *myInt2* in an expression such as

myInt3 = myInt / myInt2;

the compiler generates the following errors:

Use of unassigned local variable 'myInt' Use of unassigned local variable 'myInt2'