3.0 What This Teaches
C++ is statically typed: every variable has a type fixed at compile time. This
tutorial covers:
- Fundamental types:
int, double, char, bool
- The three initialization syntaxes and why brace-initialization is preferred
const and constexpr
auto type deduction
- Explicit type conversions with
static_cast
3.1 Fundamental Types
| Type | Size | Example |
| int | 4 bytes | -2 147 483 648 to 2 147 483 647 |
| long long | 8 bytes | very large integers |
| double | 8 bytes | 64-bit floating point |
| float | 4 bytes | 32-bit floating point |
| char | 1 byte | single character or small integer |
| bool | 1 byte | true or false |
| std::string | varies | heap-managed text (not a primitive) |
Use int for integers and double for floating point
by default. Switch to long long or float only when
size or performance matters.
3.2 Initialization Syntax
int a = 5; // copy initialization
int b(5); // direct initialization
int c{5}; // uniform (brace) initialization - preferred
All three produce the same value here. Brace initialization is preferred in
modern C++ because it catches narrowing conversions at compile time:
int bad{3.7}; // error: narrowing conversion from double to int
int ok = 3.7; // silently truncates to 3
3.3 const and constexpr
const int MAX_SIZE = 100; // runtime constant; cannot be modified
constexpr double PI = 3.14159265; // compile-time constant; evaluated by compiler
const prevents modification after initialization - the value may
still come from a runtime expression. constexpr requires the
value to be known at compile time and is usable in array sizes, template
arguments, and other compile-time contexts.
int n = 5;
const int size = n; // ok: const from runtime value
// constexpr int s = n; // error: n is not a compile-time constant
constexpr int s = 5; // ok
3.4 auto Type Deduction
auto x = 42; // int
auto y = 3.14; // double
auto name = std::string("Alice"); // std::string
auto flag = true; // bool
auto asks the compiler to infer the type from the initializer.
It requires an initializer - auto z; is an error. Use it to avoid
writing long type names, especially with iterators and lambdas.
3.5 Type Conversions
double pi = 3.14159;
int truncated = static_cast<int>(pi); // 3 - explicit, visible in code
int count = 7;
double ratio = static_cast<double>(count) / 10; // 0.7, not 0
Prefer static_cast over C-style casts like (int)pi.
static_cast is checked at compile time and shows up clearly in
code review.
3.6 Example - All Together
// Variables - types, initialization, const, constexpr, and auto.
#include <iostream>
#include <string>
int main() {
// --- fundamental types ---
int count = 10;
double ratio = 3.14159;
char letter = 'A';
bool flag = true;
std::cout << count << " " << ratio << " " << letter << " " << flag << "\n";
// --- brace initialization ---
int a{5}, b{10};
std::cout << a + b << "\n";
// --- const and constexpr ---
const int MAX_SIZE = 100;
constexpr double PI = 3.14159265;
std::cout << MAX_SIZE << " " << PI << "\n";
// --- auto ---
auto name = std::string("Alice");
auto x = 42;
std::cout << name << " " << x << "\n";
// --- cast ---
int truncated = static_cast<int>(3.7);
std::cout << truncated << "\n";
return 0;
}
10 3.14159 A 1
15
100 3.14159
Alice 42
3
3.7 Exercise
Exercise
- Declare a
constexpr double GRAVITY = 9.81 and use it to
compute the kinetic energy of a 2 kg object falling 10 m
(KE = mass * g * height). Print the result.
- Try initializing
int bad{3.7}; and observe the compiler
error. Then fix it with static_cast.
- Use
auto for all variable types in a small program that
reads two integers and prints their sum. Hover over the variables in your
IDE to confirm the deduced types.
3.8 Common Mistakes
Integer division
int a = 7, b = 2;
double result = a / b; // 3.0, not 3.5 - division happens before assignment
double fixed = static_cast<double>(a) / b; // 3.5
When both operands are int, / truncates. Cast at
least one operand to double first.
Uninitialized variables
int x;
std::cout << x; // undefined behavior: x has garbage value
Always initialize variables. Brace initialization to zero:
int x{}; initializes to 0.
Forgetting const
If a value should not change, declare it const. It documents
intent and lets the compiler catch accidental mutations.
3.9 Key Terms
| Term | Meaning |
| int | 32-bit signed integer type |
| double | 64-bit floating-point type |
| bool | Boolean type: true or false |
| const | Prevents modification after initialization |
| constexpr | Value must be computable at compile time |
| auto | Type deduced from the initializer |
| static_cast<T>(x) | Explicit type conversion checked at compile time |
| narrowing conversion | Converting to a type that cannot represent all values of the source type |