Variables

Variables

A variable is a named memory location that is capable of holding data values of specific types e.g. a whole number such as your age, a whole number with a fractional part such as the amount of money in your bank account, a representation of a date such as your date of birth; this could be in a number of different formats, a logical value of true or false etc. Each one of these values is represented by a type. So your age could be represented by an integer, your bank balance could be represented by a float, your name by a sequence of characters called a string etc.

C# has numerous datatypes that can be used to represent data values (courtesy of https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/types ) - these are called the built-in types

Type

Family

Descriptoin

Type

Family

Descriptoin

sbyte

integral

Represents signed 8-bit integers with values between -128 and 127

byte

integral

Represents unsigned 8-bit integers with values between 0 and 255

short

integral

Represents signed 16-bit integers with values between -32768 and 32767

ushort

integral

Represents unsigned 16-bit integers with values between 0 and 65535

int

integral

Represents signed 32-bit integers with values between -2147483648 and 2147483647

uint

integral

Represents unsigned 32-bit integers with values between 0 and 4294967295

long

integral

Represents signed 64-bit integers with values between -9223372036854775808 and 9223372036854775807

ulong

integral

Represents unsigned 64-bit integers with values between 0 and 18446744073709551615

char

integral

Represents unsigned 16-bit integers with values between 0 and 65535. The set of possible values for the char type corresponds to the Unicode character set

Even though char is within the integral family it differs in two ways

  • there is no implicit conversion from the other integral types to char, forced coercion must be used

  • if you want to use an integer literal to represent a char it must be accompanied by the char cast operator e.g. 10 should be written as (char)10 to represent ‘\x000A’

float

floating

32-bit single precision IEEE 754 format. Represents values ranging from approximately 1.5 * 10^-45 to 3.4 * 10^38 with a precision of 7 digits

double

floating

64-bit double precision IEEE 754 format. Represents values ranging from approximately 5.0 * 10^-324 to 1.7 × 10^308 with a precision of 15-16 digits

bool

boolean

Represents boolean logical quantities. The possible values of type bool are true and false

decimal

decimal

 Represent values ranging from 1.0 * 10^-28 to approximately 7.9 * 10^28 with 28-29 significant digits. It is a 128-bit data type suitable for financial and monetary calculations.

Declaring Variables

In this example, x is declared and C# initialises it to a default value of 0. X is then assigned a value of 4. But the declaration of y is different, this is known as a declaration with initialisation, in this case, it is initialised with the value of 3.

The variables x and y are more commonly termed “local variables”. Local meaning they are scoped to the enclosing method; in this case, Main(). We will discuss methods in more detail in a later section.

The type of a variable is immutable. It is fixed at the time of declaration. So an int variable will always be an int variable.

As shown in the diagram above, all variables of the built-in (atomic) types are declared this way. So the general form is

Declaration

<atomic type> <variable name>;

Declaration with initialisation

<atomic type> <variable> = <some value matching the domain of the atomic type>;

It’s important to note the rhand value must be of a data range that matches the domain of possible values for the lhand type. For example, using the table above we see that a variable of type byte can only hold values within the range 0 .. 255. So what would happen if we assigned a value of greater than 255?

Notice that the 256 is underscored in red. This is VS telling us there is an issue. If we build this piece of code we gain more insight into the error

The value of 256 cannot be converted to a byte. In visual studio, if you hover your mouse over the offending item, VS will give you more details as to what the error is

Constants have default sizes (the rhand is a constant) - the maximum number of bits that are required to represent the largest and smallest value of that type. In this example, 256 in binary would require 16 bits, therefore 256 cannot be stored in a variable of type byte because it is only 8 bits in size.

Good programming practice

Determining the correct data types that your program needs, requires you to understand as well as is possible the problem you are trying to solve. Getting data types wrong is not an end of the world experience, but as your codebase grows, it can trigger significantly more effort than is wanted during refactoring.

Constants

The values held within a variable may change unless the variable is declared as const as shown here. We call such a variable a constant variable or just constant for short.

const int x = 3;

Any attempt to perform an assignment operation on x will result in an error

