CSIS 111B: Fundamentals of Computer Programming: Lessons

Lesson 5

Objectives

By the end of this lesson you will be able to:

• Understand what a variable is and how it is used in computer programming
• Understand what a constants isand how to use it in computer programming
• Understand how data types determine size requirements for storing data in memory
• Describe the various data types
• Declare and initialize storage structures for storing values in memory
• Write code, using the name/identifier of the storage location, which reads from and writes to these storage structures
• Understand usage of regular expressions in coding patterns
• Understand usage of special characters in coding patterns
• Understand string interpolation and how to use it in your code

Introduction to Values, Data Types, Variables, and Constants

In this lesson you will learn how to declare and initialize storage structures for storing values in computer memory. You can read and write to these structures by referring to the memory location in your code using the name/identifier of the storage location where the value is stored. One of the most common procedures you will do as a computer programmer is to insert references in your code by using the name of a memory location instead of hard coding the value into the program's code. This makes your code more flexible in that different values can be used without changing the program's code.

Computer's determine how much space to reserve in memory for storing values based on the type of value that is being stored. Meaning the data type that is created will have reserved for it a pre-determined number of bits in memory, based on the number of bits that type of data needs. For instance an integer like the number nine can be represented in memory using only 4 bytes, which you might know is 4 X 8 bits or 32 bits.

A single letter typed from a keyboard (known as a character or char) only required 8 bits in the original microcomputers. At that time microcomputer character encoding schemes were based on a translation table known as "ASCII" (pronounced ass-key). Nowadays microcomputers use 16 bits (or 2 bytes) to represent the Unicode character encoding set. It wouldn't make sense to reserve 32 bits of computer memory just for storing characters typed from the keyboard, that would be wasting 16 bits of memory every time a char needed to be stored in memory.

Visual Studio Solution For Tutorial 5

Values

A value is a discrete quantity of data. The members of a type are the values of that type. Computer languages vary in their implementation of primitive value types, but some examples would be null, undefined, true/false, and numeric values, like the following: 1, 3.1459, "Chuck", 'D', true.

Data Types

A data type or simply type is a classification of data which tells the compiler or interpreter how the programmer intends to use the data. Data types specify the type of data that you work with in a program. The data type defines the size of memory needed to store data and the kinds of operations that can be performed on the data. Most computer programming languages support various types of data, for example: real, integer, string, or boolean. A data type provides a set of values from which an expression (i.e. variable, function...) may take its values. The type defines the operations that can be done on the data, the meaning of the data, and the way values of that type can be stored. Data types are grouped into value types and reference types. Value data types store the value on the stack, whereas reference data types write the memory address on the stack which points to where the data value begins in dynamic memory (the heap).

Modern-day programming languages have basic data types built-in to them; these are generally referred to as their primitive data types. Meaning, the programmer does not have to write the code that defines the data type, its allowed operations, etc. Usually a simple statement like:

`            int myVariable;`

is all that is needed to declare an integer variable to the compiler or interpreter using any modern-day programming language.

Data Types By Programming Language

Click on the links below to view the specific data types for the designated programming language.

C++ Fundamental Types

C++ Fundamental Types (official documentation)

Data types in C++ are mainly divided into two types:

Primitive Data Types: These data types are built-in or predefined data types and can be used directly by the user to declare variables. example: int, char , float, bool etc. Primitive data types available in C++ are:

• Integer
• Character
• Boolean
• Floating Point
• Double Floating Point
• Valueless or Void
• Wide Character

Abstract or user defined data type: These data types are defined by user itself. Like, defining a class in C++ or a structure.

JavaScript Built-In Data Types

JavaScript Built-In Data Types (official documentation)

In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 6 primitive data types: string, number, boolean, null, undefined, symbol (new in ECMAScript 2015).

Most of the time, a primitive value is represented directly at the lowest level of the language implementation.

All primitives are immutable, i.e., they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.

Java Data Types

Java Data Types (official documentation)

The Java programming language supports the following primitive data types.

• byte
• short
• int
• long
• float
• double
• boolean
• char

Notice that the Java primitive data tyes all begin with a lowecase character. This format indicates that the data type is a primitive type, meaning that it defines the size that will be reserved in memory for that data type, but it has no associated methods. Java also has data type objects which in addition to defining the size of the data type they also have associated methods which allow for manipulation of the data type. Java object data type names are the same as the primitive type names except that they begin with a capital letter, e.g. Byte, Int, Double, etc.

Python Built-In Types

