C++ Basics

Program Structure

Minimal C++ program
#include <iostream>
#include <string>

int main(int argc, char* argv[]) {
    std::cout << "hello, world" << std::endl;
    return 0;
}

#include is a preprocessor directive — it copies the header file’s contents into the source. main returns int to the OS. std::cout is the standard output stream.

Variables and Types

Fundamental types and modern declarations
// Fundamental types
int count = 42;
double pi = 3.14159;
bool active = true;
char letter = 'A';

// Modern C++ — auto type inference
auto name = std::string("Evan");
auto ratio = 3.14;  // double
auto port = 8080;   // int

// const and constexpr
const int MAX_RETRIES = 3;           // runtime constant
constexpr int BUFFER_SIZE = 1024;     // compile-time constant

// References
int x = 10;
int& ref = x;   // ref IS x — another name for the same memory
ref = 20;
std::cout << x;  // 20

auto deduces type from the initializer. const is a runtime promise not to modify. constexpr is a compile-time guarantee.

Strings

std::string vs C strings
#include <string>

std::string name = "Evan";
std::string greeting = "Hello, " + name;  // concatenation

// Common operations
name.length();        // 4
name.substr(0, 2);    // "Ev"
name.find("an");      // 2
name.empty();         // false
name.append("!");     // "Evan!"

// C string conversion
const char* cstr = name.c_str();

// String formatting (C++20)
auto msg = std::format("Host: {} Port: {}", "sw01", 22);

Always prefer std::string over C-style char*. c_str() gives you a null-terminated pointer when you need to interface with C APIs.

Control Flow

if, switch, for, while
// if with init statement (C++17)
if (auto it = map.find("key"); it != map.end()) {
    std::cout << it->second << std::endl;
}

// Range-based for loop (C++11)
std::vector<int> nums = {1, 2, 3, 4, 5};
for (const auto& n : nums) {
    std::cout << n << " ";
}

// Structured bindings (C++17)
std::map<std::string, int> ports = {{"ssh", 22}, {"http", 80}};
for (const auto& [name, port] : ports) {
    std::cout << name << ": " << port << std::endl;
}

Structured bindings (auto& [k, v]) decompose pairs, tuples, and structs. Range-based for avoids index errors.

Input/Output

iostream and formatting
#include <iostream>
#include <iomanip>

// Output
std::cout << "Name: " << name << ", Port: " << port << std::endl;

// Input
std::string input;
std::cout << "Enter host: ";
std::getline(std::cin, input);

// Formatting
std::cout << std::fixed << std::setprecision(2) << 3.14159 << std::endl;
// 3.14

// printf-style (still valid, often cleaner)
printf("Host: %s Port: %d\n", name.c_str(), port);

std::endl flushes the buffer (slow). Use "\n" when you do not need an immediate flush.