Introduction to variables
In this lesson, we'll talk about how to store different values while a program is running — that is, how to use variables.
Motivation
To understand what they are useful for, let's write a program that raises a number to the third power and then displays it:
#include <iostream>
int main()
{
std::cout << 212 * 212 * 212;
}
9528128
If we now want to raise a different number to the third power, we will have to change three places in the code. It is tedious.
Solution
In order to avoid changing so many things every time, let's assume for a moment
that the number we are exponentiating is called x
.
What will the code look like then?
#include <iostream>
int main()
{
std::cout << x * x * x;
}
The above program at this stage will not compile. To use x
in a calculation,
we first need to create a variable named x
:
#include <iostream>
int main()
{
int x = 212;
std::cout << x * x * x;
}
The above program will compile and run correctly.
A variable is a named "container" that holds a specific type of information that can be used in a program. Its value can change, but the type cannot.
Variable is like a labeled box that you can put things in and take things out of as needed.
Creating variables
In the above program, we created the variable like this:
int x = 212;
- 🔢 With initial value
- ⚪ Without initial value
This is an important notation that you'll see very often throughout your programming career. In the following sections, we'll explain what different parts of this notation mean.
Variable type
The type of a variable tells you what the variable can store. As mentioned before, a variable is a container that holds certain things of a certain type.
int
is an abbreviation of the word integer that is, a number without the fractional part (a whole number).
At this stage, you should remember the following types of variables:
Type | Description |
---|---|
int | integer (whole number) |
float | real number (with fractional part) |
char | a single character |
bool | boolean value, i.e. true or false |
We will cover more types and facts about them in the future.
The above-mentioned types of variables are always written with lowercase letters. It matters, C++ is case-sensitive!
Examples of creating variables:
int
float
char
bool
// Without initialization
// Variable will contain an unpredictable value
int x;
// We create a variable and assign the 30 value to it
int y = 30;
// Without initialization
// Variable will contain an unpredictable value
float x;
// We create a variable and assign the 30 value to it
float y = 30;
// We create a variable and assign the 1.234 value to it
float z = 1.234f;
When we assign a value with a fractional part to a variable of type float
, we have to put the f
character at the very end:
- ✔
12.45f
- ❌
12.45
This has its justification, but more on that later.
// Without initialization
// Variable will contain an unpredictable value
char x;
// We create a variable and assign the 'j' character to it
char y = 'j';
Single characters are always written between single quotes.
- character:
'c'
- a string of characters, consisting of 1 character:
"c"
Therefore:
- ✔
char x = 'c';
- ❌
char x = "c";
// Without initialization
// Variable will contain an unpredictable value
bool x;
// We create a variable and assign the "true" value to it
bool y = true;
// We create a variable and assign the "false" value to it
bool z = false;
Variable name
The name can be anything you want, with some important restrictions:
- ❌ must not have spaces (prohibited: ❌
abc def
) - ❌ most symbols not allowed
- ✔ may consist of:
- ✔ characters
a
-z
andA
-Z
- ✔ digits, but not at the beginning (prohibited: ❌
932abc
) - ✔ underscores
_
- ✔ characters
Extra notes on underscores
While underscores are allowed in names, there are a few instances that are reserved by C++:
- Leading underscores followed by a capital letter (prohibited: ❌
_Speed
) - Double leading underscores (prohibited: ❌
__xyz
)
You can create as many variables as you want, but they must have different names as they are their unique identifiers (with some exceptions, but more on that later).
Capitilization is important, variable names are case-sensitive:
int x = 30;
float X = 12.34f;
In the code above, the variables x
and X
are two different variables!
It's best to use only English names, for example:
float average;
instead of:
float srednia; // average in Polish
Initialization (initial value)
Initialization is an optional step in creating variables. When we create it, we can either leave it without the desired value:
int x;
or assign it an initial value:
int x = 30;
An uninitialized variable, inside a function block (e.g. inside main
) will initially have
an unpredictable value, it won't be reset to 0.
Leaving a variable without its initial value can cause problems later in the code. Sometimes, however, we may intentionally skip it, but more on that later.
You can never read from a variable when it is in an uninitialized state!
Semicolon at the end
Just a reminder 😀
int age = 40;
Opportunities
In this section, I will only show you a few ways to use variables, while their explaination is in the next lesson.
Receiving input from the user
To receive user input, we can make an uninitialized variable, then tell C++ to put the user's response into that variable.
#include <iostream>
int main()
{
int age; // current age (note: uninitialized!)
std::cout << "Enter your age: ";
std::cin >> age;
std::cout << "In 10 years you will be: " << age + 10 << " years\n";
}
Breaking up complex equations
We can use variables to represent intermediate values in complex equations. This helps make the code more readable and maintainable.
#include <iostream>
int main()
{
float current_pos = 10; // in meters
float target_pos = 20; // in meters
float current_speed = 2.5f; // in meters/second
float time_remaining = 0.5f; // in seconds
// Calculate where we will end up once time runs out
float ending_pos = current_pos + current_speed * time_remaining;
// Calculate how far away we landed from the target
float error = target_pos - ending_pos;
// Calculate the required speed needed to land directly on the target
float required_speed = (target_pos - current_pos) / time_remaining;
// Calculate the amount of extra speed we needed to land directly on the target
float extra_speed_needed = required_speed - current_speed;
std::cout << "We landed " << error << " meters away from the target.\n";
std::cout << "We needed to go " << extra_speed_needed << "m/s faster to land on the target.";
}
We landed 8.75 meters away from the target.
We needed to go 17.5m/s faster to land on the target.
Summary
To summarize, we learned:
- How to create a variable and understand the syntax
- The difference between types of variables
- Why variables are useful
Additional info
Lack of initialization
int main() {
int x; // No initializer
}
An uninitialized variable (without an assigned value at the beginning), inside a function block (e.g. inside main
)
will have an unpredictable value at the beginning, (ie, it won't be set to zero).
Leaving a variable without an initial value can cause problems later in the code execution if you read from it before it is assigned.
While it may seem weird to have such a possibility for error in the language, we sometimes want to intentionally do this. Receiving input from the user displays one reason for this.
Type conversion
A variable has a specific type that cannot be arbitrarily changed in different places in the code.
The values that we try to write into it must match its type. But, many types will be converted
automatically if you assign without matching types.
For example, we can write an integer value (int
) to a variable of type float
(a real number).
This triggers a conversion from int
to float
.
float y = 30; // OK - 30 is converted to 30.0f
Going in the other direction is a bit more problematic.
A variable of type int
cannot store a fractional part, so when we try to write a float
value to it,
it will be converted to a number that doesn't have a fractional part.
C++ doesn't do this by rounding - instead, it does it by truncating. The fractional part of the number
is completely chopped off and thrown away. For example, 3.1415
truncates to 3
.
int y = 30.5f; // OK, 30.5f is converted to 30, but information lost!
A compiler may issue a warning that there is an implicit narrowing conversion. This warning exists because it's common for programmers to accidentally write code like this that loses the fractional part, causing errors in our values.
Try to match types whenever you can! Implicit conversions like float
to int
causes loss of information!
This can cause wrong results in the best case, and even disaster in the worst case.
The Ariane 5 rocketship flight V88 catastrophically exploded 37 seconds after launch due to an erroneous
conversion from float
to int
, causing a loss of precision that halted the navigation computer.