Introduction to Variables

Introduction to Storage

A computer is an electronic device that is used to solve one specific problem or to perform an assignment. For example, a fitness machine allows a person to get in shape. A digital camera is used to take pictures. A cell phone is used to make phone calls. An ultrasound machine is a health care machine used to produce images from inside a human body. A music synthesizer can be used to create music:     An electronic device can also be used to solve general types of problems. A computer can also get its values from a combination of sources: To manage these different connections, a computer uses a motherboard. A computer uses a processor that is connected to a motherboard: The values a computer receives are stored in the computer memory. The computer uses two categories of storage (memory): temporary and permanent. The computer's temporary memory is used to hold information for a while and then lose it if that information is not needed anymore. For example, it can hold some values while the computer is turned on. If the computer gets turned off, the values stored in the temporary memory are lost. This is not an anomaly: that's the way it is designed (it would be catastrophic otherwise; try to imagine a computer that would keep everything; it would be filled in a short time and blow up :)).

The memory area where the computer temporarily stores some values is called random access memory or RAM: Let's illustrate memory as a small cake pan made of boxes or holes that can contain something: Altough it looks physically small, the RAM is huge, and your program is not the only one that uses the computer. For example, when the computer starts, it launches the operating system (OS). Other programs (and utilities) also occupy the RAM. When a program starts, the compiler reserves a certain area of memory: A variable is, or indicates, the amount of memory you want a value of your program to use.

Introduction to Numeric Representations

A computer program is a series of instructions that tell the computer what to do, when to do something, and how to do it. To understand the instructions it receives, the computer uses its own language (called the machine language) that uses a combination of 1s and 0s. Because that language is difficult to read (for us regular humans), the computer uses an intermediary language (or program) called an assembler that is closer to (or is in fact) English. The assembler transforms the instructions into a shorter version that uses new words but that are still in English.

The simplified language the computer understands uses a combination of 1s and 0s. This means that the assembler must bring your C# instructions to 1s and 0s. The combinations or sequences of 1s and 0s indicate what needs to be done.

Introduction to the Decimal System

We are familiar with the system that uses 10 digits as 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. A combination of these 10 digits can produce any number. Because this system uses 10 digits. It is named the decimal system.

Introduction to the Binary System

As mentioned already, the language of the computer is made of combinations of two values: 1 and 0. This is called the binary system (because it is based on two values only). Examples of numbers in the binary system, or binary numbers, are 1, 10, 1001, or 1010110111. When you submit a value to a computer, the value must be changed into a combination of 1s and 0s.

An alternative to represent a large number uses the 10 digits of the decimal system and uses the first 6 letters of the English alphabet: A, B, C, D, E, and F or a, b, c, d, e, and f. This means that this system uses a combination of 16 characters to create any number. For this reason, it is called the hexadecimal system. To differentiate a hexadecimal number from a word, the number must start with 0x. Examples are 0x2, or 0xED8, or 0x962AAED3.

Signed and Unsigned

One of the characteristics of a number is to indicate whether it is lower than 0, equal to 0, or higher than 0. A number that is lower than 0 is said to be negative. Such a number must be preceded by -. If a number is higher than 0, it is said to be positive. Such a number can be preceded by + or no sign. The ability for a number to hold a sign makes it possible to say that such a number is signed. It is important to know that, when a number is said to be signed, that number can be negative or positive.

Any number that uses neither - or + is said to be positive and, because it doesn't use a sign, it is said to be unsigned. Normally, the 0 number doesn't use a sign.

Variable Declaration

Representing Memory Bits

We mentioned that, to store a value in the computer memory, you must indicate how much memory you will need and you must give it a name. The amount of memory you need is referred to as a data type. As you can imagine, different values require different amounts of memory. We also mentioned that the computer considers a value as a combination of 1s and 0s. The area of memory that holds a single piece of 1 or 0 is called a bit.

Consider a bit like a small object (like a cup of a cup cake) that can be full or can be empty: When it is empty, a bit holds a value of 0. When it is full, it holds a value of 1: Different combinations of empty (0) and full (1) objects produce the necessary values.

Declaring a Variable

In previous lessons, in our introduction to variables, we saw that, to use a combination of bits, you let the compiler know that you want a variable, which is referred to as declaring a variable. The amount of memory you need is called a data type.