Python Built-In Types (official documentation)

Python has four primitive data types:

• Integers
• Float
• Strings
• Boolean

C# Data Types

C# Data Types (official documentation)

C# provides several built-in data types by way of the .NET framework which can be used in your programs. You can also define new data types by defining your own data structure, such as a `class` or a `struct`.

In this lesson we focus on some of the most commonly used data types.

Figure 2: C# Data Types
Data Type Size Range Of Values
byte 1 byte 0 to 255
char 2 bytes U+0000 to U+ffff (Unicode characters)
short 2 bytes -32,768 to 32,767
int 4 bytes -2,147,483,648 to 2,147,483,647
long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
float 4 bytes ±1.5 X 10-45 to ±3.4 X 1038
double 8 bytes ±5.0e-324 to ±1.7e308
bool 2 bytes True or False
string - zero or more unicode characters

All of the data types in the table above are value types except for `string`, which is a reference type. The variables which are based on value types directly contain the value on the stack. Data types which are of type reference store a reference on the `stack` which points to a memory address on the `heap` where the value is actually stored. This will make more sense after you learn about `arrays`, `stacks`, `heaps`, and other data structures later on in this course. For now, just remember that the `string` type is a reference type and NOT a value type.

The MSDN Web site has a more comprehensive table showing the C# integral data types. which is a subset of the simple types. You might also want to review Types for a more comprehensive overview of C# types.

Variables

Variables are a way of creating a temporary area of storage in computer memory for storing data while a program is running. Variables are named storage locations that hold values. We can then retrieve the value stored in memory by using the name (a.k.a. identifier) we assign to it when declaring the variable. Think of a variable as a placeholder or a box of a specific size which we can write a name on to help us to recall the data programmatically at a later time. For instance let's declare a variable named age and then later we'll store a value in it.

To do this we must follow the C# required format, `data-type name;` like this:

int age;

In the C# language we are required to include one of the C# data types provided by the .NET framework to let the compiler know what kind of value it should expect when we assign a value to it. The data type also determines what kinds of operations can be performed on it. In our example we used int which represents a 32-bit value which can only be a whole number, either positive or negative. By informing the compiler that our variable will be used to store a 32-bit integer value, the compiler now knows how many bits of space it needs to reserve in memory for holding the value when we assign data to it. You can determine a C# variable's data type like this `variable_name.GetType();`

Should we forget and try to assign text as a value for our variable or another numeric data type like a float data type, say 23.5, the compiler will let us know that this is not allowed while we are writing our program instead of us finding out the hard way, later on after the program has been compiled and being run by our customer. This saves a lot of time and money.

For more information on the data types available for use in the C# language, read the section titled Data Types.

You can also initialize our variable (assign a value to it) at the same time we declare it by adding the C# assignment operator (=) followed by a value, like this:

Notice how asignment goes from right to left. Whether you are initializing a variable or just modifying its current value, assignments always go from right to left. Once our variable is declared or initialized, we can change the value of our variable at any time by simply writing an assignment statement using the name of the variable, the assignment operator, and a new value, like this:

```    //variable = expression
age = 45;```

Beginning in Visual C# 3.0, variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type. The following two declarations of i are functionally equivalent:

```        var i = 10; //implicitly typed
int i = 10; //explicitly typed ```

Python is a dynamically typed language like JavaScript in that the interpreter infers the data type at run-time based on the value assigned to the variable. For instance, `age = 20` would give the inference that age is an int. However, if we declare age like this `age = "20"` then the inference is that age should be a string type. You can test this in Python using the type() function, like this: `type(variable_name)`.

In JavaScript the keyword `var` is used to dynamically declare a variable's data type, for example: `var age = 20;`. When the `var` keyword is not used in the declaration of a JavaScript variable, the variable is considered global in scope even if the declaration appears inside of a structure like a `for` loop.

Constants

Constants are immutable values which are known at compile time and do not change for the life of the program. Constants are declared with the `const` modifier. Only the C# built-in types (excluding `System.Object`) may be declared as `const`. Example:

`    const int i = 20;`

In this example a constant named i is declared which stores an integer data type of the value 20. Once declared the value of the `const` cannot be changed.

Python and JavaScript do not have the concept of a constant, instead global variables in which values cannot be changed are used instead.

Bool

Boolean data types stores one of two possible values, false or true (0 or 1 in binary). However, bools can be used to represent any diametrically opposed values like up or down, left or right, in or out, on or off, etc. The default value of a bool variable is false

