This lesson introduces C# expressions, types, and variables. It's goal
is to meet the following objectives:
Left associativity means that operations are evaluated from left to
right. Right associativity mean all operations occur from right to left,
such as assignment operators where everything to the right is evaluated before
the result is placed into the variable on the left.
Listing 1-2. Unary Operators: Unary.cs
- using System;
class Unary
{
public static
void Main()
{
int unary = 0;
int preIncrement;
int preDecrement;
int
postIncrement;
int
postDecrement;
int positive;
int negative;
sbyte bitNot;
bool logNot;
preIncrement = ++unary;
Console.WriteLine("Pre-Increment:
{0}", preIncrement);
preDecrement = --unary;
Console.WriteLine("Pre-Decrement:
{0}", preDecrement);
postDecrement = unary--;
Console.WriteLine("Post-Decrement:
{0}", postDecrement);
postIncrement = unary++;
Console.WriteLine("Post-Increment:
{0}", postIncrement);
Console.WriteLine("Final
Value of Unary: {0}", unary);
positive = -postIncrement;
Console.WriteLine("Positive:
{0}", positive);
negative = +postIncrement;
Console.WriteLine("Negative:
{0}", negative);
bitNot = 0;
bitNot = (sbyte)(~bitNot);
Console.WriteLine("Bitwise
Not: {0}", bitNot);
logNot = false;
logNot = !logNot;
Console.WriteLine("Logical
Not: {0}", logNot);
}
}
When evaluating expressions, post-increment and post-decrement operators
return their current value and then apply the operators. However, when
using pre-increment and pre-decrement operators, the operator is applied to the
variable prior to returning the final value.
In Listing 1-2, the "unary" variable is initialized to zero.
When the pre-increment (++x) operator is used, "unary" is incremented
to 1 and the value 1 is assigned to the "preIncrement" variable.
The pre-decrement (--x) operator turns "unary" back to a 0 and then
assigns the value to the "preDecrement" variable.
When the post-decrement (x--) operator is used, the value of
"unary", 0, is placed into the "postDecrement"
variable and then "unary" is decremented to -1. Next the post
increment (x++) operator moves the current value of "unary", -1, to
the "postIncrement" variable and then increments "unary" to
0.
The variable "bitNot" is initialized to zero and the bitwise not
operator is applied. The bitwise not (~) operator flips the bits in the
variable. In this case, the binary representation of 0,
"00000000", was transformed into -1, "11111111".
Notice the expression "(sbyte)(~bitNot)". Any operation
performed on types sbyte, byte, short, or ushort return integer values. To
assign the result into the bitNot variable we had to use a cast (Type) operator,
where Type is the type you wish to convert to (in this case - sbyte). Cast
operators must be performed explicity when you go from a larger type to a
smaller type because of the potential for lost data. Generally speaking,
assigning a smaller type to a larger type is no problem, since the larger type
has room to hold the entire value. Also be aware of the dangers of casting
between signed and unsigned types. You want to be sure to preserve the
integrity of your data. Many basic programming texts contain good
descriptions of bit representations of variables and the dangers of explicit
casting.
The logical not (!) operator allows you to toggle the value of a boolean
variable. In the example, the "logNot" variable is changed from
false to true. You can expect the following output from the above program.
- >Pre-Increment: 1
>Pre-Decrement 0
- >Post-Decrement: 0
>Post-Increment -1
- >Final Value of Unary: 0
>Positive: 1
- >Negative: -1
>Bitwise Not: -1
- >Logical Not: True
Listing 1-3. Binary Operators: Binary.cs
- using System;
class Binary
{
public static
void Main()
{
int x, y,
result;
float
floatResult;
x = 7;
y = 5;
result = x+y;
Console.WriteLine("x+y:
{0}", result);
result = x-y;
Console.WriteLine("x-y:
{0}", result);
result = x*y;
Console.WriteLine("x*y:
{0}", result);
result = x/y;
Console.WriteLine("x/y:
{0}", result);
floatResult = (float)x/(float)y;
Console.WriteLine("x/y:
{0}", floatResult);
result = x%y;
Console.WriteLine("x%y:
{0}", result);
result += x;
Console.WriteLine("result+=x:
{0}", result);
}
}
Listing 1-3 shows several examples of binary operators. As you might
expect, the results of addition (+), subtraction (-), multiplication (*), and
division (/) produce the expected mathematical results.
The "floatResult" variable is a floating point type. We
explicitly cast the integer variables "x" and "y" to
calculate a floating point value.
There is also an example of the remainder(%) operator. It
performs a division operation on two values and returns the remainder.
The last statement shows another form of the assignment with operation (+=)
operator. Any time you use the assignment with operation operator, it's
the same as applying the binary operator to both the left hand and right hand
sides of the operator and putting the results into the left hand side. The
example could have been written as "result = result + x" and returned
the same value.
One type you've seen a lot in the last two lessons is the "string"
type. The "string" type is represented by a list of Unicode
characters within single quotes. i.e. "This is a string."
Another data type is the Array. Arrays can be thought of as containers
that have a list of storage locations for a specified type. When declaring
an Array, you specify the type, Array name, dimensions, and size.
Listing 1-4. Array Operations: Array.cs
- using System;
class Array
{
public static
void Main()
{
int[] myInts = {
5, 10, 15 };
bool[][] myBools
= new bool[2][];
myBools[0] = new
bool[2];
myBools[1] = new
bool[1];
double[,]
myDoubles = new double[2,
2];
string[]
myStrings = new string[3];
Console.WriteLine("myInts[0]:
{0}, myInts[1]: {1}, myInts[2]: {2}", myInts[0], myInts[1], myInts[2]);
myBools[0][0] = true;
myBools[0][1] = false;
myBools[1][0] = true;
Console.WriteLine("myBools[0][0]:
{0}, myBools[1][0]: {1}", myBools[0][0], myBools[1][0]);
myDoubles[0, 0] = 3.147;
myDoubles[0, 1] = 7.157;
myDoubles[1, 1] = 2.117;
myDoubles[1, 0] = 56.00138917;
Console.WriteLine("myDoubles[0,
0]: {0}, myDoubles[1, 0]: {1}", myDoubles[0, 0], myDoubles[1, 0]);
myStrings[0] = "Joe";
myStrings[1] = "Matt";
myStrings[2] =
"Robert";
Console.WriteLine("myStrings[0]:
{0}, myStrings[1]: {1}, myStrings[2]: {2}", myStrings[0], myStrings[1],
myStrings[2]);
}
}
Listing 1-4 shows different implementations of Arrays. The first
example is the "myInts" Array. It is initialized at declaration
time with explicit values.
Next is a jagged array. It is essentially an array of arrays. We
needed to use the "new" operator to instantiate the size of the
primary array and then use the new operator again for each sub-array.
The third example is a two dimensional array. Arrays can be
multi-dimensional, with each dimension separated by a comma. it must also
be instantiated with the "new" operator.
Finally, we have the one dimensional array of strings.
In each case, you can see that array elements are accessed by identifying the
integer index for the item you wish to refer to. Arrays sizes can be any
"int" type value. Their indexes always begin at 0. Here's
the output from Listing 1-4:
>myInts[0]: 5, myInts[1]: 10, myInts[2]: 15
>myBools[0][0]: True, myBools[1][0]: True
>myDoubles[0, 0]: 3.147, myDoubles[1, 0]: 56.00138917
>myStrings[0]: Joe, myStrings[1]: Matt, myStrings[2]: Robert
By now you know what a C# variable is. You have learned the C# simple
data types as well as arrays and strings. You also know how to form
expressions with C# operators.
I invite you to return for Lesson 3: Control Statements.
Your feedback is very
important and I appreciate any constructive comments you have. Please feel free
to contact me for any questions or comments you may have about this lesson.
Feedback
Copyright © 2000 C# Station, All Rights Reserved