We already know that, to declare a variable, you can use a data type and a name for the variable, in a formula as follows:

`data-type variable-name;`

Remember (from previous lessons) that, when you are declaring a variable, you are not required to initialize it. Otherwise, if you know the initial value you want the variable to hold, you can declare it using the var keyword. In that case, you must initialize the variable.

Besides var, if you want to use a variable without specifying the explicit type for the value, you can declare it using the object type or the dynamic keyword.

Initializing a Variable

The Nullity of a Variable

When you declare a variable, you ask the compiler to reserve a certain area and amount of memory to eventually hold a value for that variable. A value is referred to as null when it cannot be clearly determined. A null value is not 0 because 0 is an actual value.

We already saw that the formula to declare a null variable is:

`data-type? variable-name;`

Assigning a Value to a Variable

Initializing a variable consists of storing an initial value in that reserved area. The technique you use is the same for all types but the type of value you want to store depends: you should not and must not try to store just any type of value.

When you declare a variable and initialize it, the compiler stores its value in the memory that was reserved for it.

• You can assign null when declaring the variable:
```@{
data-type? VariableName = null;
}```
• You can assign null after the variable has been declared:
```@{
data-type? VariableName;

variable-name = null;

// You can use the variable
. . .
}```

The rule is that you must assign the value before the variable can be used.

A Byte

A Combination of Four Bits

Although there are cases where you can use or access a bit, you cannot actually store a value in it. That is, you cannot ask the compiler to store the value 1 in a certain bit for you. This is because even the simplest value in C# needs more than one bit to store itself. Still, the minimum combination of bits you can be concerned with is four (in some languages, or in some implementations of the Assembly language, a combination of four bits is called a nibble).

By creating different combinations of empty (0) and full (1) objects grouped in four, you can get 16 combinations:    In a combination of four bits, the bits are counted as 0, 1, 2, and 3. The bit on the most right side is Bit 0 and it is called the low order bit (or LOBIT): The last bit, the bit on the most left side, is Bit 3 and it is called the high order bit (or HIBIT).

If you represent the four-combination bits in binary formats, you get 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111, which produces 16 combinations. In decimal format, these combinations produce 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, and 15. In hexadecimal format, these combinations produce 0x0 (0x0000), 0x1 (or 0x0001), 0x2 (or 0x0002), 0x3 (or 0x0003), 0x4 (or 0x0004), 0x5 (0x0005), 0x6 (0x0006), 0x7 (or 0x0007), 0x8 (or 0x0008), 0x9 (or 0x0009), 0xA (or 0xa), 0xB (or 0xb), 0xC (or 0xc), 0xD (or 0xd), 0xE (or 0xe), and 0xF (or 0xF).

As a result, we get a table as follows:

 Decimal Binary Hexadecimal 0 0000 0x0 1 0001 0x1 2 0010 0x2 3 0011 0x3 4 0100 0x4 5 0101 0x5 6 0110 0x6 7 0111 0x7 8 1000 0x8 9 1001 0x9 10 1010 0xA 11 1011 0xB 12 1100 0xC 13 1101 0xD 14 1110 0xE 15 1111 0xF

Table of Numeric Conversions

The minimum and maximum values in a combination of four bits are:

 Decimal Hexadecimal Binary Minimum 0 0x0 0000 Maximum 15 0xf 1111

You will never be concerned with combinations of four bits because you cannot store anything in it (these combinations are too small).

A Combination of 8 Bits

We presented them here for two reasons. First, you should be aware of such a thing as a combination of four bits so you will know where the number 16 comes from when you see it mentioned in different places. Second, it allowed us the introduce the byte.A byte is a combination of eight adjacent bits. The first bit, located on the most right side, is Bit 0. The last bit, on the most left side, is Bit 7: Bit 0 is called the least significant bit. It is also called the low order bit or LOBIT. Bit 7 is called the most significant bit. It is also called the high order bit or HIBIT.

