C++ Variables and Data Types
ProgrammingLesson 2 of 65 min read
What you'll learn
- Declare and initialise variables with int, double, char, bool and std::string
- Check type sizes with
sizeofand know that sizes depend on the platform - Use
auto,constand brace initialisation appropriately - Convert between types with
static_castand avoid integer-division traps
On this page
Every value in a C++ program has a type that decides how many bytes it occupies and what you can do with it. Pick the wrong type and a price loses its decimals, a counter wraps around, or a comparison quietly does something you did not intend. This lesson covers the types you will use every day and the habits that keep them safe.
Declaring and initialising variables
A declaration gives the type, then the name, then optionally a value: int age = 29;. C++ also supports brace initialisation, int age{29};, which refuses conversions that would lose information. That makes it a good default habit. Unlike Java, a local variable that you do not initialise is not set to zero; it holds whatever garbage was in that memory, and reading it is a bug.
The core types
The fundamental types are small and map closely to hardware. The sizes below are the usual ones on modern 64-bit desktop systems; the C++ standard only guarantees minimums and that sizeof(char) is 1, so use sizeof when it matters.
| Type | Typical size | Holds | Example |
|---|---|---|---|
| char | 1 byte | A single character in single quotes | char grade = 'A'; |
| bool | 1 byte | true or false | bool inStock = true; |
| int | 4 bytes | Whole numbers, roughly -2.1 billion to 2.1 billion | int age = 29; |
| long long | 8 bytes | Very large whole numbers | long long people = 8000000000LL; |
| float | 4 bytes | Decimals, about 7 significant digits | float rating = 4.5f; |
| double | 8 bytes | Decimals, about 15 significant digits | double price = 499.99; |
| std::string | Varies | Text of any length (a class, not a primitive) | string name = "Priya"; |
#include <iostream>
#include <string>
using namespace std;
int main() {
int age = 29;
double price = 499.99;
char grade = 'A';
bool inStock = true;
string name = "Priya";
cout << name << " is " << age << endl;
cout << "Price: " << price << endl;
cout << "Grade: " << grade << endl;
cout << "In stock: " << inStock << endl;
cout << boolalpha << "In stock: " << inStock << endl;
string last = "Sharma";
string full = name + " " + last;
cout << full << " has " << full.length() << " characters" << endl;
cout << full.substr(0, 5) << endl;
cout << (name == "Priya") << endl;
return 0;
}Output
Priya is 29 Price: 499.99 Grade: A In stock: 1 In stock: true Priya Sharma has 12 characters Priya true
Two things to notice. A bool prints as 1 or 0 until you switch on boolalpha, and that setting is sticky for the rest of the stream. And std::string is far friendlier than Java strings in one way: == compares the text, and strings are mutable, so you can change them in place. Prefer std::string over old C-style char arrays for all text.
Finding sizes with sizeof
sizeof tells you how many bytes a type or variable occupies on the machine you are compiling for. It is evaluated at compile time. This is a useful way to confirm your assumptions instead of guessing.
#include <iostream>
using namespace std;
int main() {
cout << "char: " << sizeof(char) << "\n";
cout << "bool: " << sizeof(bool) << "\n";
cout << "int: " << sizeof(int) << "\n";
cout << "float: " << sizeof(float) << "\n";
cout << "double: " << sizeof(double) << "\n";
cout << "long long: " << sizeof(long long) << "\n";
return 0;
}Output
char: 1 bool: 1 int: 4 float: 4 double: 8 long long: 8
That output is typical for a 64-bit desktop system. Your machine may differ for anything except char, which is always 1.
auto, const and casting
auto asks the compiler to deduce the type from the initialiser, so auto items = 3; is an int and auto price = 250.0; is a double. It shines with long types such as iterators and is fine for obvious cases, but do not use it where it hides what a value is. const marks a value that cannot change after initialisation. Use it generously: it documents intent and lets the compiler catch accidental writes.
When you convert between types on purpose, use static_cast<type>(value). It is more visible and searchable than the old C-style (type)value. The program below shows the integer-division trap, truncation, character arithmetic and why 0.1 + 0.2 is not quite 0.3.
#include <iomanip>
#include <iostream>
using namespace std;
int main() {
const double TAX_RATE = 0.18;
int total = 7;
int count = 2;
cout << total / count << endl;
cout << static_cast<double>(total) / count << endl;
auto price = 250.0;
auto items = 3;
auto bill = price * items * (1 + TAX_RATE);
cout << bill << endl;
cout << static_cast<int>(19.99) << endl;
cout << 'A' + 1 << endl;
cout << static_cast<char>('A' + 1) << endl;
cout << 0.1 + 0.2 << endl;
cout << setprecision(17) << 0.1 + 0.2 << endl;
return 0;
}Output
3 3.5 885 19 66 B 0.3 0.30000000000000004
7 / 2 is 3 because both operands are ints, so C++ performs integer division. Casting just one operand to double fixes it. Casting 19.99 to int truncates toward zero rather than rounding. 'A' + 1 is 66 because arithmetic promotes char to int, so you cast back to see B. Finally, cout shows only 6 significant digits by default, which hides the tiny binary rounding error until you ask for 17 digits. Never compare doubles for exact equality, and avoid them for money.
Common mistakes
- Reading an uninitialised variable.
int total; cout << total;compiles, but the value is garbage. With-Wallyou may seewarning: 'total' is used uninitialized. - Narrowing in brace initialisation.
int x{3.5};fails witherror: narrowing conversion of '3.5' from 'double' to 'int'. With=,int x = 3.5;compiles and silently truncates to3. - Integer division.
double avg = sum / count;with two ints still divides as integers, then converts. Cast one side first. - Forgetting `#include <string>`. Depending on the compiler you get
error: 'string' was not declared in this scopeor'string' does not name a type. - Single quotes versus double quotes.
char c = "A";fails witherror: invalid conversion from 'const char*' to 'char'. Acharuses single quotes and a string uses double. - Comparing doubles with `==`.
0.1 + 0.2 == 0.3isfalse. Compare with a small tolerance, such asabs(a - b) < 1e-9.
How this shows up in interviews and real projects
Expect questions on integer overflow, the difference between const and constants defined with #define, what auto does, and why sizeof(int) is not always 4. In real C++ code, reaching for the right type is also a performance and correctness decision: fixed-width integers for file formats and networking, std::size_t for sizes, and const everywhere it applies. Next up is C++ If-Else, Switch and Loops.
Try it yourself
Write a program that stores a student's three subject marks as ints, computes the average as a double without losing the decimal part, and prints it. Declare the pass mark as a const int and print whether the student passed using boolalpha.
Show a hint
Sum the marks first, then use static_cast<double>(sum) / 3. Compare the average with your const pass mark.
Key takeaways
- Use
int,double,char,boolandstd::stringfor most work, andlong longwhen numbers get large. - Local variables are not zero-initialised, so always give them a value.
- Type sizes depend on the platform; confirm with
sizeofand use fixed-width types when exact size matters. - Use
static_castfor deliberate conversions,constfor values that must not change, andautowhen the type is obvious. - Integer division truncates, doubles carry tiny rounding errors, and signed overflow is undefined behavior.
Test yourself
A trick from this lesson's ride: A fresh local is a room nobody cleaned: old junk is still inside. Four more tricks like it wait along the route, each followed by a question.
Frequently asked questions
What are the basic data types in C++?
The basic types are int, double and float for numbers, char for single characters and bool for true or false. Text is normally stored in std::string, which is a library class rather than a primitive type.
What is the difference between int and long long in C++?
int is usually 4 bytes and holds values up to about 2.1 billion, while long long is at least 64 bits and holds vastly larger numbers. Use long long when values such as totals, IDs or factorials might exceed the int range.
What does auto do in C++?
auto makes the compiler deduce a variable's type from its initial value, so auto x = 5; is an int. The variable is still statically typed, and you must give it an initialiser. It is especially useful for long types such as iterators.