Tuesday, April 15, 2014

Variables



After reviewing the main data types in C# let’s see how we can use them. In order to work with data we should use variables. We have already seen their usage in the examples, but now let’s look at them in more detail.
A variable is a container of information, which can change its value. It provides means for:
-      storing information;
-      retrieving the stored information;
-      modifying the stored information.
In C# programming, you will use variables to store and process information all the time.

Characteristics of Variables

Variables are characterized by:
-      name (identifier), for example age;
-      type (of the information preserved in them), for example int;
-      value (stored information), for example 25.
A variable is a named area of memory, which stores a value from a particular data type, and that area of memory is accessible in the program by its name. Variables can be stored directly in the operational memory of the program (in the stack) or in the dynamic memory in which larger objects are stored (such as character strings and arrays).
Primitive data types (numbers, char, bool) are called value types because they store their value directly in the program stack.
Reference data types (such as strings, objects and arrays) are an address, pointing to the dynamic memory where their value is stored. They can be dynamically allocated and released i.e. their size is not fixed in advance contrary to the case of value types.
More information about the value and reference data types is provided in the section "Value and Reference Types".

Naming Variables – Rules

When we want the compiler to allocate a memory area for some information which is used in our program we must provide a name for it. It works like an identifier and allows referring to the relevant memory area.
The name of the variable can be any of our choice but must follow certain rules defined in the C# language specification:
-      Variable names can contain the letters a-z, A-Z, the digits 0-9 as well as the character '_'.
-      Variable names cannot start with a digit.
-      Variable names cannot coincide with a keyword of the C# language. For example, base, char, default, int, object, this, null and many others cannot be used as variable names.
A list of the C# keywords can be found in the section "Keywords" in chapter "Introduction to Programming". If we want to name a variable like a keyword, we can add a prefix to the name – "@". For example, @char and @null are valid variable names while char and null are invalid.

Naming Variables – Examples

Proper names:
-      name
-      first_Name
-      _name1
Improper names (will lead to compilation error):
-      1 (digit)
-      if (keyword)
-      1name (starts with a digit)

Naming Variables – Recommendations