If you create different combinations of empty (0) and full (1) objects grouped in eight, in binary formats, you get 00000000, 00000001, 00000010, 00000011, 00000100, 00000101, 00000110, 00000111, 00001000, 00001001, 00001010, 00001011, 00001100, 00001101, 00001110, 00001111, etc, up to 11111111. When a large number is represented in binary format, it can be difficult to read. An alternative is to create groups of four bits so that instead of writing 01001011, you would write 0100 1011.

To evaluate the number of combinations in decimal format, you use the number 2 that represents decimal, you elevate it to the power of the position of the bit (0, 1, 2, 3, 4, 5, 6, or 7), and you add the number. This can be done as follows:

```27 + 26 + 25 + 24 + 23 + 22 + 21 + 20
= 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1
= 255```

Therefore, we get 255 possible combinations of eight bits. The combinations can also be represented in hexadecimal format as 0x1, 0x2, ..., 0xA, 0xA1, ..., 0xC8, ..., up to 0xFFFF.

In the three numeric systems, we get:

 Decimal Hexadecimal Binary Minimum 0 0x0 0000 Maximum 255 0xff 1111 1111

The minimum storage area offered by most (the majority of) processors is the byte. As you know already, a byte is a group of 8 consecutive bits. The amount of memory space offered by a byte can be used to store just a single symbol, such as those you see on your keyboard. These symbols, also called characters, have been organized by the American Standard Code for Information Exchange (ASCII) in a list. But, ASCII uses only 128 decimal numbers (based on a 7-bit format) to represent symbols counted from 0 to 127. To compensate for the remaining 1 bit, IBM used it to organize special characters, foreign language characters, mathematical symbols, small graphics, etc. Each one of these characters has a decimal, a hexadecimal, and a binary equivalent.

The Byte Data Type

To let you declare a variable for a small number, the C# language provides a data type named byte. You can use it to declare a variable for a small number. Here is an example:

```@{
byte small;
byte other;
}```

A byte is an unsigned number whose value can range from 0 to 255. Therefore, when assigning a value to a byte variable, the value nust fit in only one byte. Here are examples:

```@{
// A Byte variable
byte small = 150;
// Another Byte variable
byte other = 250;
}```

When assigning a value to a byte variable, make sure the value is between 0 and 255. Instead of a decimal number, you can also initialize a byte variable with a hexadecimal value. The value must be between 0x00 and 0xFF (255). Here is an example:

```@{
var number = 0xFE;
}```

Signed Byte

A byte number is referred to as signed if it can hold a negative or a positive value that ranges from -128 to 127. To support signed-byte numbers, the C# language provides a data type named sbyte. You can use it to declare a variable that would hold small positive or negative numbers. Here is an example:

```@{
sbyte roomTemperature = -88;
}```

Introduction to the Characteristics of Data Types

Introduction

To assist you in creating and managing values for your applications, the .NET library provides various structures. There is a particular structure for each of the types of values we will study. All those structures were created in the System namespace.

As you will see, some of the names of the C# data type will be different from the equivalent .NET library structures. Nevertheless, each data type has some characteristics (such as the limits of a type). The characteristics of a type are controlled by its equivalent .NET library structure.

The Byte Data Type

To support small numbers that fit in 8 bits, the .NET library provides a structure named Byte. You can use it to declare a variable. A Byte data type primarily follows the same rules as the byte type.

Converting a Value to a String

In most cases, to display the value of a variable to a console, we already know that you can simply pass the name of the variable to the Write() or the WriteLine() method. Here is an example:

```@{
// A variable of the C# byte type
byte small = 150;
// A variable of the .NET Byte type
Byte other = 250;
}```

To display the value of a variable to a user, you may have to convert the variable to a string. To assist you with this, each structure of a data type is equipped with an overloaded method named ToString. The simplest version of this method doesn't take any argument. Its syntax is:

`public string ToString ();`

To use this version, call it on the variable. To let you control how a value should display, each structure of a data type is equipped with another version of the ToString() method whose syntax is:

`public string ToString (string? format);`

This version takes a string as argument. The argument uses a letter as follows:

 Use the Letter To Display the Value as C Currency E Exponent F Fixed G General N Natural P Percentage X Hexadecimal

The Minimum Value of a Type

Every data type has limits. Those limits specify the lowest and the highest value the variable of a type can hold. To provide the lowest value that a type can hold, each structure is equipped with a constant field named MinValue. For the byte type, this field is defined as follows:

