Syntax, Data Types, Arithmetic, Strings, Input

In thesenotes we’ll look at the basic structure and methods involved in creating C# programs.

General Format of a Simple C# Program

In general, your programs will have the following structure:

using System;

using System.Text;

using...

namespace NameOfProject

{

classNameOfProgram

{

public or private variable declarations

public or private method declarations

staticvoid Main(string[] args)

{

Code here for the starting method...

}

}

}

The “using” statement at the top tells the C# compiler what other namespaces you want to use. Rather than rewrite commonly used code from scratch, you can use pre-built code that is organized in these namespaces. The “using” statement specifies which namespace you wish to use. Next we have class which defines our object. We’ll say a lot more about classes later. For now, all C# programs are organized into classes. When you create a Windows application the IDE adds a class for you called Form1. Inside the class, you will declare variables that belong to that class. We’ll focus on two categories of variables, public and private, where public is information we’ll make available to the rest of the program, and private is only available within the class. Then we’ll define methods that make up the class. Methods perform actions and consists of a group of statements. Each statement corresponds to a single action. The curly braces define blocks of code that make up methods, namespaces, classes, etc.

For example, previously we added the code:

MessageBox.Show("Contact list 1.0. \nWritten by: Kenrick Mock", "About");

This line of code is a single statement. It consists of an invocation to a method called Show that displays information in a window. It sends two arguments to the method, one with the text to display in the window and the other with the text to label the window.

Your program knows where to start

When you created a new Windows application, one of the files added by the IDE is called Program.cs. If you look at it then you will see something like the following:

amespace ContactDatabase

{

staticclassProgram

{

///<summary>

/// The main entry point for the application.

///</summary>

[STAThread]

staticvoid Main()

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(newForm1());

}

}

The // are comments and are ignored by the compiler. They are useful for the programmer to add a description of what the program is doing. Three slashes has special meaning to the IDE; normally a programmer would use two slashes.

Every C# program has a special entry point, the method called Main. Even though your program can have a lot of methods, only one can be the first one that gets executed, and that’s your Main method. You can experiment by adding a new Main method to a new Class and rename the old Main method to something else. This will change the entry point to the new Main.

Text Output

To output text, we used “MessageBox.Show” and the message we wanted within quotation marks. The entity in quotation marks is called a literal string because it’s directly embedded in the program. But what if we wanted to print out a double quotation mark? The computer would get confused because it would think the quotation mark you want to print really ends the message to be printed:

static void Main()

{

MessageBox.Show("Jessica Simpson said, "Am I eating chicken or tuna?"");

}

What will happen when this program is compiled? The compiler will complain about missing some expected character. Text enclosed in double quotes is referred to as strings. If we want to print a double quote itself (or some other special characters) then we need to use an escape character. In C#, the escape character is \. The program that works is:

MessageBox.Show("Jessica Simpson said, \"Am I eating chicken or tuna?\"");

Some other escape characters:

\n - newline, Moves the cursor to the next line like endl

\t - horizontal tab

\r- carriage return, but does not advance the line

\\- print the escape character itself

An alternate technique to output text is to use Console.WriteLine. This will output text to the “Output” window. You might have to make sure it is visible in the IDE. If you run a program from a command prompt then anything output to the console will show up in the command prompt. The following outputs the text to the console:

Console.WriteLine("Jessica Simpson said, \"Am I eating chicken or tuna?\"");

The console can be particularly handy for debugging purposes or writing quick programs to output some data.

Variables and Identifiers

Let’s expand our program a little bit more to include some identifiers. An identifier is made up of letters, numbers, and underscores, but must begin with a letter or an underscore.

BEWARE: C# is case sensitive. This means that Value, VALUE, value, and vaLue are four separate identifiers. In fact, we can construct 32 distinct identifiers from these five letters by varying the capitalization. Which of these identifiers are valid?

_FoosBallF00sBall%FoosBall9FoosBall%12391 _*_ _FF99

Note: When picking identifiers try to select meaningful names!

Here is a short program that uses some variables as identifiers:

staticvoid Main()