The above line of code will result in the error CS0131: The left-had of an assignment must be a variable. C# is telling you that x is not a variable (its values can not vary), it is in actual fact a constant (a named memory location whose contents can not be changed).

The const keyword is typically called a type modifier.

Good programming practice

Typically we use const to create named values. For example, rather than littering your code 3.14159 (the value of PI) we would declare the constant PI

const float PI = 3.14159

This allows us the ease of changing the value in one place, and the change is reflected throughout the code. It makes the code more readable, and less brittle (does not break easily if something changes).

Strings

C# supports two forms of string literals, regular and verbatim.

Regular strings are a sequence of zero or more characters enclosed in double quotes (“), like “hello world”. There may also be escape characters like \t (the TAB character), and hexadecimal and unicode escape characters.

Regular strings are declared and initialised in the same way as atomic types

So the above piece of code would print out

hello world

message in a bottle

 

Escape characters

\'\"\\\0, \a\b, \f, \n, \r, \t, \u, \U, \x, \v

Visit https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#string-literals for more details on these characters

A verbatim string begin with an @ character followed by a sequence of zero or more characters enclosed in double quotes (“), like @“hello world”. Verbatim strings do not interpret the escape characters

So the above code will print out

hello world

message in a bottle

So here are more complete examples of the differences between the two types of strings

String

Output

String

Output

“hello world”

hello world

@”hello world”

hello world

“hello world\t- message in a bottle”

hello world - message in a bottle

@”hello world\t- message in a bottle”

hello world\t- message in a bottle

“hello world\n - message in a bottle”

hello world

– message in a bottle

@”hello world\n - message in a bottle”

hello world\n - message in a bottle

“hello world\r - message in a bottle”

– message in a bottle

@”hello world\r - message in a bottle”

hello world\r - message in a bottle

“hello world\” - message in a bottle”

hello world” - message in a bottle

@”hello world”” - message in a bottle”

hello world” - message in a bottle

DateTime Type

Quite often you will find yourself having to work with dates and times. Both of these sequences use a very different counting base to our normal numbering system of 10. So performing any operations such as additions or subtractions on dates and times can be quite tricky and cumbersome. The DateTime type easily resolves this problem by providing such operations as additions and subtractions plus many other useful operations.

Because DateTime is not an atomic type but a class (a structured type with uniquely defined operations/methods), it is declared and initialised in a different way.

The above would initalise the variable blankDateTime with an object holding the value 01/01/0001 00;00;00 (we will discuss object in more detail in a later section)

You can print this out to the console using the statement

The following yield interesting and useful results

Statement

Output using Console.WriteLine()

Statement

Output using Console.WriteLine()

DateTime todaysDateAndTime = DateTime.Now;

The current date and time

DateTime todaysDate = DateTime.Today;

Today’s date

You can perform useful operations such as addition and subtraction of dates/times and days from DateTime objects.

Statement

Output using Console.WriteLine()

Statement

Output using Console.WriteLine()

Assuming today’s date is 28/09/2021, will result in 05/10/2021 15:22:23

Assuming today’s date is 14/09/2021, will result in 05/10/2021 15:25:51

Introducing TimeSpan

The C# TimeSpan represents a time interval measured in the number of days, hours, minutes, and seconds. Use TimeSpan when you want to compare C# DateTime objects to find the difference between those dates, or to manipulate those dates.

Statement

Output using Console.WriteLine()

Statement

Output using Console.WriteLine()

Assuming todays date is the 29/09/2021 will display 86

When using the TimeSpan object, the three zeroes represent hours, minutes, and seconds.

Assuming todays date is the 29/09/2021 will display 10/10/2021

Lab time

Calculate your electricity bill.

  • You are provided with the previous and current meter readings - these are in the form of whole numbers and represent units used, will be something like 16517 and 17215 respectively

  • The previous and current meter readings have previous and current dates

  • Each unit has a rate per unit - will be something like 17.84/kWh

  • There is a standing charge - will be something like 23.91 pence per day

  • The cost of used electricity will be units used * rate per unit + standing charge

  • VAT has to be added to the cost of the electricity used - this will be something like 5% addition to the cost of used electricity

 

So data types do we need?