```    public class BoolTest
{
static void Main()
{
bool b = true;

// WriteLine automatically converts the value of b to text.
Console.WriteLine(b);

int days = DateTime.Now.DayOfYear;

// Assign the result of a boolean expression to b.
b = (days % 2 == 0);

// Branch depending on whether b is true or false.
if (b)
{
Console.WriteLine("days is an even number");
}
else
{
Console.WriteLine("days is an odd number");
}
}
}
/* Output:
True
days is an (even/odd) number
*/```

In this example, you enter a character from the keyboard and the program checks if the input character is a letter. If it is a letter, it checks if it is lowercase or uppercase. These checks are performed with the IsLetter, and IsLower, both of which return the bool type:

```    public class BoolKeyTest
{
static void Main()
{
Console.Write("Enter a character: ");
if (Char.IsLetter(c))
{
if (Char.IsLower(c))
{
Console.WriteLine("The character is lowercase.");
}
else
{
Console.WriteLine("The character is uppercase.");
}
}
else
{
Console.WriteLine("Not an alphabetic character.");
}
}
}
/* Sample Output:
Enter a character: X
The character is uppercase.

Enter a character: x
The character is lowercase.

Enter a character: 2
The character is not an alphabetic character.
*/```

Byte

The Byte data type is used to represent an 8-bit unsigned integer. Byte is an immutable value type that represents unsigned integers with values that range from 0 (which is represented by the Byte.MinValue constant) to 255 (which is represented by the Byte.MaxValue constant). The .NET Framework also includes a signed 8-bit integer value type, SByte, which represents values that range from -128 to 127.

```    byte value1 = 64;
byte value2 = 255;```

In this example two bytes named value1 and value2 are initialized with the integer values of 64 and 255 respectively.

To format a Byte value as an integral string with no leading zeros, you can call the parameterless `ToString()` method. By using the "D" format specifier, you can also include a specified number of leading zeros in the string representation. By using the "X" format specifier, you can represent a Byte value as a hexadecimal string. The following example formats the elements in an array of Byte values in these three ways.

```    byte[] numbers = { 0, 16, 104, 213 };
foreach (byte number in numbers) {
// Display value using default formatting.
Console.Write("{0,-3}  -->   ", number.ToString());
// Display value with 3 digits and leading zeros.
Console.Write(number.ToString("D3") + "   ");
Console.Write(number.ToString("X2") + "   ");
// Display value with four hexadecimal digits.
Console.WriteLine(number.ToString("X4"));
}
// The example displays the following output:
//       0    -->   000   00   0000
//       16   -->   016   10   0010
//       104  -->   104   68   0068
//       213  -->   213   D5   00D5```

You can also format a Byte value as a binary, octal, decimal, or hexadecimal string by calling the `ToString(Byte, Int32)` method and supplying the base as the method's second parameter. The following example calls this method to display the binary, octal, and hexadecimal representations of an array of byte values.

```    byte[] numbers ={ 0, 16, 104, 213 };
Console.WriteLine("{0}   {1,8}   {2,5}   {3,5}",
"Value", "Binary", "Octal", "Hex");
foreach (byte number in numbers) {
Console.WriteLine("{0,5}   {1,8}   {2,5}   {3,5}",
number, Convert.ToString(number, 2),
Convert.ToString(number, 8),
Convert.ToString(number, 16));
}
// The example displays the following output:
//       Value     Binary   Octal     Hex
//           0          0       0       0
//          16      10000      20      10
//         104    1101000     150      68
//         213   11010101     325      d5```

Int