{

char period = '.';// Single quotes

string name = "Cotty, Manny";// Double quotes

string foods = "cheese and pasta";

int someNum = 15;

Console.WriteLine(name + " loves to eat " + foods);

Console.WriteLine(someNum + " times as much as you" + period);

}

Let’s walk through the program:

Lines 3 through 6 instruct the compiler to assign variables of a particular type. The format is to first indicate the data type identifier, in this case char, string, or int.

-char indicates that the value to be stored is to hold a single ASCII character.

-string indicates that the value to be stored can be composed of many characters.

-int indicates that we want to store an integer value

In line 3, a period is stored in the variable named period. In line 4, the string made up of the characters ‘C’, ‘o’, ‘t’, ‘t’, ‘y’, ‘,’ , ‘ ‘, ‘M’, ‘a’, ‘n’, ‘n’, ‘y’ is stored in name. By convention, most C# programmers use all uppercase for identifiers that won’t change, and lowercase mixed with uppercase for ones that may change. Since these strings won’t change, we could have named this identifier NAME instead of name.

In line 6, we defined one numeric value, someNum to 15. This sets someNum to fifteen.

When the compiler processes the variable declarations, it assigns a memory location to each one. It is intended that the data we store in each memory location is of the same type that we defined it in the program. For example, we defined someNum to be of type int. This means we should only store integers into the memory location allocated for someNum. We shouldn’t be storing floating point numbers, strings, or characters.

Finally, we have output statements that print the contents of the variables. Note that when we use WriteLine, we can print out variables of different types and concatenate the output using the + symbol. The + symbol will also serve as addition as we will see later! So be aware that a symbol may do different things in a different context.

The final output when run is:

Cotty, Manny loves to eat cheese and pasta

15 times as much as you.

Words and Symbols with Special Meanings

Certain words have predefined meanings within the C# language; these are called reserved words or keywords. For example, the names of data types are reserved words. In the sample program there are reserved words: char, int, void, main. We aren’t allowed to use reserved words as names for your identifiers. A complete list of reserved words is given in the book.

Data Types

A data type is a set of values and a set of operations on these values. In the preceding program, we used the data type identifiers int, char, and string.

C# distinguishes between a number of fundamental data types. Of these, the ones we will use most commonly are:

int

long

float (also called a single)

double

string

char

byte

bool

The table below summarizes the different types:

An int is a positive or negative number with no value past the decimal point. Note the limitation on the range of values it can hold. If we allocate more storage space (e.g., more bytes) then we can represent larger numbers.

The long data type uses 8 bytes of storage instead of 4 like the int, so it can represent much larger values.

Similarly, C# has two commonly used floating point values: float and double. These data types are used to represent real numbers. The float uses 4 bytes and the double uses 8 bytes, so the double can store larger values than the float (also called a single.)

If double has a larger data range than integer, and can store floating point numbers, you might wonder why we don’t just always use a double. We could do this, but it would be wasteful – the double format takes up more space than an integer. Also it is slower to perform arithmetic operations on a number stored as double than it is on a number stored as integer. The integer data type is better to use if that is all your application needs.

boolstands for Boolean and is used to represent True or False. These are the only two values that are allowed. Booleans are useful in programming due to their ability to select a course of action based upon some outcome that is either true or false, so we will use Booleans extensively in decision-making.

Strings consist of textual data and are enclosed in double-quotes. Strings are represented as a sequence of bit patterns that match to alphanumeric values. For example, consider the following mapping for the letters A, B, and C:

A01000001

B01000010

C01000011

To store the string “CAB” we would simply concatenate all of these codes:

01000011 01000001 01000010

Note that there is a difference between a string of numbers, and a number such as an Integer. Consider the string “0” and the number 0. The String “0” is represented by the bit pattern 00110000 while the integer 0 is represented by 00000000. Similarly, the string “10” would be represented as 00110001 00110000 while the integer 10 is represented as 00001010.

Strings are simply a sequence of encoded bit patterns, while integers use the binary number format to represent values. We will often convert back and forth between String and Number data types.

Numbers