We will provide some recommendations how to name your variables, since not all names, allowed by the compiler, are appropriate for the variables.
-      The names should be descriptive and explain what the variable is used for. For example, an appropriate name for a variable storing a person’s name is personName and inappropriate name is a37.
-      Only Latin characters should be used. Although Cyrillic is allowed by the compiler, it is not a good practice to use it in variable names or in the rest of the identifiers within the program.
-      In C# it is generally accepted that variable names should start with a small letter and include small letters, every new word, however, starts with a capital letter. For instance, the name firstName is correct and better to use than firstname or first_name. Usage of the character _ in the variable names is considered a bad naming style.
-      Variable names should be neither too long nor too short – they just need to clarify the purpose of the variable within its context.
-      Uppercase and lowercase letters should be used carefully as C# distinguishes them. For instance, age and Age are different variables.
Here are some examples of well-named variables:
-      firstName
-      age
-      startIndex
-      lastNegativeNumberIndex
And here are some examples for poorly named variables (although the names are correct from the C# compiler’s perspective):
-      _firstName (starts with _)
-      last_name (contains _)
-      AGE (is written with capital letters)
-      Start_Index (starts with capital letter and contains _)
-      lastNegativeNumber_Index (contains _)
-      a37 (the name is not descriptive and does not clearly provide the purpose of the variable)
-      fullName23, fullName24, etc. (it is not appropriate for a variable name to contain digits unless this improves the clarity of the variable used; if you need to have multiple variables with similar names ending in a different number, storing the same or similar type of data, it may be more appropriate to create a single collection or array variable and name it fullNamesList, for example).
Variables should have names, which briefly explain their purpose. When a variable is named with an inappropriate name, it makes the program very difficult to read and modify later (after a while, when we have forgotten how it works). For further explanation on the proper naming of variables refer to chapter "High-Quality Programming Code".
idi_exc
Always try to use short and precise names when naming the variables. Follow the rule that the variable name should state what it is used for, e.g. the name should answer the question "what value is stored in this variable". When this condition is not fulfilled then try to find a better name. Digits are not appropriate to be used in variable names.

Declaring Variables

When you declare a variable, you perform the following steps:
-      specify its type (such as int);
-      specify its name (identifier, such as age);
-      optionally specify initial value (such as 25) but this is not obligatory.
The syntax for declaring variables in C# is as follows:
<data type> <identifier> [= <initialization>];
Here is an example of declaring variables:
string name;
int age;

Assigning a Value

Assigning a value to a variable is the act of providing a value that must be stored in the variable. This operation is performed by the assignment operator "=". On the left side of the operator we put the variable name and on the right side – its new value.
Here is an example of assigning values to variables:
name = "John Smith";
age = 25;

Initialization of Variables

The word initialization in programming means specifying an initial value. When setting value to variables at the time of their declaration we actually initialize them.

Default Variable Values

Each data type in C# has a default value (default initialization) which is used when there is no explicitly set value for a given variable. We can use the following table to see the default values of the types, which we already got familiar with:
Data Type
Default Value

Data Type
Default Value
sbyte
0
float
0.0f
byte
0
double
0.0d
short
0
decimal
0.0m
ushort
0
bool
false
int
0
char
'\u0000'
uint
0u
string
null
long
0L
object
null
ulong
0u


Let’s summarize how to declare variables, initialize them and assign values to them with the following example:

// Declare and initialize some variables
byte centuries = 20;
ushort years = 2000;
decimal decimalPI = 3.141592653589793238m;
bool isEmpty = true;
char ch = 'a';
string firstName = "John";

ch = (char)5;
char secondChar;

// Here we use an already initialized variable and reassign it
secondChar = ch;

Value and Reference Types



Data types in C# are two types: value and reference.
Value types are stored in the program execution stack and directly contain their value. Value types are the primitive numeric types, the character type and the Boolean type: sbyte, byte, short, ushort, int, long, ulong, float, double, decimal, char, bool. The memory allocated for them is released when the program exits their range, i.e. when the block of code in which they are defined completes its execution. For example, a variable declared in the method Main() of the program is stored in the stack until the program completes execution of this method, i.e. until it finishes (C# programs terminate after fully executing the Main() method).
Reference types keep a reference (address), in the program execution stack, and that reference points to the dynamic memory (heap), where their value is stored. The reference is a pointer (address of the memory cell) indicating the actual location of the value in the heap. An example of a value at address in the stack for execution is 0x00AD4934. The reference has a type. The reference can only point to objects of the same type, i.e. it is a strongly typed pointer. All reference types can hold a null value. This is a special service value, which means that there is no value.
Reference types allocate dynamic memory for their creation. They also release some dynamic memory for a memory cleaning (garbage collector), when it is no longer used by the program. It is unknown exactly when a given reference variable will be released of the garbage collector as this depends on the memory load and other factors. Since the allocation and release of memory is a slow operation, it can be said that the reference types are slower than the value ones.
As reference data types are allocated and released dynamically during program execution, their size might not be known in advance. For example, a variable of type string can contain text data which varies in length. Actually the string text value is stored in the dynamic memory and can occupy a different volume (count of bytes) while the string variable stores the address of the text value.
Reference types are all classes, arrays and interfaces such as the types: object, string, byte[]. We will learn about classes, objects, strings, arrays and interfaces in the next chapters of this book. For now, it is enough to know that all types, which are not value, are reference and their values are stored in the heap (the dynamically allocated memory).

Value and Reference Types and the Memory

In this example we will illustrate how value and reference types are represented in memory. Consider the execution of the following programming code:
int i = 42;
char ch = 'A';
bool result = true;
object obj = 42;
string str = "Hello";
byte[] bytes = { 1, 2, 3 };
At this point the variables are located in the memory as follows:

If we now execute the following code, which changes the values of the variables, we will see what happens to the memory when changing the value and reference types:
i = 0;
ch = 'B';
result = false;
obj = null;
str = "Bye";
bytes[1] = 0;
After these changes the variables and their values are located in the memory as follows:

As you can see from the figure, a change in a value type (i = 0) changes its value directly into the stack. When changing a reference type, things are different: the value is changed in the heap (bytes[1] = 0). The variable that keeps the array reference remains unchanged (0x00190D11). When assigning a null value in a reference type, that reference is disconnected from its value and the variable remains with no value (obj = null).
When assigning new value to an object (a reference type variable) the new object is allocated in the heap (the dynamic memory) while the old object remains free (unreferenced). The reference is redirected to the new object (str = "Bye") while the old objects ("Hello") will be cleaned at some moment by the garbage collector (the .NET Framework’s internal system for automatic memory cleaning) as they are not in use anymore.

Literals


Primitive types, which we already met, are special data types built into the C# language. Their values specified in the source code of the program are called literals. One example will make this clearer:

bool result = true;
char capitalC = 'C';
byte b = 100;
short s = 20000;
int i = 300000;
In the above example, literals are true, 'C', 100, 20000 and 300000. They are variable values set directly in the source code of the program.

Types of Literals

In C# language, there are several types of literals:
-      Boolean
-      Integer
-      Real
-      Character
-      String
-      Object literal null

Boolean Literals

Boolean literals are:
-      true
-      false
When we assign a value to a variable of type bool we can use only one of these two values or a Boolean expression (which is calculated to true or false).

Boolean Literals – Example

Here is an example of a declaration of a variable of type bool and assigning a value, which represents the Boolean literal true:
bool result = true;

Integer Literals

Integer literals are sequences of digits, a sign (+, -), suffixes and prefixes. Using prefixes we can present integers in the program source in decimal or hexadecimal format. More information about the different numeral systems we can find in the chapter "Numeral Systems". In the integer literals the following prefixes and suffixes may take part:
-      "0x" and "0X" as prefix indicates hexadecimal values, for example 0xA8F1;
-      'l' and 'L' as suffix indicates long type data, for example 357L.
-      'u' and 'U' as suffix indicates uint or ulong data type, for example 112u.
By default (if no suffix is used) the integer literals are of type int.

Integer Literals – Examples

Here are some examples of using integer literals:
// The following variables are initialized with the same value
int numberInDec = 16;
int numberInHex = 0x10;

// This will cause an error, because the value 234L is not int
int longInt = 234L;

Real Literals

Real literals are a sequence of digits, a sign (+, -), suffixes and the decimal point character. We use them for values of type float, double and decimal. Real literals can be represented in exponential format. They also use the following indications:
-      'f' and 'F' as suffixes mean data of type float;
-      'd' and 'D' as suffixes mean data of type double;
-      'm' and 'm' as suffixes mean data of type decimal;
-      'e' is an exponent, for example, "e-5" means the integer part multiplied by 10-5.
By default (if there is no suffix), the real numbers are of type double.

Real Literals – Examples

Here are some examples of real literals' usage:
// The following is the correct way of assigning a value:
float realNumber = 12.5f;

// This is the same value in exponential format:
realNumber = 1.25e+1f;

// The following causes an error, because 12.5 is double
float realNumber = 12.5;

Character Literals

Character literals are single characters enclosed in apostrophes (single quotes). We use them to set the values of type char. The value of a character literal can be:
-      a character, for example 'A';
-      a character code, for example '\u0065';
-      an escaping sequence;

Escaping Sequences

Sometimes it is necessary to work with characters that are not displayed on the keyboard or with characters that have special meanings, such as the “new line” character. They cannot be represented directly in the source code of the program and in order to use them we need special techniques, which we will discuss now.
Escaping sequences are literals. They are a sequence of special characters, which describe a character that cannot be written directly in the source code. This is, for instance, the “new line” character.
There are many examples of characters that cannot be represented directly in the source code: a double quotation mark, tab, new line, backslash and others. Here are some of the most frequently used escaping sequences:
-      \' – single quote
-      \" – double quotes
-      \\ – backslash
-      \n – new line
-      \t – offset (tab)
-      \uXXXX – char specified by its Unicode number, for example \u03A7.
The character \ (backslash) is also called an escaping character because it allows the display on screen (or other output device) of characters that have special meaning or effect and cannot be represented directly in the source code.

Escaping Sequences – Examples

Here are some examples of character literals:
// An ordinary character
char character = 'a';
Console.WriteLine(character);

// Unicode character code in a hexadecimal format
character = '\u003A';
Console.WriteLine(character);

// Assigning the single quotiation character (escaped as \')
character = '\'';
Console.WriteLine(character);

// Assigning the backslash character (escaped as \\)
character = '\\';
Console.WriteLine(character);

// Console output:
// a
// :
// '
// \

String Literals

String literals are used for data of type string. They are a sequence of characters enclosed in double quotation marks.
All the escaping rules for the char type discussed above are also valid for string literals.
Strings can be preceded by the @ character that specifies a quoted string (verbatim string). In quoted strings the rules for escaping are not valid, i.e. the character \ means \ and is not an escaping character. Only one character needs to be escaped in the quoted strings – the character " (double-quotes) and it is escaped in the following way – by repeating it "" (double double-quotes). All other characters are treated literally, even the new line. Quoted strings are often used for the file system paths naming.

String Literals – Examples

Here are few examples for string literals usage:
string quotation = "\"Hello, Jude\", he said.";
Console.WriteLine(quotation);
string path = "C:\\Windows\\Notepad.exe";
Console.WriteLine(path);
string verbatim = @"The \ is not escaped as \\.
I am at a new line.";
Console.WriteLine(verbatim);
// Console output:
// "Hello, Jude", he said.
// C:\Windows\Notepad.exe
// The \ is not escaped as \\.
// I am at a new line.
More about strings we will find in the chapter "Strings and Text Processing".