Int or Int32 (specific to C#) is an immutable value type that represents signed integers with values that range from negative 2,147,483,648 (which is represented by the Int32.MinValue constant) through positive 2,147,483,647 (which is represented by the Int32.MaxValue constant. The .NET Framework also includes an unsigned 32-bit integer value type, UInt32, which represents values that range from 0 to 4,294,967,295.

You can declare an Int32 variable and assign it a literal integer value that is within the range of the Int32 data type. The following example declares two Int32 variables and assigns them values in this way.

```    int number1 = 64301;
int number2 = 25548612;```

You can assign the value of an integer type whose range is a subset of the Int32 type. This is a widening conversion that does not require a cast operator in C#.

```    sbyte value1 = 124;
short value2 = 1618;

int number1 = value1;
int number2 = value2;```

You can call a method of the Convert class to convert any supported type to an Int32 value. This is possible because Int32 supports the IConvertible interface. The following example illustrates the conversion of an array of Decimal values to Int32 values.

```    decimal[] values= { Decimal.MinValue, -1034.23m, -12m, 0m, 147m,
199.55m, 9214.16m, Decimal.MaxValue };
int result;

foreach (decimal value in values)
{
try {
result = Convert.ToInt32(value);
Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.",
value.GetType().Name, value,
result.GetType().Name, result);
}
catch (OverflowException) {
Console.WriteLine("{0} is outside the range of the Int32 type.",
value);
}
}
// The example displays the following output:
//    -79228162514264337593543950335 is outside the range of the Int32 type.
//    Converted the Decimal value '-1034.23' to the Int32 value -1034.
//    Converted the Decimal value '-12' to the Int32 value -12.
//    Converted the Decimal value '0' to the Int32 value 0.
//    Converted the Decimal value '147' to the Int32 value 147.
//    Converted the Decimal value '199.55' to the Int32 value 200.
//    Converted the Decimal value '9214.16' to the Int32 value 9214.
//    79228162514264337593543950335 is outside the range of the Int32 type.
```

You can call the Parse or TryParse method to convert the string representation of an Int32 value to an Int32. The string can contain either decimal or hexadecimal digits. The following example illustrates the parse operation by using both a decimal and a hexadecimal string.

```    string string1 = "244681";
try {
int number1 = Int32.Parse(string1);
Console.WriteLine(number1);
}
catch (OverflowException) {
Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string1);
}
catch (FormatException) {
Console.WriteLine("The format of '{0}' is invalid.", string1);
}

string string2 = "F9A3C";
try {
int number2 = Int32.Parse(string2,
System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(number2);
}
catch (OverflowException) {
Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string2);
}
catch (FormatException) {
Console.WriteLine("The format of '{0}' is invalid.", string2);
}
// The example displays the following output:
//       244681
//       1022524
```

The Int32 type provides full support for standard and custom numeric format strings. (For more information, see Formatting Types, Standard Numeric Format Strings, and Custom Numeric Format Strings.) To format an Int32 value as an integral string with no leading zeros, you can call the parameterless ToString() method. By using the "D" format specifier, you can also include a specified number of leading zeros in the string representation. By using the "N" format specifier, you can include group separators and specify the number of decimal digits to appear in the string representation of the number. By using the "X" format specifier, you can represent an Int32 value as a hexadecimal string. The following example formats the elements in an array of Int32 values in these four ways.

```    int[] numbers = { -1403, 0, 169, 1483104 };
foreach (int number in numbers) {
// Display value using default formatting.
Console.Write("{0,-8}  -->   ", number.ToString());
// Display value with 3 digits and leading zeros.
Console.Write("{0,11:D3}", number);
// Display value with 1 decimal digit.
Console.Write("{0,13:N1}", number);
Console.Write("{0,12:X2}", number);
// Display value with eight hexadecimal digits.
Console.WriteLine("{0,14:X8}", number);
}
// The example displays the following output:
//    -1403     -->         -1403     -1,403.0    FFFFFA85      FFFFFA85
//    0         -->           000          0.0          00      00000000
//    169       -->           169        169.0          A9      000000A9
//    1483104   -->       1483104  1,483,104.0      16A160      0016A160
```

Float

The floating-point types are a subset of the simple types and can be initialized with literals. All floating-point types are also value types. All floating-point numeric types support arithmetic, comparison, and equality operators.

A floating-point expression can contain the following sets of values:

• Positive and negative zero
• Positive and negative infinity
• Not-a-Number value (NaN)
• The finite set of nonzero values

For more information about these values, see IEEE Standard for Binary Floating-Point Arithmetic, available on the IEEE website.

float data type uses four bytes to store numberic values which contain decimal places.

Real literals

The type of a real literal is determined by its suffix as follows:

1. The literal without suffix or with the d or D suffix is of type double
2. The literal with the f or F suffix is of type float
3. The literal with the m or M suffix is of type decimal

The following code demonstrates an example of each:

```    double d = 3D;
d = 4d;
d = 3.934_001;

float f = 3_000.5F;
f = 5.4f;

decimal myMoney = 3_000.5m;
myMoney = 400.75M;```

The preceding example also shows the use of _ as a digit separator, which is supported starting with C# 7.0. You can use the digit separator with all kinds of numeric literals.

You also can use scientific notation, that is, specify an exponent part of a real literal, as the following example shows:

```    double d = 0.42e2;
Console.WriteLine(d);  // output 42;

float f = 134.45E-2f;
Console.WriteLine(f);  // output: 1.3445

decimal m = 1.5E6m;
Console.WriteLine(m);  // output: 1500000```

Doubles

The Double value type represents a double-precision 64-bit number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, PositiveInfinity, NegativeInfinity, and not a number (NaN). It is intended to represent values that are extremely large (such as distances between planets or galaxies) or extremely small (the molecular mass of a substance in kilograms) and that often are imprecise (such as the distance from earth to another solar system), The Double type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.

Char

The char data type

```    var chars = new char[4];

chars[0] = 'X';        // Character literal
chars[2] = (char)88;   // Cast from integral type
chars[3] = '\u0058';   // Unicode

Console.Write(string.Join(" ", chars));
// Output: X X X X ```

Escaping and Casting Values

As you can see above the literal values being assigned to chars[1] and chars[3] use a special programming technique known as an escape sequence. Escape sequences can be used in many ways with chars and strings. In order to escape a character you type to type a backslash character before the character you want escaped. In the case of chars[1] the value being escaped is a hexadecimal value - hex is indicated using a lower-case 'x'. In the chars[3] example the value is a unicode value as designated by prefixing the value with a 'u'.

The literal value being assigned to chars[2] uses a programming technique known as casting. Casting, placing a data type name in parenthesis before the literal value to be assigned, converts the value to the data type identified in the parenthesis.

Here are a few more char examples:

```    // An ordinary character
char character = 'a';
Console.WriteLine(character);

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

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

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

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

Strings

In computer programming, a string data type is a data type which contains an array of char (character) data types.

Using Strings In JavaScript

Watch this video to learn about strings and string manipulation.

String Properties

The string type in C# has two properties:

Chars[index]
Gets the Char object at a specified position in the current String object.
Length
The number of characters in the current string.

String Methods

The string type in C# has numerous methods: Clone, Compare, CompareOrdinal, CompareTo, Concat, Contains, Copy, CopyTo, Create, EndsWith, EnumerateRunes, Equals, Format, GetEnumerator, GetHashCode, GetTypeCode, IndexOf, IdexOfAny, Insert, Intern, IsInterned, IsNormalized, IsNull Or Empty, IsNullOrWhiteSpace, Join, LastIndexOf, LastIndexOfAny, Normalize, PadLeft, PadRight, Remove, Replace, Split, StartsWith, Substring, ThCharArray, ToLower, ToLowerInvariant, ToString, ToUpper, ToUpperInvariant, Trim, TrimEnd, and TrimStart (as of .NET Framework 4.8).

String Code Example

C#

Here is how the code in our `Program.cs` file will look. Place the code inside the Main() method and run it.

```        string x, y, z;

Console.Write("Enter x: ");
Console.Write("Enter y: ");
Console.Write("Enter z: ");

Console.WriteLine(\$"x={x}, y={y}, z={z}");```

Code Dissected

More fun with string algorithms.

Operators

You have already seen a couple of C# operators in action (`=` and `new`). In this section we will discuss C# operators in more depth.

Operators are symbols that specify which operations (math, indexing, function call, etc.) to perform on the operands in an expression. Operands can be variables, constants, literals, etc. Operators can be organized by function or by number of operands it operates on. If we organize operators by function, each operator would  fall into one of three categories, 1) arithmetic, 2) boolean, or 3) relational. Examples of arithmetic operators include: +, -, *, /, and %. If we organize operators by the number of operands they operate on then the groupings would be: 1) unary operators, 2) binary operators, and 3) ternary operators.

Operators can be organized depending on the number of operands involved, like this:

Unary operators: The unary operators work with only one operand. Examples include ++x (prefix increment), x++ (postfix increment), or new.

Binary operators: Binary operators take two operands. Examples include x + y or x > y

Ternary operators: Ternary operators take three operands. There is just one ternary operator in C# ?:. Pseudo code example:

condition ? expression_if_true : expression_if_false;

Operators can also be organized by how they are used, like this:

Arithmetic operators can be used to create expressions like:

x = 1 + 1;

Conditional operators can be used to create expressions like:

if (x < 2)

Logical operators can be used to create expressions like:

if (x<2 && y == 3)

Often expressions involve more than one operator. In this case the compiler needs to determine which operator takes precedence over the other(s). Figure 3 lists the C# operators in order of precedence (pretty much the same in all computer programming languages). The higher an operator is located in the table, the higher the precedence. Operators with higher precedence are evaluated before operators with lower precedence. Operators that appear in the same row have equal precedence.

Figure 3: C# Operators
Category Operators
Primary x.y f(x) a[x] x++ x-- new
typeof checked unchecked
Unary + - ! ~ ++x --x (T)x
Multiplicative * / %
Shift << >>
Relational and type testing <> <= >= is as
Equality == != === !==
Logical AND &
Logical XOR ^
Logical OR |
Conditional AND &&
Conditional OR ||
Conditional ternary ?:
Assignment = *= /= %= += -= <<= >>= ^= |=

The unary increment operator (++) adds 1 to the value of the an identifier (variable). Similarly, the decrement (--) operator subtracts 1 from the value of the identifier. The unary increment and decrement operator can be used as prefixes or suffixes. For example:

```int x = 10;
x++; //value of x is now 11
++x; //value of x is now 12```

However, when used as part of an assignment the results can be unexpected. When the unary increment and decrement operators are used as prefixes (++x), the current value of the identifier is returned after (post) the increment or decrement operation. When used as a suffix (x++), the value of the identifier is returned before (pre) the increment decrement operation is complete. To better understand how this works let's look at another example:

```int x = 10;
int y = x++ //value of y is 10 (assigned pre-increment)
int z = ++x //value of z is 12 (assigned post-increment)```

In this example, because y is assigned the value of x pre-increment y's value is 10. However x is increment after the assignment to y so x's value is now 11. Then, z is assigned the value of x post-increment so both x and y now have the value of 12. Fun stuff, eh?

If this example boggles you brain, I encourage you to copy this console application code into Visual Studio and try it out for yourself:

```using System;

namespace IncrementDecrementOperators
{
class Program
{
static void Main(string[] args)
{
int x = 10;
int y = x++; //value of x is now 11
Console.WriteLine("x = " + x + ", y = " + y);
int z = ++x; //value of x is now 12
Console.WriteLine("x = " + x + ", z = " + z);
}
}
}```

Regular Expressions

As a programmer you will encounter the need for character pattern matching from time to time. For example creating an algorithm for finding and replacing groups of characters in a string, or validating user input for correctness. Regular Expressions are the programmer's tool for defining patterns used in matching operations. Although you won't be using regular expressions in this class, it is good to be familiar with them so that you can implement them when needed in your professional programming life. View this video to learn about regular expressions and how and where to use them.

Special Characters

In the C# language you can use the @ symbol as a verbatim identifier and the \$ sign character for string interpolation (starting with version 6). In the String Variables code example below you will use string interpolation when displaying the output and you will see the verbatim identifier which will be used later in Lesson 11 File I/O to assist with overriding the default nature of the backslash character to be treated as an escape character. Interpolated strings are replacements for the composite format strings supported by the .NET Framework.

The @ special character serves as a verbatim identifier. It can be used in the following ways:

1. To enable C# keywords to be used as identifiers. The @ character prefixes a code element that the compiler is to interpret as an identifier rather than a C# keyword. The following example uses the @ character to define an identifier named for that it uses in a for loop.
```    string[] @for = { "John", "James", "Joan", "Jamie" };
for (int ctr = 0; ctr < @for.Length; ctr++)
{
}
// The example displays the following output:
2. To indicate that a string literal is to be interpreted verbatim. The @ character in this instance defines a verbatim string literal. Simple escape sequences (such as "\\" for a backslash), hexadecimal escape sequences (such as "\x0041" for an uppercase A), and Unicode escape sequences (such as "\u0041" for an uppercase A) are interpreted literally. Only a quote escape sequence ("") is not interpreted literally; it produces a single quotation mark. Additionally, in case of a verbatim interpolated string brace escape sequences ({{ and }}) are not interpreted literally; they produce single brace characters. The following example defines two identical file paths, one by using a regular string literal and the other by using a verbatim string literal. This is one of the more common uses of verbatim string literals.
```    string filename1 = @"c:\documents\files\u0066.txt";
string filename2 = "c:\\documents\\files\\u0066.txt";

Console.WriteLine(filename1);
Console.WriteLine(filename2);
// The example displays the following output:
//     c:\documents\files\u0066.txt
//     c:\documents\files\u0066.txt```

String interpolation provides a more readable and convenient syntax to create formatted strings than a string composite formatting feature. The following example uses both features to produce the same output:

```    string name = "Mark";
var date = DateTime.Now;

// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine(\$"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Both calls produce the same output that is similar to:
// Hello, Mark! Today is Wednesday, it's 19:40 now. ```