Variables
By the end of this lesson you'll be able to store text, numbers, and true/false values in C++, choose the right type, convert safely between them, and read input from the user — the foundation of every C++ program you'll ever write.
Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn
💡 Real-World Analogy
A variable is a labelled container in a kitchen. A jar labelled "Sugar" ( string ) holds text; a measuring cup labelled "Cups" ( int ) holds whole numbers; a scale labelled "Weight" ( double ) holds decimals. Each container only holds one kind of thing — you can't pour flour into a liquid measuring cup. C++ is statically typed , which means every variable's type is fixed when you declare it and the compiler checks it before your program ever runs. That strictness is a feature: it catches whole classes of mistakes early.
📊 The Core Data Types
Type
Holds
Size
Example
int
Whole numbers
4 bytes
int age = 25;
double
Decimals (~15 digits)
8 bytes
double h = 1.75;
float
Decimals (~7 digits)
float t = 36.6f;
char
One character
1 byte
char g = 'A';
bool
true / false
bool ok = true;
std::string
Text
varies
string n = "Al";
Notice string uses "double quotes" but char uses 'single quotes' — mixing these up is the #1 beginner error, so it's worth burning in now. ( string lives in the <string> header.)
1. Declaring & Initializing Variables
Every variable needs a type and a name , and you usually give it a value on the same line: type name = value; . Use descriptive camelCase names like firstName or totalPrice — code is read far more often than it's written, so a clear name pays for itself. Read this worked example, run it, then check the output against the comments.
There's more than one way to give a variable its first value. The modern brace initialization — int x { 5 } — is preferred because it refuses to silently lose data (it blocks "narrowing", like squeezing 3.9 into an int ). And auto lets the compiler pick the type for you from the value on the right.
Your turn. The program below is almost complete — fill in the three blanks marked ___ using the hints in the comments, then run it.
2. Constants, Signedness & Sizes
Some values should never change — a tax rate, a maximum number of lives, pi. Mark them const and the compiler will reject any attempt to reassign them. constexpr goes one step further: the value must be known at compile time, which lets the compiler use it as a fixed size or array length. Numbers are also signed by default (they can be negative); marking one unsigned drops the negatives and reaches a bigger positive range with the same memory. sizeof tells you exactly how many bytes a type uses.
3. Type Conversion & Casting
Sometimes a value is the wrong type and you need to convert it. Implicit conversion happens automatically when it's safe (an int fits inside a double ). When the conversion can lose data — like double to int — C++ may still do it but the decimals just vanish. To convert deliberately you use static_cast<type>(value) , which states your intent clearly and is far safer than old C-style (int) casts. The classic trap: dividing two int values gives an int result.
Now you try. The two values below are int , so a plain / would chop the decimals off. Cast one side to double so the answer keeps its fraction:
4. Scope & Reading Input with cin
Scope is simply where a variable is visible . A variable lives inside the nearest pair of { } braces and disappears at the closing brace — try to use it outside and the compiler won't know what you mean. You read keyboard input with std::cin >> variable : the >> operator pulls what the user typed into your variable, automatically matching the variable's type (a number into an int , a word into a string ).
🔎 Deep Dive: auto vs spelling out the type
auto asks the compiler to deduce the type from the value: auto city = string("London"); is exactly a string . It's still strongly typed — once deduced, the type is fixed. Use auto to cut noise when the type is obvious or very long, but prefer the explicit type when it makes beginner code clearer.
const and constexpr both mean "do not reassign". const is read-only at run time; constexpr is fixed at compile time. Constants are written in UPPER_SNAKE_CASE by convention so they stand out.
Pro Tips
- 💡 Prefer double over float : double is the default and far more precise; only use float when memory is genuinely tight.
- 💡 Always initialize: an uninitialized local like int x; holds a garbage value until you assign one. Give every variable a starting value.
- 💡 Use brace init for safety: int x { 5 } blocks narrowing conversions that int x = 5.9; would silently allow.
- 💡 Name things well: totalPrice tells a story; tp or x doesn't.
Common Errors (and the fix)
- Uninitialized variable (undefined behaviour): int x; cout << x; prints a random garbage value — and the program's behaviour is undefined. Always initialize: int x = 0; or int x { } .
- Integer division truncation: cout << 7 / 2; prints 3 , not 3.5 . Make one side a decimal — 7.0 / 2 — or use static_cast<double>(7) / 2 .
- "narrowing conversion ... inside { } ": brace init blocks lossy conversions, so int n { 3.9 } ; won't compile. Use a double , or cast: int n { static_cast<int>(3.9) } ; .
- Wrong quotes: "A" (double quotes) is a string ; 'A' (single quotes) is a char . Writing char c = "A"; fails to compile because the types don't match.
- "was not declared in this scope": you used a variable outside the { } block it was declared in. Declare it in an outer scope so it's still visible where you need it.
📋 Quick Reference
Task
Code
Result
Declare integer
int x = 10;
10
Brace init
int x{5};
5 (safe)
Infer type
auto y = 3.14;
Constant
const int MAX = 100;
read-only
Safe cast
static_cast<double>(x)
Memory size
sizeof(int)
4
Read input
cin >> age;
into age
Frequently Asked Questions
Mini-Challenge: Profile Card
No blanks this time — just a brief and a blank canvas (with an outline to keep you on track). Build it, run it, and check your output against the example in the comments. This is exactly the kind of small program real apps are made of.
🎉 Lesson Complete
- ✅ Fundamental types: int , double , float , char , bool , std::string
- ✅ "double quotes" for strings, 'single quotes' for a single char
- ✅ Brace init int x { 5 } blocks narrowing; auto infers the type
- ✅ const and constexpr lock values; unsigned drops negatives; sizeof shows bytes
- ✅ Implicit conversion is automatic; static_cast<type>(x) converts safely and clearly
- ✅ Variables live inside their { } scope; cin >> reads input into them
- ✅ Next lesson: Operators — do maths, compare values, and combine conditions
Practice quiz
Which type should you use to store a whole number like an age or a count?
- double
- int
- char
- bool
Answer: int. int holds whole numbers; double and float are for decimals.
What is the default floating-point type in C++ (about 15 digits of precision)?
- float
- decimal
- double
- real
Answer: double. double is the default floating-point type, with roughly 15 significant digits.
What is the difference between 'A' and "A" in C++?
- They are identical
- 'A' is a char, "A" is a std::string
- 'A' is a string, "A" is a char
- 'A' is invalid syntax
Answer: 'A' is a char, "A" is a std::string. Single quotes make a char (one character); double quotes make a std::string.
What does std::cout print for 7 / 2 when both are int?
- 3.5
- 3
- 4
- 3.0
Answer: 3. Two ints do integer division: the remainder is dropped, giving 3.
Which keyword lets the compiler infer a variable's type from its value?
- var
- auto
- let
- infer
Answer: auto. auto deduces the type from the initializer, e.g. auto x = 42; makes x an int.
What keyword marks a value that must be known at compile time?
- const
- static
- constexpr
- final
Answer: constexpr. constexpr is stronger than const: the value must be known at compile time.
How do you convert an int to a double deliberately and clearly?
- double(x)!
- static_cast<double>(x)
- convert<double>(x)
- x as double
Answer: static_cast<double>(x). static_cast<double>(x) states the conversion clearly and is safer than C-style casts.
What does brace initialization int n{3.9}; do?
- Sets n to 4
- Sets n to 3
- Fails to compile (narrowing blocked)
- Sets n to 3.9
Answer: Fails to compile (narrowing blocked). Brace init blocks narrowing, so squeezing 3.9 into an int won't compile.
What does sizeof(int) typically return on a 64-bit desktop?
- 1
- 2
- 4
- 8
Answer: 4. An int is typically 4 bytes; sizeof reports the byte size of a type.
What happens to a variable declared with 'int c;' but never assigned before use?
- It is automatically 0
- It holds a garbage value
- The program won't compile
- It becomes null
Answer: It holds a garbage value. An uninitialized local holds a garbage value until you assign one — always initialize.
Continue this course
- Previous: Introduction to C++
- Next: Operators