Working with Variables, Operators, and Expressions - Microsoft® Visual C#® 2012 Step by Step (2012)

Microsoft® Visual C#® 2012 Step by Step (2012)

Chapter 2. Working with Variables, Operators, and Expressions

After completing this chapter, you will be able to

§ Understand statements, identifiers, and keywords.

§ Use variables to store information.

§ Work with primitive data types.

§ Use arithmetic operators such as the plus sign (+) and the minus sign (–).

§ Increment and decrement variables.

In Chapter 1, you learned how to use the Microsoft Visual Studio 2012 programming environment to build and run a console program and a graphical application. This chapter introduces you to the elements of Microsoft Visual C# syntax and semantics, including statements, keywords, and identifiers. You’ll study the primitive types that are built into the C# language and the characteristics of the values that each type holds. You’ll also see how to declare and use local variables (variables that exist only in a method or other small section of code), learn about the arithmetic operators that C# provides, find out how to use operators to manipulate values, and learn how to control expressions containing two or more operators.

Understanding Statements

A statement is a command that performs an action, such as calculating a value and storing the result, or displaying a message to a user. You combine statements to create methods. You’ll learn more about methods in Chapter 3, but for now, think of a method as a named sequence of statements. Main, which was introduced in the previous chapter, is an example of a method.

Statements in C# follow a well-defined set of rules describing their format and construction. These rules are collectively known as syntax. (In contrast, the specification of what statements do is collectively known as semantics.) One of the simplest and most important C# syntax rules states that you must terminate all statements with a semicolon. For example, you saw in Chapter 1 that without its terminating semicolon, the following statement won’t compile:

Console.WriteLine("Hello World!");

TIP

C# is a “free format” language, which means that white space, such as a space character or a new line, is not significant except as a separator. In other words, you are free to lay out your statements in any style you choose. However, you should adopt a simple, consistent layout style to make your programs easier to read and understand.

The trick to programming well in any language is learning the syntax and semantics of the language and then using the language in a natural and idiomatic way. This approach makes your programs more easily maintainable. As you progress through this book, you’ll see examples of the most important C# statements.

Using Identifiers

Identifiers are the names you use to identify the elements in your programs, such as namespaces, classes, methods, and variables. (You will learn about variables shortly.) In C#, you must adhere to the following syntax rules when choosing identifiers:

§ You can use only letters (uppercase and lowercase), digits, and underscore characters.

§ An identifier must start with a letter or an underscore.

For example, result, _score, footballTeam, and plan9 are all valid identifiers, whereas result%, footballTeam$, and 9plan are not.

IMPORTANT

C# is a case-sensitive language: footballTeam and FootballTeam are not the same identifier.

Identifying Keywords

The C# language reserves 77 identifiers for its own use, and you cannot reuse these identifiers for your own purposes. These identifiers are called keywords, and each has a particular meaning. Examples of keywords are class, namespace, and using. You’ll learn the meaning of most of the C# keywords as you proceed through this book. The following table lists the keywords:

abstract

do

in

protected

true

as

double

int

public

try

base

else

interface

readonly

typeof

bool

enum

internal

ref

uint

break

event

is

return

ulong

byte

explicit

lock

sbyte

unchecked

case

extern

long

sealed

unsafe

catch

false

namespace

short

ushort

char

finally

new

sizeof

using

checked

fixed

null

stackalloc

virtual

class

float

object

static

void

const

for

operator

string

volatile

continue

foreach

out

struct

while

decimal

goto

override

switch

default

if

params

this

delegate

implicit

private

throw

TIP

In the Visual Studio 2012 Code and Text Editor window, keywords are colored blue when you type them.

C# also uses the following identifiers. These identifiers are not reserved by C#, which means that you can use these names as identifiers for your own methods, variables, and classes, but you should avoid doing so if at all possible.

add

get

remove

alias

global

select

ascending

group

set

async

into

value

await

join

var

descending

let

where

dynamic

orderby

