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 |
---|---|---|
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 Even though char is within the integral family it differs in two ways
|
float | floating | 32-bit single precision IEEE 754 format. Represents values ranging from approximately |
double | floating | 64-bit double precision IEEE 754 format. Represents values ranging from approximately |
bool | boolean | Represents boolean logical quantities. The possible values of type |
decimal | decimal | Represent values ranging from |
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 |
---|---|
“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() |
---|---|
| The current date and time |
| 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() |
---|---|
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() |
---|---|
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?