C++ Basics: History, Compiler, Hello World & Namespace Masterclass
Welcome to Phase 1 (Chapter 1): C++ Basics Masterclass! C++ is a statically-typed, compiled, multi-paradigm programming language created by Bjarne Stroustrup in 1979 as an extension of C. It combines procedural, object-oriented, generic, and functional programming styles. C++ powers systems software, game engines, compilers, embedded systems, databases, and high-performance applications worldwide.
| Year | Standard | Key Additions |
|---|---|---|
| 1979 | C with Classes | Classes, basic inheritance, Stroustrup at Bell Labs |
| 1985 | C++ 1.0 | Virtual functions, function/operator overloading, references |
| 1998 | C++98 | First ISO standard, STL (vector, map), templates, exceptions |
| 2003 | C++03 | Bug-fix release of C++98 |
| 2011 | C++11 | auto, lambdas, move semantics, smart pointers, range-for, nullptr, threads |
| 2014 | C++14 | Generic lambdas, return type deduction, constexpr relaxation |
| 2017 | C++17 | Structured bindings, if constexpr, std::optional, std::variant, std::filesystem |
| 2020 | C++20 | Concepts, Ranges, Coroutines, Modules, std::format, std::span |
| 2023 | C++23 | std::print, std::generator, std::ranges::to, stacktrace |
| Feature | C | C++ |
|---|---|---|
| Paradigm | Procedural only | Multi-paradigm (OOP, generic, functional) |
| Classes & Objects | No (only structs) | Full OOP with classes, inheritance, polymorphism |
| Function Overloading | No | Yes |
| Templates | No (only macros) | Full generic programming |
| References | No (only pointers) | Yes โ safer than raw pointers |
| Exception Handling | No (only setjmp/longjmp) | try/catch/throw with stack unwinding |
| Namespaces | No | Yes โ prevent name collisions |
| Standard Library | C standard library | C++ STL + C standard library |
| Type Safety | Weaker (void* implicit) | Stronger type system |
| Memory Management | malloc/free (manual) | new/delete + RAII + smart pointers |
| Inline functions | Macros only | inline keyword (type-safe) |
| Bool type | _Bool or int | Native bool |
// Single-line comment โ ignored by compiler
/* Multi-line
comment */
#include <iostream> // Preprocessor: include iostream header (cin, cout, cerr)
#include <string> // std::string
#include <cstdlib> // EXIT_SUCCESS, EXIT_FAILURE
// Namespace: 'main' lives in global namespace
// All standard library things live in std:: namespace
int main() { // Entry point: OS calls main() to start program
// int = return type (exit code: 0 = success)
std::cout // Standard output stream (console)
<< "Hello, World!" // stream insertion operator โ feeds string into cout
<< "
"; // newline (
is faster than std::endl which also flushes)
std::cout << "C++ " << 2024 << " is amazing!
";
// Using 'using' to avoid std:: prefix
using std::cout;
using std::string;
string name = "Bjarne Stroustrup";
cout << "C++ created by: " << name << "
";
// Reading input
cout << "Enter your name: ";
string userName;
std::cin >> userName; // reads one word (stops at whitespace)
cout << "Hello, " << userName << "!
";
// std::endl vs '
'
cout << "Using endl (flushes buffer): " << std::endl; // slower
cout << "Using \n (no flush): " << "
"; // faster
// stderr (unbuffered, for errors)
std::cerr << "This goes to standard error
";
return 0; // Tell OS: success. Use 1 for failure, EXIT_SUCCESS/EXIT_FAILURE
}
#include <iostream>
#include <string>
// Define your own namespace
namespace Math {
const double PI = 3.14159265358979;
double circleArea(double r) { return PI * r * r; }
double circlePerimeter(double r) { return 2 * PI * r; }
// Nested namespace (C++17 shorthand)
namespace Trig {
double degreesToRadians(double deg) { return deg * PI / 180.0; }
}
}
namespace IO {
void printSeparator(int n = 40) {
for (int i = 0; i < n; ++i) std::cout << '-';
std::cout << '
';
}
}
int main() {
// Fully qualified names
std::cout << Math::PI << "
";
std::cout << Math::circleArea(5.0) << "
";
std::cout << Math::Trig::degreesToRadians(90) << "
";
// using declaration โ bring one name into scope
using std::cout;
using std::string;
cout << "cout without std::
";
// using directive โ bring entire namespace into scope (avoid in headers!)
{
using namespace Math;
cout << "PI = " << PI << "
"; // no Math:: needed
cout << "Area(r=3) = " << circleArea(3.0) << "
";
}
// Outside the block, Math:: required again
IO::printSeparator();
cout << "Namespaces help organize code!
";
IO::printSeparator();
return 0;
}
// โโโ mymath.h โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// Traditional include guard
#ifndef MYMATH_H
#define MYMATH_H
// OR modern equivalent (supported by all major compilers):
// #pragma once
namespace MyMath {
double square(double x); // declaration only in header
double cube(double x);
int factorial(int n);
}
#endif // MYMATH_H
// โโโ mymath.cpp โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// #include "mymath.h" // include your header (quotes for local files)
// #include <cmath> // angle brackets for system headers
// namespace MyMath {
// double square(double x) { return x * x; }
// double cube(double x) { return x * x * x; }
// int factorial(int n) { return n <= 1 ? 1 : n * factorial(n-1); }
// }
// โโโ main.cpp โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
#include <iostream>
// #include "mymath.h"
// Common standard headers:
// <iostream> โ cin, cout, cerr
// <string> โ std::string
// <vector> โ std::vector
// <array> โ std::array
// <map> โ std::map
// <set> โ std::set
// <algorithm> โ sort, find, transform, etc.
// <cmath> โ sqrt, pow, sin, cos, etc.
// <cassert> โ assert()
// <limits> โ numeric_limits
// <memory> โ unique_ptr, shared_ptr
// <functional> โ std::function, std::bind
// <thread> โ std::thread
// <mutex> โ std::mutex
int main() {
// MyMath::square(4.0); // would work with the header
std::cout << "Header files organize declarations!
";
return 0;
}
| Error Type | When Detected | Example | Fix |
|---|---|---|---|
| Syntax Error | Compile time (immediately) | cout << "hi" (missing semicolon) | Read compiler message, fix syntax |
| Semantic Error | Compile time | Using undeclared variable | Declare variable, check types |
| Linker Error | Link time | Declared but not defined function | Provide definition in a .cpp file |
| Runtime Error | During execution | Array out-of-bounds, null dereference | Add bounds checking, nullptr checks |
| Logic Error | Wrong output produced | Using + instead of * in formula | Test with expected values, debug |
#include <iostream>
#include <cassert>
// SYNTAX ERROR (uncomment to see compiler error):
// int x = 5 // missing semicolon
// RUNTIME ERROR (undefined behaviour, may crash):
// int arr[5]; arr[10] = 99; // out of bounds
// LOGIC ERROR (compiles, wrong answer):
double badAverage(int a, int b) {
return a + b / 2; // Wrong! Operator precedence: b/2 first, then +a
}
double goodAverage(int a, int b) {
return (a + b) / 2.0; // Correct
}
// Using assert for defensive programming
void processAge(int age) {
assert(age >= 0 && age <= 150 && "Age must be 0-150");
std::cout << "Processing age: " << age << "
";
}
int main() {
std::cout << "badAverage(10, 20) = " << badAverage(10, 20) << "
"; // 20 (WRONG!)
std::cout << "goodAverage(10, 20) = " << goodAverage(10, 20) << "
"; // 15 (correct)
processAge(25); // OK
// processAge(-5); // ASSERT FAILS โ catches logic error at runtime
return 0;
}
Q1: What is the difference between cout and printf?
std::cout is the C++ stream โ type-safe, extensible for user-defined types, operator-based. printf (from C's <cstdio>) uses format strings โ fast but not type-safe (wrong format spec = UB). Use std::format (C++20) for formatted output.
Q2: Why return 0 from main?
The return value of main() is the program's exit code. 0 means success by convention. Non-zero means failure. The OS/shell can check this. In main() only, returning 0 is implicit (compiler adds it if you don't).
Q3: What is the difference between #include "file" and #include <file>?
Angle brackets (<>) search system/compiler include directories first โ for standard and third-party headers. Quotes ("") search the current source file's directory first โ for your own headers. Quotes fall back to angle bracket search if not found locally.
Q4: What does using namespace std; do? Is it bad?
It imports all names from the std namespace into the current scope. Convenient for small programs. Avoid in header files โ it pollutes every file that includes that header and can cause name collisions (e.g., your function named sort conflicts with std::sort).
Q5: What is std::endl vs " "?
std::endl inserts newline AND flushes the output buffer (forces immediate write to console). "
" inserts newline but doesn't flush. For performance-critical code, use "
" โ avoid endl in loops.