We have already seen a little bit of working with numbers – for example, setting the size or position of a window. When we put a numeric value directly into the program, these are called numeric literals.

C# allows us to perform standard arithmetic operations:

Arithmetic OperatorC# Symbol

Addition+

Subtraction-

Multiplication*

Division/ (truncation if both operands are integers!)

Modulus%

Here are some examples of arithmetic operations and outputting the result to the console:

Console.WriteLine(3 + 2);

Console.WriteLine (3 - 2);

Console.WriteLine (5 * 2 * 10);

Console.WriteLine (14 % 5);

Console.WriteLine (9 % 4);

Console.WriteLine (10 / 2);

Console.WriteLine (11 / 2);

Console.WriteLine (1 / 2);

Console.WriteLine(1.0 / 2);

The results are:

5

1

100

4

1

5

5

0

0.5

Take care when using division! If an intermediate result is less than zero, the whole thing becomes zero, even though mathematically it should not be zero:

Console.WriteLine((1 / 2) * 4);

In addition to the standard arithmetic operators, C# provides an increment operator and a decrement operator. The increment operator ++ adds one to its operand; the decrement operator -- subtracts one from its operand.

To complicate matters a bit more, if ++ and -- are used within an expression, we get different results depending upon its placement. ++x is a pre-increment while x++ is a post-increment operation. In a pre-increment operation, the variable is incremented before evaluated. In a post-increment operation, the variable is not incremented until after evaluation. Consider the following example:

int x=1;

int y=1;

x = (y++)*2;

Console.WriteLine(x + " " + y);

x = 1;

y = 1;

x = (++y)*2;

Console.WriteLine(x + " " + y);

The output from this program is:

2 2

4 2

In the post-increment evaluation of (y++)*2, we assign the current value of y multiplied by 2 into x (which is 1*2 = 2) and then increment y to 2.

In the pre-increment evaluation of (++y)*2, we first increment y to 2, then compute 2*2=4 and assign that into x.

Shorthand Assignment Operators

A useful shorthand in C# for assignment statements is to combine the assignment along with a mathematical operator. In general, we can use a math symbol in combination with an = to apply the operation to the same variable on the left, and store the result back into that variable.

The following are equivalent:

x = x+ yx += y

x = x* yx *= y

x = x - yx -= y

x = x/ yx /= y

x = x% yx %= y

Generally these are used with constants; e.g.:

x += 5;

Precedence Rules

The precedence rules of arithmetic apply to arithmetic expressions in a program. That is, the order of execution of an expression that contains more than one operation is determined by the precedence rules of arithmetic. These rules state that:

  1. parentheses have the highest precedence
  2. multiplication, division, and modulus have the next highest precedence
  3. addition and subtraction have the lowest precedence.

Because parentheses have the highest precedence, they can be used to change the order in which operations are executed. When operators have the same precedence, order is left to right.

Examples:

int x;Value stored in X

x = 1 + 2 + 6 / 6; 4

x = (1 + 2 + 3) / 6;1

x = 2 * 3 + 4 * 5;26

x = 2 / 4 * 4;2

x = 2 / (4 * 4);0

x = 10 % 2 + 1;1

In general it is a good idea to use parenthesis if there is any possibility of confusion.

There are a number of built-in math functions that are useful with numbers. Here are just a few:

Math.Sqrt(number)returns the square root of number

Ex:

Console.WriteLine(Math.Sqrt(9));// Displays 3

double d;

d = Math.Sqrt(25);

Console.WriteLine(d);// Displays 5

Console.WriteLine(Math.Sqrt(-1));// Displays NaN

Math.Round(number);returns the number rounded up/down

Ex: Math.Round(2.7);returns 3

Math.Abs(number);returns the absolute value of number

Ex: Math.Abs(-4);returns 4

There are many more, for sin, cos, tan, atan, exp, log, etc.

When we have many variables of the same type it can sometimes be tedious to declare each one individually. C# allows us to declare multiple variables of the same type at once, and assign initial values if we like, for example:

double a, b;

double c = 2, d = 5.5;

int e = 10;

(Break for Who Wants To Be A Millionaire Quiz)Converting Numeric Types