`public const byte MinValue = 0;`

To know the lowest value of a type, you can access this field. Here is an example:

```@page
@model Exercises.Pages.ExerciseModel
@{
}

<pre>byte minimum: @byte.MinValue)
Byte minimum: @Byte.MinValue
==================</pre>```

This would produce:

```byte minimum: 0
Byte minimum: 0
==================```

The Maximum Value of a Type

Every data type has a highest value beyond which it is not valid. To provide that value, each structure is equipped with a constant field named MaxValue. For the byte type, this field is defined as follows:

`public const byte MaxValue = 255;`

To get the highest value of a type, access this field. Here is an example:

```@page
@model Exercises.Pages.ExerciseModel
@{
}

<pre>================================
byte minimum: @byte.MinValue
Byte minimum: @Byte.MinValue
--------------------------------
byte minimum: @byte.MaxValue
Byte minimum: @Byte.MaxValue
================================</pre>```

This would produce:

```================================
byte minimum: 0
Byte minimum: 0
--------------------------------
byte minimum: 255
Byte minimum: 255
================================```

Parsing a Value

As mentioned in previous lessons, the values that a user enters in an application are considered strings. If you want to involve a provided value to numeric expressions, you should first convert the value to the appropriate type. To assist you with that operation, each structure of a data type is equipped with an overloaded static method named Parse. One of the versions of this method uses the following syntax:

`public static byte Parse (string s);`

As we have been doing so far, to call this method, write the data type, a period, and Parse(). In the parentheses of the Parse() method, enter the value to convert.

Trying to Parse a String

Sometimes, the Parse() method fails. For example, if you don't provide any value (in which case the value would be considered null) or you provide a value that is in a bad format (such as "124;85"), the (above version of the) Parse() method is not equipped to convert such a value. As an alternative, each structure of a data type is equipped with an overloaded static method named TryParse. The most fundamental version of this method uses the following syntax:

`public static bool TryParse (string s, out byte result);`

This method takes two arguments. The first argument is the value to convert. It's the same type of value you would pass to a Parse() method. The second argument is passed by reference. Since this argument is passed as an out reference, first declare a variable and pass it as the second argument (we will see examples in other sections).

Converting a Value to a Byte

Once again, remember that when a user provides a value in an application, by default, that value is a string and cannot be directly used in a numeric operation. We have already seen that, to assist you with value conversion, the .NET library provides a static class named Convert:

`public static class Convert`

The Convert class is equipped with an overloaded method for each of the data types we will review. The methods associated with a data type are used to convert a value from a certain type to that type. Based on this, the method used to convert a value to a small number is named ToByte. Remember that the method is overloaded. The version used to convert a string to a byte uses the following syntax:

`public static byte ToByte (string value);`

The version used to convert any value to a byte uses the following syntax:

`public static byte ToByte (object value);`

In both cases, pass the desired value to the method.

The Size of a Data Type

The C# language provides a unary operator named sizeof. It allows you to find out how much space a data type uses. To find out how much memory space a data type uses, type it between the parentheses of the sizeof operator. Here is an example:

```@page
@model Exercises.Pages.ExerciseModel
@{
}

<pre>================================
The byte data type uses @sizeof(byte) byte.
================================</pre>```

This would produce:

```================================
The byte data type uses 1 byte.
================================```

A Word

Introduction

A group of 16 consecutive bits is called a word. The bits are counted from right to left starting at 0: Considered as a group of 16 bits, the most right bit of a word, bit 0, is called the least significant bit or low order bit or LO bit or LOBIT. The most left bit, bit 15, is called the most significant bit or high order bit or HI bit or HIBIT. The other bits are referred to using their positions: bit 1, bit 2, bit 3, etc.

Considering that a word is made of two bytes, the group of the right 8 bits is called the least significant byte or low order byte or LO byte or LOBYTE. The other group is called the most significant byte or high order byte or HI byte or HIBYTE.

The representation of a word in binary format is 0000000000000000. To make it easier to read, you can group bits by 4, like this: 0000 0000 0000 0000. Therefore, the minimum binary value represented by a word is 0000 0000 0000 0000. The minimum decimal value of a word is 0. The minimum hexadecimal value you can store in a word is 0x0000000000000000. This is also represented as 0x00000000, or 0x0000, or 0x0. All these numbers produce the same value, which is 0x0.