yield

from

partial

Using Variables

A variable is a storage location that holds a value. You can think of a variable as a box in the computer’s memory holding temporary information. You must give each variable in a program an unambiguous name that uniquely identifies it in the context in which it is used. You use a variable’s name to refer to the value it holds. For example, if you want to store the value of the cost of an item in a store, you might create a variable simply called cost and store the item’s cost in this variable. Later on, if you refer to the cost variable, the value retrieved will be the item’s cost that you stored there earlier.

Naming Variables

You should adopt a naming convention for variables that helps you avoid confusion concerning the variables you have defined. This is especially important if you are part of a project team with several developers working on different parts of an application; a consistent naming convention helps to avoid confusion and can reduce the scope for bugs. The following list contains some general recommendations:

§ Don’t start an identifier with an underscore. Although this is legal in C#, it can limit the interoperability of your code with applications built by using other languages, such as Microsoft Visual Basic.

§ Don’t create identifiers that differ only by case. For example, do not create one variable named myVariable and another named MyVariable for use at the same time, because it is too easy to get them confused. Also, defining identifiers that differ only by case can limit the ability to reuse classes in applications developed by using other languages that are not case sensitive, such as Microsoft Visual Basic.

§ Start the name with a lowercase letter.

§ In a multiword identifier, start the second and each subsequent word with an uppercase letter. (This is called camelCase notation.)

§ Don’t use Hungarian notation. (Microsoft Visual C++ developers reading this book are probably familiar with Hungarian notation. If you don’t know what Hungarian notation is, don’t worry about it!)

For example, score, footballTeam, _score, and FootballTeam are all valid variable names, but only the first two are recommended.

Declaring Variables

Variables hold values. C# has many different types of values that it can store and process—integers, floating-point numbers, and strings of characters, to name three. When you declare a variable, you must specify the type of data it will hold.

You declare the type and name of a variable in a declaration statement. For example, the following statement declares that the variable named age holds int (integer) values. As always, the statement must be terminated with a semicolon.

int age;

The variable type int is the name of one of the primitive C# types, integer, which is a whole number. (You’ll learn about several primitive data types later in this chapter.)

NOTE

Microsoft Visual Basic programmers should note that C# does not allow implicit variable declarations. You must explicitly declare all variables before you use them.

After you’ve declared your variable, you can assign it a value. The following statement assigns age the value 42. Again, you’ll see that the semicolon is required.

age = 42;

The equal sign (=) is the assignment operator, which assigns the value on its right to the variable on its left. After this assignment, you can use the age variable in your code to refer to the value it holds. The next statement writes the value of the age variable, 42, to the console:

Console.WriteLine(age);

TIP

If you leave the mouse pointer over a variable in the Visual Studio 2012 Code and Text Editor window, a ScreenTip appears, telling you the type of the variable.

Working with Primitive Data Types

C# has a number of built-in types called primitive data types. The following table lists the most commonly used primitive data types in C# and the range of values that you can store in each.

Data type

Description

Size (bits)

Range

Sample usage

int

Whole numbers (integers)

32

–231 through 231 – 1

int count;

count = 42;

long

Whole numbers (bigger range)

64

–263 through 263 – 1

long wait;

wait = 42L;

float

Floating-point numbers

32

±1.5 x 10-45 through ±3.4 x 1038

float away;

away = 0.42F;

double

Double-precision (more accurate) floating-point numbers

64

±5.0 x 10-324 through ±1.7 x 10308

double trouble;

trouble = 0.42;

decimal

Monetary values

128

28 significant figures

decimal coin;

coin = 0.42M;

string

Sequence of characters

16 bits per character

Not applicable

string vest;

vest = “fortytwo”;

char

Single character

16

0 through 216 – 1

char grill;

grill = ‘x’;

bool

Boolean

8

true or false

bool teeth;

teeth = false;

Unassigned Local Variables

When you declare a variable, it contains a random value until you assign a value to it. This behavior was a rich source of bugs in C and C++ programs that created a variable and accidentally used it as a source of information before giving it a value. C# does not allow you to use an unassigned variable. You must assign a value to a variable before you can use it, otherwise your program will not compile. This requirement is called the definite assignment rule. For example, the following statements generate the compile-time error message “Use of unassigned local variable ‘age’” because the Console.WriteLine statement attempts to display the value of an uninitialized variable:

int age;

Console.WriteLine(age); // compile-time error

Displaying Primitive Data Type Values

In the following exercise, you use a C# program named PrimitiveDataTypes to demonstrate how several primitive data types work.

Display primitive data type values

1. Start Visual Studio 2012 if it is not already running.

2. On the FILE menu, point to Open, and then click Project/Solution.

The Open Project dialog box appears.

3. If you are using Windows 8, move to the \Microsoft Press\Visual CSharp Step By Step\Chapter 2\Windows 8\PrimitiveDataTypes folder in your Documents folder. If you are using Windows 7, move to the \Microsoft Press\Visual CSharp Step By Step\Chapter 2\Windows 7\PrimitiveDataTypes folder in your Documents folder.

NOTE

To avoid repetition and to save space, in subsequent exercises I will simply refer to solution paths by using a phrase of the form \Microsoft Press\Visual CSharp Step By Step\Chapter 2\Windows X\PrimitiveDataTypes, where X is either 7 or 8, depending on the operating system you are using.

4. Select the PrimitiveDataTypes solution file, and then click Open.

The solution loads, and Solution Explorer displays the PrimitiveDataTypes project.

NOTE

Solution file names have the .sln suffix, such as PrimitiveDataTypes.sln. A solution can contain one or more projects. Project files have the .csproj suffix. If you open a project rather than a solution, Visual Studio 2012 automatically creates a new solution file for it. This situation can be confusing if you are not aware of this feature, as it can result in you accidentally generating multiple solutions for the same project.

TIP

Be sure to open the solution file in the correct folder for your operating system. If you attempt to open a solution for a Windows Store app by using Visual Studio 2012 on Windows 7, the project will fail to load. Solution Explorer will mark the project as unavailable and display the message “This project requires Windows 8 or higher to load” if you expand the project node, as shown in the following image:

image with no caption

If this happens, close the solution and open the version in the correct folder.

5. On the DEBUG menu, click Start Debugging.

You might see some warnings in Visual Studio. You can safely ignore them. (You will correct them in the next exercise.)

If you are using Windows 8, the following page is displayed:

image with no caption

If you are using Windows 7, the following window appears:

image with no caption

6. In the Choose a Data Type list, click the string type.

The value “forty two” appears in the Sample Value box.

7. Click the int type in the list.

The value “to do” appears in the Sample Value box, indicating that the statements to display an int value still need to be written.

8. Click each data type in the list. Confirm that the code for the double and bool types is not yet implemented.

9. Return to Visual Studio 2012, and on the DEBUG menu click Stop Debugging.

NOTE

If you are using Windows 7, you can also click Quit to close the window and stop the program.

Use primitive data types in code

1. In Solution Explorer, expand the PrimitiveDataTypes project (if it is not already expanded) and then double-click MainWindow.xaml.

NOTE

To keep the exercise instructions simple, the forms in the Windows 8 and Windows 7 applications have the same names from now on.

The form for the application appears in the Design View window.

TIP

If your screen is not big enough to display the entire form, you can zoom in and out in the Design View window by using Ctrl+Alt+= and Ctrl+Alt+- or by selecting the size from the zoom drop-down list in the bottom-left corner of the Design View window.

2. In the XAML pane, scroll down to locate the markup for the ListBox control. This control displays the list of data types in the left part of the form, and it looks like this (some of the properties have been removed from this text):

3. <ListBox x:Name="type" ... SelectionChanged="typeSelectionChanged">

4. <ListBoxItem>int</ListBoxItem>

5. <ListBoxItem>long</ListBoxItem>

6. <ListBoxItem>float</ListBoxItem>

7. <ListBoxItem>double</ListBoxItem>

8. <ListBoxItem>decimal</ListBoxItem>

9. <ListBoxItem>string</ListBoxItem>

10. <ListBoxItem>char</ListBoxItem>

11. <ListBoxItem>bool</ListBoxItem>

</ListBox>

The ListBox control displays each data type as a separate ListBoxItem. When the application is running, if a user clicks an item in the list, the SelectionChanged event occurs (this is a little bit like the Clicked event that occurs when the user clicks a button, which you saw in Chapter 1). You can see that in this case, the ListBox invokes the typeSelectionChanged method. This method is defined in the MainWindow.xaml.cs file.

12.On the VIEW menu, click Code.

The Code and Text Editor window opens, displaying the MainWindow.xaml.cs file.

NOTE

Remember that you can also use Solution Explorer to access the code. Click the arrow to the left of the MainWindow.xaml file to expand the node, and then double-click MainWindow.xaml.cs.

13.In the Code and Text Editor window, find the typeSelectionChanged method.

TIP

To locate an item in your project, on the EDIT menu, point to Find and Replace, and then click Quick Find. A menu opens in the top-right corner of the Code and Text Editor window. In the text box in this menu, type the name of the item you’re looking for, and then click Find Next (this is the button with the right-arrow symbol next to the text box):

image with no caption

By default, the search is not case sensitive. If you want to perform a case-sensitive search, click the down arrow next to the text to search for, click the drop-down arrow to the right of the text box in the shortcut menu to display additional options, and then select the Match Case check box. If you have time, you can experiment with the other options as well.

You can also press Ctrl+F to display the Quick Find dialog box rather than using the EDIT menu. Similarly, you can press Ctrl+H to display the Quick Replace dialog box.

As an alternative to using the Quick Find functionality, you can also locate the methods in a class by using the class members drop-down list box above the Code and Text Editor window, on the right.

image with no caption

The class members drop-down list box displays all the methods in the class, together with the variables and other items that the class contains. (You will learn more about these items in later chapters.) In the drop-down list, click the typeSelectionChanged method, and the cursor will move directly to the typeSelectionChanged method in the class.

If you have programmed using another language, you can probably guess how the typeSelectionChanged method works; if not, then Chapter 4, will make this code clear. At present, all you need to understand is that when the user clicks an item in the ListBox control, the value of the item is passed to this method, which then uses this value to determine happens next. For example, if the user clicks the float value, then this method calls another method named showFloatValue.

14.Scroll down through the code and find the showFloatValue method, which looks like this:

15.private void showFloatValue()

16.{

17. float floatVar;

18. floatVar = 0.42F;

19. value.Text = floatVar.ToString();

}

The body of this method contains three statements. The first statement declares a variable named variable of type float.