If an integral and a floating point variable or constant are mixed in an operation, the integral value is changed temporarily to its equivalent floating point representation before the operation is executed. This automatic conversion of an integral value to a floating point value is called type coercion. In C#, if a literal floating point value like 0.5 is represented as a double. For example the expression:

1 / 2.0

The 2.0 is represented as a double, the 1 is converted from an int to a double, and the division is performed on two doubles resulting in 0.5 as a double.

When we perform an assignment the data types must match. A common problem is trying to assign a floating point value into an integer variable:

intVar = floatValue;

The compiler will complain that the types don’t match. One way around this problem is to explicitly cast the type:

intVar = (int) floatValue;

This is done by putting the “target” type in parenthesis; floatValue is turned into an int, then the int is copied into intVar. However, when a floating point value is coerced into an integral value, loss of information occurs unless the floating point value is a whole number. That is, 1.0 can be coerced into 1, but what about 1.5? Is it coerced into 1 or 2? In C# when a floating point value is coerced into an integral value, the floating point value is truncated. Thus, the floating point value 1.5 is coerced into 1:

intVar = (int) 1.5;// 1 is copied into intVar

intVar = (int) 1.2;// 1 is copied into intVar

Type changes can be made explicit using the Convert class:

intValue = Convert.ToInt32(10.66);

this rounds up and produce the value 11 in intValue. I tend to like using the Convert technique because it’s more general and works in more cases, but does take longer to type.

We can convert to Double, Long, String, Single (float) and every other common data type. Later we’ll use this to convert strings to numeric values.

Sometimes the mistake is made that a data type is a floating point type but we end up with an integer value instead. Here is an example with float:

float x=1;

x = 11 / 2;

Console.WriteLine(x);

You might think this would produce 5.5. But instead it produces 5.0. Why? How to fix it?

How about the following:

x = 2 / 4 * 4 / 2;

x = 2 / 4.0 * 4 / 2;// Gives error message about double/float

We get an error message on the last expression because 4.0 is considered a double and this forces the entire right hand side to be computed as a double, but then the double is assigned into a float (x). We can convert it, but at the potential of a loss of precision in the double since it stores more bits than the float:

x = Convert.ToSingle(2 / 4.0 * 4 / 2);

The bottom line here is to be careful if you are mixing integers with floating point values in arithmetic expressions. Especially if performing division, you might end up with zero when you really want a floating point fractional answer. The solution is to coerce one of the integers into a float or double so the entire calculation is made using floating point.

Example

Let’s put together what we know so far with an example program. Here is the problem:

You are running a marathon (26.2 miles) and would like to know what your finishing time will be if you run a particular pace. Most runners calculate pace in terms of minutes per mile. So for example, let’s say you can run at 7 minutes and 30 seconds per mile. Write a program that calculates the finishing time and outputs the answer in hours, minutes, and seconds.

Input:

Distance : 26.2

PaceMinutes: 7

PaceSeconds: 30

Output:

3 hours, 16 minutes, 30 seconds

For now we’ll just hard-code the inputs into the program, but shortly we will allow the user to enter values when running the program.

Here is one algorithm to solve this problem:

  1. Express pace in terms of seconds per mile, call this SecsPerMile
  2. Multiply SecsPerMile * 26.2 to get the total number of seconds to finish. Call this result TotalSeconds.
  3. There are 60 seconds per minute and 60 minutes per hour, for a total of 60*60 = 3600 seconds per hour. If we divide TotalSeconds by 3600 and throw away the remainder, this is how many hours it takes to finish.
  4. TotalSeconds mod 3600 gives us the number of seconds leftover after the hours have been accounted for. If we divide this value by 60, it gives us the number of minutes, i.e. (TotalSeconds % 3600) / 60
  5. TotalSeconds mod 3600 gives us the number of seconds leftover after the hours have been accounted for. If we mod this value by 60, it gives us the number of seconds leftover. (We could also divide by 60, but that doesn’t change the result), i.e. (TotalSeconds % 3600) mod 60
  6. Output the values we calculated!

Code: