Imagine writing a program that asks for someone's name and then greets them. Before the program can print Hello, Sarah, it has to know what Sarah actually is — it has to store that name somewhere so it can refer to it later. Variables are how programs hold on to information while they run.
Variables
A variable is a labeled container that holds a value. Picture a row of small boxes on a shelf, each with a label written on the front. The label is the name you've chosen for the box, and inside the box is whatever you've put there.
In a program, if you want to keep track of a player's score, you create a box, give it the name score, and put a number inside. Every time the program mentions score after that, it looks at that box and uses whatever value is currently in there.
This is what makes variables powerful. Instead of writing the same value in twenty different places throughout your code, you store it once under a meaningful name and refer to that name everywhere. If the value ever needs to change, you change it in one place and the rest of the program adjusts automatically.
Declaring a Variable
Before you can use a variable, you have to declare it. Declaring is the moment you tell the program: "I want a new box, this is its name, and this is the kind of thing I'm going to put in it."
The most common form looks like this:
Three things are happening on this single line. The word int is the type — it tells the compiler what kind of value the box can hold, in this case an integer. The word age is the name of the variable, your label for the box. The = 16 part is the initialization — the starting value placed inside the box.
You can also declare a variable without giving it a starting value:
Here, the first line creates the box, and the second line places a value into it. Both styles are valid C++, but initializing on the same line as the declaration is usually cleaner. It avoids the risk of using a variable before you've actually put anything meaningful into it, which is a common source of bugs.
You can also declare multiple variables of the same type on one line by separating them with commas:
This is mainly a stylistic shortcut. For readability, it's often better to give each variable its own line, especially when the values come from different sources or represent different ideas.
Naming Rules
Variable names aren't a free-for-all. C++ has a few rules you have to follow:
A name can contain letters, digits, and the underscore character (_).
A name must start with a letter or an underscore, never a digit.
Names are case-sensitive — score and are two completely different variables.
Reserved keywords like int, return, if, and while can't be used as names.
Spaces are not allowed inside a name.
Beyond the rules, you have a lot of freedom in how you name things — and you should use it wisely. A name like numberOfStudents is much easier to read six months later than a name like n or x. Short names are fine for short-lived values inside a small block of code, but when a variable's purpose isn't obvious from its surroundings, a descriptive name saves you from having to re-read the entire program just to remember what something meant.
Data Types
Every variable has a type, and the type controls three things at once: what kinds of values the variable is allowed to hold, how much memory it takes up, and what operations make sense to perform on it.
You wouldn't store a person's name inside a box labeled "shoe size", and you wouldn't try to take the square root of the word "hello". Types prevent that kind of mismatch. They're how you tell the compiler what each variable is actually for, so it can catch mistakes before the program ever runs.
C++ comes with a number of built-in types. The ones below are the most common, and you'll use them constantly from this point on.
int
The int type stores whole numbers — positive, negative, or zero. No decimal points.
On most systems, an int can hold values from roughly -2,147,483,648 to 2,147,483,647. That covers the overwhelming majority of everyday numbers — ages, scores, counts, indices — but it does have a ceiling. What happens when a value tries to push past that ceiling is the topic of the third lesson this week.
char
The char type stores a single character. The character is written between single quotes.
A char can hold any single character: a letter, a digit, a punctuation mark, even a space. 'a', '7', '?', and ' ' are all valid char values. One thing worth pointing out is that '7' (the character) is not the same as 7 (the number) — they look similar in source code, but the program treats them very differently. The character '7' is just a symbol; the number 7 is something you can do arithmetic with.
Here's a small program that uses a char:
This prints:
ASCII Encoding
Internally, the computer doesn't actually store the letter 'A' as a tiny drawing of the letter. It stores a number. Every character has a corresponding numeric code, defined by a standard called ASCII (American Standard Code for Information Interchange).
The character 'A' corresponds to 65. 'B' is 66, 'C' is 67, and so on through the alphabet. Lowercase 'a' is 97. The digit character '0' is 48. The full ASCII table covers 128 entries — every letter, digit, and common punctuation mark you'd find on a standard keyboard.
You can ask the program to show you the ASCII value of a character by converting it to an int:
This prints:
The expression int(letter) is called a cast — it asks the program to look at the character and give you its numeric code as an integer.
The cast also works in the other direction. You can take an integer and convert it back into the character whose ASCII code matches:
This prints A. The expression char(code) takes the integer and returns the corresponding character. This is how you produce a character "by position" — for instance, the 5th lowercase letter of the alphabet is the character whose code is 'a' + 4.
Character Arithmetic
Because characters and integers convert so freely between each other, you can do arithmetic directly on characters and the compiler handles the conversions for you. The expression 'a' + 1 produces an integer (98, the ASCII value of 'b'), which you can turn back into a character with another cast:
This prints e. The compiler treated 'a' as 97, added 4 to get 101, and the char(...) cast converted 101 back into the character 'e'.
This pattern is used constantly when working with letters. A few common applications:
char('a' + k) gives you the k-th letter (zero-indexed) of the lowercase alphabet. So char('a' + 0) is 'a', and char('a' + 25) is 'z'.
char(c + 32) converts an uppercase letter c to lowercase, because every lowercase letter sits exactly 32 positions after its uppercase counterpart in ASCII.
char(c - 32) does the opposite, converting lowercase to uppercase.
For example:
This prints m. The 'M' has ASCII code 77, adding 32 gives 109, which is the code for 'm'.
You can also subtract characters from each other. The expression 'e' - 'a' evaluates to 4, because 'e' is the 5th letter (index 4) of the alphabet. This is how you'd find the position of a letter when you don't know it ahead of time.
string
A string represents a sequence of characters — a word, a sentence, a name, anything text-shaped. Strings are written between double quotes, not single ones.
To use string, you also need to include the <string> library at the top of your file:
The variable greeting holds the entire phrase "Hello, world!" as a single value. Strings can be empty (""), a single character long ("A"), or hundreds of characters long. There's no practical limit on their size for normal use.
Notice the careful distinction in quotes: single quotes ('A') make a char, while double quotes ("A") make a string. They look almost identical in source code, but they mean different things to the compiler. A char is exactly one character. A string is a sequence of characters, even if that sequence happens to contain only one.
float and double
The int type can't store fractions. If you need numbers like 3.14, 9.8, or 0.5, you need a floating-point type — a type designed for numbers with a decimal part.
C++ provides two of them: float and double. Both store decimal numbers, but they differ in precision — how many digits of the number they can keep track of accurately.
A float typically gives you around 7 significant digits of precision.
A double gives you around 15 to 16 significant digits.
In almost all situations, double is the safer default. It's more precise, and on modern computers the performance difference between float and double is irrelevant for the kinds of programs you'll be writing for a while.
A subtle gotcha: integer division
One thing to watch out for when mixing types. If both operands of / are integers, C++ performs integer division — it computes the result and discards the fractional part. This is true even when the destination is a double:
You might expect this to print 3.3333.... It actually prints 3. The expression 10 / 3 was computed first using integer arithmetic, producing 3. That integer was then converted to a double and stored in result — but the decimal part was already gone before the assignment ever happened.
To get a real-valued division, at least one of the operands has to be a floating-point number:
The cast form (double)a / b is the version you'll use most often. When the values come from int variables, you can't add a .0 to them — you have to convert one of them with a cast.
Controlling output precision
By default, cout doesn't show many digits after the decimal point. If you want more, you can use setprecision from the <iomanip> library:
This prints:
The number 10 divided by 3 has an infinite decimal expansion — the threes go on forever — so the program has to stop somewhere. setprecision(8) tells cout to show 8 significant digits before stopping. Try changing the number inside setprecision to see how the output adjusts.
Decimal places vs significant digits
There's an important subtlety with setprecision. By default, the number you pass controls the count of significant digits — the total number of meaningful digits shown, regardless of where the decimal point sits. With setprecision(4), the value 12345.6789 comes out as 1.235e+04 (scientific notation), and 0.000123456 comes out as 0.0001235.
If what you want is a specific number of digits after the decimal point — which is what almost every problem actually asks for — you also need the fixed manipulator:
This prints:
With fixed, the number passed to setprecision is now interpreted as decimal places — exactly what you want when a problem asks for "precision of 10⁻⁶" or "6 digits after the decimal point". Once fixed is applied to cout, it stays in effect for the rest of the program, so you only need to set it once at the beginning.
The combination cout << fixed << setprecision(n) is the standard idiom for clean decimal-place output, and you'll use it constantly from this point on.
bool
The bool type holds one of exactly two values: true or false. Nothing else.
Booleans are everywhere in programming, even when you don't see them written out as bool variables. Every time a program checks a condition — "is this number greater than ten?", "are these two names equal?", "did the user click yes?" — the answer to that check is a bool. Either yes (true) or no (false).
You can also store the result of a comparison directly into a bool:
After this code runs, isAdult holds the value true, because the comparison age >= 18 evaluates to true when age is 20.
In next week's lessons, you'll see bool show up constantly inside conditional statements — the if keyword relies entirely on boolean values to decide which branch of code should run.
long long int
Sometimes int isn't big enough. If you're counting something that goes into the billions, or working with astronomical distances, or computing factorials of even moderately large numbers, you'll bump into the upper limit of int very quickly.
The long long int type (often written simply as long long) gives you a much larger range — up to about 9.2 quintillion. The exact upper limit is 9,223,372,036,854,775,807.
Notice the LL suffix at the end of the literal 1234567890123456789LL. Without it, the compiler tries to interpret the number as a regular int first, and since the number is far too big to fit in an int, you get an error or a wrong value. The LL tells the compiler: "treat this number as a long long from the very start, before doing anything else with it."
You don't need the LL suffix for small values. long long score = 100; works fine — the number 100 fits comfortably in an int, and the compiler can promote it to long long without any trouble. The suffix only matters when the literal itself is already too large to be an int.
Quick Reference
Type
Stores
Example values
int
Whole numbers
42, -7, 0
long long int
Very large whole numbers
1234567890123LL
float
Decimal numbers, ~7 digits of precision
3.14
double
Decimal numbers, ~15 digits of precision
9.80665
char
A single character
'A', '?', '7'
string
A sequence of characters
"Hello", "Sarah"
bool
true or false
true, false
Each type exists for a reason. For now, the rule of thumb is straightforward: whole numbers go in int, very large whole numbers go in long long, decimal numbers go in double, single characters go in char, text goes in string, and yes/no values go in bool.
In the next lesson, we'll look at how to update variables efficiently using assignment operations — the shortcut operators that come up constantly in real programs.
int age = 16;
int score;score = 100;
int width = 10, height = 5, depth = 3;
int score = 100;int temperature = -5;int zero = 0;
#include <iostream>using namespace std;int main(){ char letter = 'A'; int code = int(letter); cout << "The ASCII value of "<< letter << " is "<< code << endl; return 0;}
The ASCII value of A is 65
#include <iostream>using namespace std;int main(){ int code = 65; char letter = char(code); cout << letter << endl; return 0;}
char letter = char('a' + 4);cout << letter << endl;
double a = 10.0 / 3; // 10.0 is a double, result is 3.333...double b = 10 / 3.0; // 3.0 is a double, same resultdouble c =(double)10 / 3; // cast 10 to double explicitly
#include <iostream>#include <iomanip>using namespace std;int main(){ double result = 10.0 / 3.0; cout << setprecision(8)<< result << endl; return 0;}
3.3333333
#include <iostream>#include <iomanip>using namespace std;int main(){ double value = 1234.56789; cout << fixed << setprecision(2)<< value << endl; return 0;}
1234.57
bool isReady = true;bool isFinished = false;
int age = 20;bool isAdult =(age >= 18);
#include <iostream>using namespace std;int main(){ long long int bigNumber = 1234567890123456789LL; cout << bigNumber << endl; return 0;}