The second statement assigns variable the value 0.42F. (The F is a type suffix specifying that 0.42 should be treated as a float value. If you forget the F, the value 0.42 is treated as a double and your program will not compile, because you cannot assign a value of one type to a variable of a different type without writing additional code—C# is very strict in this respect.)

The third statement displays the value of this variable in the Value text box on the form. This statement requires your attention. If you remember from Chapter 1, the way in which you display an item in a text box is to set its Text property (you did this by using XAML in Chapter 1). You can also perform this task programmatically, which is what is going on here. Notice that you access the property of an object by using the same dot notation that you saw for running a method. (Remember Console.WriteLine from Chapter 1?) Also, the data that you put in the Textproperty must be a string and not a number. If you try to assign a number to the Text property, your program will not compile. Fortunately, the .NET Framework provides some help in the form of the ToString method.

Every data type in the .NET Framework has a ToString method. The purpose of ToString is to convert an object to its string representation. The showFloatValue method uses the ToString method of the float variable floatVar object to generate a string version of the value of this variable. This string can then be safely assigned to the Text property of the Value text box. When you create your own data types and classes, you can define your own implementation of the ToString method to specify how your class should be represented as a string. You learn more about creating your own classes in Chapter 7

20.In the Code and Text Editor window, locate the showIntValue method:

21.private void showIntValue()

22.{

23. value.Text = "to do";

}

The showIntValue method is called when you click the int type in the list box.

24.Type the following two statements at the start of the showIntValue method, on a new line after the opening brace, as shown in bold type in the following code:

25.private void showIntValue()

26.{

27. int intVar;

28. intVar = 42;

29. value.Text = "to do";

}

The first statement creates a variable called intVar that can hold an int value. The second statement assigns the value 42 to this variable.

30.In the original statement in this method, change the string “to do” to “42”.

The method should now look exactly like this:

private void showIntValue()

{

int intVar;

intVar = 42;

value.Text = intVar.ToString();

}

31.On the DEBUG menu, click Start Debugging.

The form appears again.

32.Select the int type in the Choose a Data Type list. Confirm that the value 42 is displayed in the Sample Value text box.

33.Return to Visual Studio, and on the DEBUG menu click Stop Debugging.

34.In the Code and Text Editor window, find the showDoubleValue method.

35.Edit the showDoubleValue method exactly as shown in bold type in the following code:

36.private void showDoubleValue()

37.{

38. double doubleVar;

39. doubleVar = 0.42;

40. value.Text = doubeVar.ToString();

}

This code is similar to the showIntValue method, except that it creates a variable called doubleVar that holds double values, and it is assigned the value 0.42.

41.In the Code and Text Editor window, locate the showBoolValue method.

42.Edit the showBoolValue method exactly as follows:

43.private void showBoolValue()

44.{

45. bool boolVar;

46. boolVar = false;

47. value.Text = boolVar.ToString();

}

Again, this code is similar to the previous examples, except that boolVar can only hold a Boolean value, true or false.

48.On the DEBUG menu, click Start Debugging.

49.In the Choose a Data Type list, select the int, double, and bool types. In each case, verify that the correct value is displayed in the Sample Value text box.

50.Return to Visual Studio, and on the DEBUG menu click Stop Debugging.

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;

NOTE

The values that an operator operates on are called operands. In the expression 750 * 20, the * is the operator, and 750 and 20 are the operands.

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");

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");

TIP

The .NET Framework provides a method called Int32.Parse that you can use to convert a string value to an integer if you need to perform arithmetic computations on values held as strings.

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 adouble (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.

NOTE

If you are familiar with C or C++, you know that you can’t use the remainder operator on float or double values in these languages. However, C# relaxes this rule. The remainder operator is valid with all numeric types, and the result is not necessarily an integer. For example, the result of the expression 7.0 % 2.4 is 2.2.

NUMERIC TYPES AND INFINITE VALUES

There are one or two other features of numbers in C# that you should be aware of. For example, the result of dividing any number by zero is infinity, which is outside the range of the int, long, and decimal types; consequently, evaluating an expression such as 5/0 results in an error. However, the double and float types actually have a special value that can represent infinity, and the value of the expression 5.0/0.0 is Infinity. The one exception to this rule is the value of the expression 0.0/0.0. Usually, if you divide zero by anything, the result is zero, but if you divide anything by zero the result is infinity. The expression 0.0/0.0 results in a paradox—the value must be zero and infinity at the same time. C# has another special value for this situation called NaN, which stands for “not a number.” So if you evaluate 0.0/0.0, the result is NaN.

NaN and Infinity propagate through expressions. If you evaluate 10 + NaN, the result is NaN, and if you evaluate 10 + Infinity, the result is Infinity. The one exception to this rule is the case when you multiply Infinity by 0. The value of the expression Infinity * 0 is 0, although the value of NaN * 0 is NaN.

Examining Arithmetic Operators

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

Run the MathsOperators project

1. Start Visual Studio 2012 if it is not already running.

2. Open the MathsOperators project, located in the \Microsoft Press\Visual CSharp Step By Step\Chapter 2\Windows X\MathsOperators folder in your Documents folder.

3. On the DEBUG menu, click Start Debugging.

If you are using Windows 8, the following page appears:

image with no caption

If you are using Windows 7, the following form displays:

image with no caption

4. Type 54 in the Left Operand text box.

5. Type 13 in the Right Operand text box.

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

6. Click the – Subtraction button, and then click Calculate.

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

7. Click the / Division button, and then click Calculate.

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

8. Click the % Remainder button, and then click Calculate.

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

NOTE

If you type a noninteger value into either of the operand text boxes, the application detects an error and displays the message “Input string was not in a correct format.” You will learn more about how to catch and handle errors and exceptions in Chapter 6

9. When you have finished, return to Visual Studio, and on the DEBUG menu click Stop Debugging (if you are using Windows 7, you can also click Quit on the MathsOperators form).

As you may 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

1. Display the MainWindow.xaml form in the Design View window. (Double-click the file MainWindow.xaml in the MathsOperators project in Solution Explorer.)

2. 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 (Windows 8) orWindow (Windows 7) that constitutes the form. As mentioned in the previous chapter, a Windows Store app page or a WPF form contains a Grid control, and the other controls are placed in 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.

image with no caption

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 (pin the Document Outline window in place by deselecting the Auto Hide button in the top-right corner of the Document Outline window to see this in action.)

3. 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.

4. 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.

5. Close the Document Outline window.

6. On the VIEW menu, click Code to display the code for the MainWindow.xaml.cs file in the Code and Text Editor window.

7. In the Code and Text Editor window, locate the addValues method. It looks like this:

8. private void addValues()

9. {

10. int lhs = int.Parse(lhsOperand.Text);

11. int rhs = int.Parse(rhsOperand.Text);

12. int outcome;

13. // TODO: Add rhs to lhs and store the result in outcome

14. expression.Text = lhsOperand.Text + " + " + rhsOperand.Text;

15. 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 text 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 text 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 concatenates three strings indicating the calculation being performed (using the plus operator, +) and assigns the result to the expression.Text property. This causes the string to appear in the Expression text box on the form.

The final statement displays the result of the calculation by assigning it to the Text property of the Result text 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.

16.Underneath the comment in the middle of the addValues method, add the statement shown below in bold:

17.private void addValues()

18.{

19. int lhs = int.Parse(lhsOperand.Text);

20. int rhs = int.Parse(rhsOperand.Text);

21. int outcome;

22. // TODO: Add rhs to lhs and store the result in outcome

23. outcome = lhs + rhs;

24. expression.Text = lhsOperand.Text + " + " + rhsOperand.Text;

25. result.Text = outcome.ToString();

}

This statement evaluates the expression lhs + rhs and stores the result in outcome.

26.Examine the subtractValues method. You should see that it follows a similar pattern, and you need to add the statement to calculate the result of subtracting rhs from lhs and storing it in outcome. Add the statement shown below in bold to this method:

27.private void subtractValues()

28.{

29. int lhs = int.Parse(lhsOperand.Text);

30. int rhs = int.Parse(rhsOperand.Text);

31. int outcome;

32. // TODO: Subtract rhs from lhs and store the result in outcome

33. outcome = lhs - rhs;

34. expression.Text = lhsOperand.Text + " - " + rhsOperand.Text;

35. result.Text = outcome.ToString();

}

36.Examine the mutiplyValues, divideValues, and remainderValues methods. Again, they all have the crucial statement that performs the specified calculation missing. Add the appropriate statements to these methods (shown below in bold).

37.private void multiplyValues()

38.{

39. int lhs = int.Parse(lhsOperand.Text);

40. int rhs = int.Parse(rhsOperand.Text);

41. int outcome = 0;

42. // TODO: Multiply lhs by rhs and store the result in outcome

43. outcome = lhs * rhs;

44. expression.Text = lhsOperand.Text + " * " + rhsOperand.Text;

45. result.Text = outcome.ToString();

46.}

47.

48.private void divideValues()

49.{

50. int lhs = int.Parse(lhsOperand.Text);

51. int rhs = int.Parse(rhsOperand.Text);

52. int outcome = 0;

53. // TODO: Divide lhs by rhs and store the result in outcome

54. outcome = lhs / rhs;

55. expression.Text = lhsOperand.Text + " / " + rhsOperand.Text;

56. result.Text = outcome.ToString();

57.}

58.

59.private void remainderValues()

60.{

61. int lhs = int.Parse(lhsOperand.Text);

62. int rhs = int.Parse(rhsOperand.Text);

63. int outcome = 0;

64. // TODO: Work out the remainder after dividing lhs by rhs and store the result

65. outcome = lhs % rhs;

66. expression.Text = lhsOperand.Text + " % " + rhsOperand.Text;

67. result.Text = outcome.ToString();

}

Test the MathsOperators application

1. On the DEBUG menu, click Start Debugging to build and run the application.

2. Type 54 in the Left Operand text box, type 13 in the Right Operand text box, click the + Addition button, and then click Calculate.

The value 67 should appear in the Result text box.

3. Click the – Subtraction button and then click Calculate. Verify that the result is now 41.

4. Click the * Multiplication button and then click Calculate. Verify that the result is now 702.

5. Click the / Division button 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.

6. Click the % Remainder button 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 school mathematics teacher would be horrified to be told that (54/13) * 13 does not equal 54!)

7. Return to Visual Studio and stop debugging (or click Quit if you are using Windows 7).

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

NOTE

The term parentheses or round brackets refers to (). The term braces or curly brackets refers to { }. The term square brackets refers to [ ].

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 its right side is evaluated and then stored in the operand on its 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 this:

myInt3 = myInt / myInt2;

the compiler generates the following errors:

Use of unassigned local variable 'myInt'

Use of unassigned local variable 'myInt2'

Incrementing and Decrementing Variables

If you want to add 1 to a variable, you can use the + operator:

count = count + 1;

However, adding 1 to a variable is so common that C# provides its own operator just for this purpose: the ++ operator. To increment the variable count by 1, you can write the following statement:

count++;

Similarly, C# provides the –– operator that you can use to subtract 1 from a variable, like this:

count--;

The ++ and –– operators are unary operators, meaning that they take only a single operand. They share the same precedence and are both left-associative.

Prefix and Postfix

The increment, ++, and decrement, ––, operators are unusual in that you can place them either before or after the variable. Placing the operator symbol before the variable is called the prefix form of the operator, and using the operator symbol after the variable is called the postfix form. Here are examples:

count++; // postfix increment

++count; // prefix increment

count--; // postfix decrement

--count; // prefix decrement

Whether you use the prefix or postfix form of the ++ or –– operator makes no difference to the variable being incremented or decremented. For example, if you write count++, the value of count increases by 1, and if you write ++count, the value of count also increases by 1. Knowing this, you’re probably wondering why there are two ways to write the same thing. To understand the answer, you must remember that ++ and –– are operators and that all operators are used to evaluate an expression that has a value. The value returned by count++ is the value of count before the increment takes place, whereas the value returned by ++count is the value of count after the increment takes place. Here is an example:

int x;

x = 42;

Console.WriteLine(x++); // x is now 43, 42 written out

x = 42;

Console.WriteLine(++x); // x is now 43, 43 written out

The way to remember which operand does what is to look at the order of the elements (the operand and the operator) in a prefix or postfix expression. In the expression x++, the variable x occurs first, so its value is used as the value of the expression before x is incremented. In the expression++x, the operator occurs first, so its operation is performed before the value of x is evaluated as the result.

These operators are most commonly used in while and do statements, which are presented in Chapter 5 If you are using the increment and decrement operators in isolation, stick to the postfix form and be consistent.

Declaring Implicitly Typed Local Variables

Earlier in this chapter, you saw that you declare a variable by specifying a data type and an identifier, like this:

int myInt;

It was also mentioned that you should assign a value to a variable before you attempt to use it. You can declare and initialize a variable in the same statement, like this:

int myInt = 99;

Or you can even do it like this, assuming that myOtherInt is an initialized integer variable:

int myInt = myOtherInt * 99;

Now, remember that the value you assign to a variable must be of the same type as the variable. For example, you can assign an int value only to an int variable. The C# compiler can quickly work out the type of an expression used to initialize a variable and indicate if it does not match the type of the variable. You can also ask the C# compiler to infer the type of a variable from an expression and use this type when declaring the variable by using the var keyword in place of the type, like this:

var myVariable = 99;

var myOtherVariable = "Hello";

The variables myVariable and myOtherVariable are referred to as implicitly typed variables. The var keyword causes the compiler to deduce the type of the variables from the types of the expressions used to initialize them. In these examples, myVariable is an int, and myOtherVariable is astring. However, it is important for you to understand that this is a convenience for declaring variables only, and that after a variable has been declared you can assign only values of the inferred type to it—you cannot assign float, double, or string values to myVariable at a later point in your program, for example. You should also understand that you can use the var keyword only when you supply an expression to initialize a variable. The following declaration is illegal and causes a compilation error:

var yetAnotherVariable; // Error - compiler cannot infer type

IMPORTANT

If you have programmed with Visual Basic in the past, you might be familiar with the Variant type, which you can use to store any type of value in a variable. I emphasize here and now that you should forget everything you ever learned when programming with Visual Basic about Variant variables. Although the keywords look similar, var and Variant mean totally different things. When you declare a variable in C# using the var keyword, the type of values that you assign to the variable cannot change from that used to initialize the variable.

If you are a purist, you are probably gritting your teeth at this point and wondering why on earth the designers of a neat language such as C# should allow a feature such as var to creep in. After all, it sounds like an excuse for extreme laziness on the part of programmers and can make it more difficult to understand what a program is doing or track down bugs (and it can even easily introduce new bugs into your code). However, trust me that var has a very valid place in C#, as you will see when you work through many of the following chapters. However, for the time being, we will stick to using explicitly typed variables except for when implicit typing becomes a necessity.

Summary

In this chapter, you have seen how to create and use variables, and you have learned about some of the common data types available for variables in C#. You have learned about identifiers. In addition, you have used a number of operators to build expressions, and you have learned how the precedence and associativity of operators determine how expressions are evaluated.

§ If you want to continue to the next chapter

Keep Visual Studio 2012 running, and turn to Chapter 3.

§ If you want to exit Visual Studio 2012 now

On the FILE menu, click Exit. If you see a Save dialog box, click Yes and save the project.

Chapter 2 Quick Reference

To

Do this

Declare a variable

Write the name of the data type, followed by the name of the variable, followed by a semicolon. For example:

int outcome;

Declare a variable and give it an initial value

Write the name of the data type, followed by the name of the variable, followed by the assignment operator and the initial value. Finish with a semicolon. For example:

int outcome = 99;

Change the value of a variable

Write the name of the variable on the left, followed by the assignment operator, followed by the expression calculating the new value, followed by a semicolon. For example:

outcome = 42;

Generate a string representation of the value in a variable

Call the ToString method of the variable. For example:

int intVar = 42;

string stringVar = intVar.ToString();

Convert a string to an int

Call the System.Int32.Parse method. For example:

string stringVar = "42";

int intVar = System.Int32.Parse(stringVar);

Override the precedence of an operator

Use parentheses in the expression to force the order of evaluation. For example:

(3 + 4) * 5

Assign the same value to several variables

Use an assignment statement that lists all the variables. For example:

myInt4 = myInt3 = myInt2 = myInt = 10;

Increment or decrement a variable

Use the ++ or -- operator. For example:

count++;