We use variables in programs when we want to store data temporarily while the program is running.
If we think about it, programs for the majority of cases, need data to function correctly.
For example a calculator takes numbers and runs operations on them (like division, addition, and multiplication etc.). Or consider a browser that needs the address of a website to be able to load that website for us to see.
A video player is another example of a program that needs data (video) to display it to users.
These data are stored in the memory and we use variables to store and have the access to those data.
A variable represents a memory location. We can call it to get the value that is already in that memory (if any) or to store a new value in that memory space.
This is the structure of how we create a variable:
Data-type variable-name;
Data-type: data in programs has different types and when we create a variable, it’s important to declare the type of that variable as well.
For example if we have a value that is an integer like 300, and we want to store this value in a variable, we need to declare the type of that variable as int which stands for integer.
After setting the type of a variable, we can’t change the type anymore. For example you can declare a variable to integer but after that cannnot change it to another type like string etc.
Now the question is why in programs we need to declare the type of a variable?
Well the first reason is the amount of memory space that will be allocated to the variable.
In C# there are multiple data types like int, double (for storing floating values), float (another data-type for storing floating values) and other types.
Each of these types takes a different amount of memory. For example a variable of type int has enough memory space to only store integer values range from -2,147,483,648 to 2,147,483,647.
If in a program we need to store a value larger or smaller than the range that a variable of type int can support, then we need to use another type like long and short just to name a few.
So the data type helps the C# engine to declare how much memory space should be set aside for that variable.
The second reason that we use data-types is to help the compiler and developers to figure out what type of values are allowed to be stored in the variable.
Note: if we put a value of different data type to a variable, depending on the type of the value, the compiler will either return error or it will try to cast the value to the right type.
Note: In the data type section we’ve explained the data types in greater details.
variable-name: the name of a variable is the way to access its memory space. It’s like a door that opens to the memory-space.
With the help of this name, we can store and get values in and out of that memory space.
Example:
using System;
namespace quickExample
{
class Program
{
static void Main(string[] args)
{
int age;
}
}
}
Here the variable is named age and its data type is integer. So now the C# engine will allocate enough memory space for this variable that allows us to store values range from -2,147,483,648 to 2,147,483,647 into this variable. Also this memory space is now linked to the age variable and it’s our way to access the memory.
Note: the process of creating a variable is called variable declaration.
In assignment operators section we will explain in depth how to assign a value to a variable but for now this is how we can do so:
int age;
age = 40;
First of all we use assignment = operator to store a value to a variable (strictly speaking: to its memory space).
For example here we’ve stored the value 40 into the age variable.
Notes:
-
To assign a value to a variable we put the variable on the left
side of the assignment `=` operator. -
We could directly assign values right where the variables are
declared.
int age = 40;
Also the process of assigning values to variables for the first time is called variable initialization.
Other than on the left side of the assignment = operator, if in any other places we call a variable we will get its value. Basically the engine will interpret the request as a get request and will return the value that is stored in the memory space of the variable.
Example:
using System;
namespace quickExample
{
class Program
{
static void Main(string[] args)
{
int age = 29;
Console.WriteLine(age);
}
}
}
Output: 29
Here the first statement in the body of the Main method is a variable declaration with the name age and it’s being initialized with the value 29.
In the next statement we’ve called the WriteLine method of the Console class and passed the age variable as its argument. The C# engine considers this action as a get request for the value that is already in the memory space of the age variable. So it will return this value and pass it to the WriteLine method.
Note:
-
You can learn more about the `WriteLine` method in the
linked section.
A couple of rules that we need to follow when setting a name for a variable:
-
The name that we use for a variable can contain letters, numbers
and underscore (_). For example: jack, ellen2020, _black, sunnySeason
etc. -
A name for a variable can begin with either underscore or letter.
For example: _sum, check_point etc. -
The name of a variable cannot start with number.
-
We can’t use white space and special characters like !@#
%^&*()+ etc. in variable’s name. For example these names are
illegal: ell en, %%jack, Tony&&, pre-process. -
The C# language is case sensitive which means a variable named
`ellen` is different than a variable named `Ellen` or `ELLEN`. -
We can’t create two variables with the same name in the same
method. But we can have two variables with the same name each
live in different method or one live in one method and the other live in
global scope (outside all other functions). -
We can’t use C# language reserved keywords as the name of a
variable. -
Here’s the list of reserved keywords:
| abstract | as | base | bool | break |
|---|---|---|---|---|
| byte | case | catch | char | checked |
| class | const | continue | decimal | default |
| delegate | do | double | else | enum |
| event | explicit | extern | false | finally |
| fixed | float | for | foreach | goto |
| if | implicit | in | int | interface |
| internal | is | lock | long | namespace |
| new | null | object | operator | out |
| override | params | private | protected | public |
| readonly | record | ref | return | sbyte |
| sealed | short | sizeof | stackalloc | static |
| string | struct | switch | this | throw |
| true | try | typeof | unit | unlong |
| unchecked | unsafe | ushort | using | virtual |
| void | volatile | while |
-
Semicolon `;`: the process of creating a new variable is called
`declaration statement` and any declaration statement ends with
semicolon `;`.
Note: We only use data types once when we’re declaring a variable. From that moment afterward, assigning values to a variable does not need mentioning the type of the variable anymore.
For example:
int firstNumber;
firstNumber = 100;
Locations where we can declare a variable:
A variable can be declared either inside a method or outside of it in the body of class. If a variable is declared in the body of a method, it is the local variable of that method and no other method can access this variable. But if the variable is declared outside of any method and in the body of the class, it is called the attribute of the class and so accessible throughout the body of that class (including within the body of its methods).
Note: if the access specifier of an attribute variable is public it can also be accessible via objects that are created from that class.
Local variables:
As mentioned before, local variables are only accessible from the body of a method that they are declared in. This means if we have two methods named first and second and inside the first method we declare a variable named age the second method can’t access that variable.
If we attempt to do so, we will get a compile time error.
Note: compile time error means the compiler will not compile the source code and instead it will return an error giving its reason of why not compiling.
Example:
using System;
namespace quickExample
{
class Program
{
static void Main(string[] args)
{
int age = 29;
Console.WriteLine(age);
}
static void Second()
{
Console.WriteLine(age);
}
}
}
Output:
The name ‘age’ does not exist in the current context
Here the Main method has a local variable named age. There’s also another method named Second in this example and in its body we’re trying to send the value of the age variable to the console. But here from the perspective of the C# engine, there’s no age variable in the body of the Second method and so instead of running the program, it will simply return an error explaining why it can’t run the program.
In short because a local method is not accessible in another method, the compiler returned error instead of compiling the program.
Now let’s declare the variable outside of all methods:
using System;
namespace quickExample
{
class Program
{
static int age = 29;
static void Main(string[] args)
{
age = 50;
Second();
}
static void Second()
{
Console.WriteLine(age);
}
}
}
Output: 50
Notes:
-
When creating a variable outside of any method, and that
variable is about to be used in a static method, we need to declare the
variable as `static` just like the way we did it in this example.
(Simply put the `static` keyword behind the variable declaration).
You’ll learn more about this in the static field
section. -
For those of you who are coming from `Java` you should know that
a static variable is accessible within the body of a non-static method.
But in Java you’re not allowed to use static variables in non-static
methods. You’ll learn more about it in the static variables
section.
In this example the variable named age is declared as the attribute of the class (outside of all methods) and so methods of this class can access the variable. This means the methods can change or just get its value.
Here we changed the value of the age variable in the body of the Main method and then called the Second method and in the body of that method we sent the value of the age variable to the output stream.
In the method section we’ll explain how methods can call each other.
Notes:
-
A method can only see and work with variables that exist globally
or within the body of that method. Check the method section for
more information. -
Also the name of a variable should be unique in the scope that is
declared. For example if a variable is declared globally with the name
`gVar`, no other `gVar` is allowed to be declared globally. Similarly,
if within the body of a method like `Main()` we declared a variable with
the name say `age`, no other variable with this name is allowed to be
declared inside this method.
Note: But we can have two variables with the same name one declared globally and the other declared locally within the body of a method. Also there can be two or more local variables with the same name if each one of them is declared inside a separate block.
Multiple variable declarations:
It is also possible to declare multiple variables with the same type in a single statement:
Data-type variable_one, variable_two, variable_n;
In this structure, each variable is separated via colon ,.
For example:
double v_one, v_two, v_n;
In the example above, we’ve created 3 variables of type double.
Note: we could also assign values directly to each variable if we wanted.
For example:
int variable_one = 10, variable_two = 30, variable_n = 50;
Access specifier:
A variable also has something called access specifier.
In access specifier section we will explain in details but for now remember that: an access specifier comes before the data type of a variable and it declares the accessibility of that variable.
For example a variable that is declared private like:
private int variable_one = 10;
Means only members in the class can access this variable. If we create an object from the class that contains a private member, that object won’t be able to access the private member.
Or if we set the access specifier of a variable as public that means the variable is also accessible via the objects created from that class.
public int variable = 10;
Note: We can’t use access specifiers for the local variables.
Again in access specifier section we will explain this topic in greater details.