The maximum binary value represented by a word is 1111 1111 1111 1111. To find out the maximum decimal value of a word, you can use the base 2 formula, filling out each bit with 1:

1*215+1*214+1*213 + 1*212 + 1*211 + 1*210 + 1*29 + 1*28 + 1*27 + 1*26 + 1*25 + 1*24 + 1*23 + 1*22 + 1*21 + 1*20

= 32768 + 16384 + 8192 + 4096 + 2048 + 1024 + 512 + 256 + 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1

= 65535

To find out the maximum hexadecimal number you can store in a word, replace every group of 4 bits with an f or F:

1111 1111 1111 1111
f f f f
 = 0xffff = 0xFFFF = 0Xffff = 0XFFFF

Short Integers

A word, which is a group of 16 contiguous bits or 2 bytes, can be used to hold a natural number. As we have studied, the maximum numeric value that can fit in a word is 65535. To declare a variable for such a value, you can use the var keyword and initialize the variable with a value between -32768 et 32767. Here is an example:

```@page
@model Exercises.Pages.ExerciseModel
@{
var schoolEffective = 1400; // Number of Students
}

<pre>================================
School Effective: @schoolEffective
================================</pre>```

This would produce:

```================================
School Effective: 1400
================================```

Since the byte is used for characters and very small numbers, whenever you plan to use a number in your program, the minimum representation you should use is a word.

A natural number is also called an integer. To let you declare a variable that can hold an integer that can be stored in a word, the C# language provides a data type named short. A short integer is signed by default. Therefore, its variable can store a value that ranges from -32768 to 32767. Here is an example program that uses a short data type:

```@{
short numberOfPages = 842;
short temperature = -1544;
}

<pre>===========================================================
Number of Pages of the book: @numberOfPages
Temperature to reach during the experiment: @temperature degrees
===========================================================```

This would produce:

```===========================================================
Number of Pages of the book: 842
Temperature to reach during the experiment: -1544 degrees
===========================================================```

.NET Short Integers

To support short integers, the .NET library provides a structure named Int16. This structure is equipped with the exact same fields and properties we reviewed for the byte type. These include the minimum and maximum values. Here is an example of accessing them:

```@page
@model Exercises.Pages.ExerciseModel
@{
}

<pre>================================
Short integer minimum:  @short.MinValue
16-bit integer minimum: @Int16.MinValue
--------------------------------
Short integer maximum:  @short.MaxValue
16-bit integer maximum: @Int16.MaxValue
================================</pre>```

This would produce:

```================================
Short integer minimum:  -32768
16-bit integer minimum: -32768
--------------------------------
Short integer maximum:  32767
16-bit integer maximum: 32767
================================```

The Int16 structure is also equipped with the abilities to parse a variable. The Convert static class is also equipped with the methods necessary to convert a value to a short integer:

```public static short ToInt16 (string value);
public static short ToInt16 (object value);```

Unsigned Short Integers

If a variable must hold positive and relatively small numbers, it is referred as an unsigned short integer. To declare a variable for such a number, you can use a data type named ushort. You can alaos use the var keyword to declare the variable. An unsigned short integer can hold numbers that range from 0 to 65535 and therefore can fit in 16 bits. Here are examples:

```@{
// These variables must hold only positive integers
ushort numberOfTracks = 16;
ushort musicCategory = 2;
}

<pre>====================================
This music album contains @numberOfTracks tracks
------------------------------------
Music Category: @musicCategory
====================================</pre>```

This would produce:

```====================================
This music album contains 16 tracks
------------------------------------
Music Category: 2
====================================```

Unsafe Code

The C and C++ languages (the ancestors to C#) use pointers to refer to the area in memory where a value is located. C# highly avoids pointers and takes over memory management as opposed to letting the programmer take care of that aspect of an application. You can still use pointers in C# in extreme cases when you judge them necessary.

Because the C# compiler is in charge of managing the memory used by the values of an application, pointers are said to be unsafe. If you want to use a pointer in your application, you must precede the name of every method that uses unsafe code with the unsafe keyword.