Types & I/O
C — printf / scanf
#include <stdio.h>
#include <stdint.h>
int i = 42; // %d
long l = 42L; // %ld
double d = 3.14; // %f / %g
char c = 'A'; // %c
char s[] = "hi"; // %s
int32_t fixed = 1; // from <stdint.h>
printf("%d %f %s\n", i, d, s);
scanf("%d", &i); // pass address to write
C++ — iostream
#include <iostream>
#include <string>
int n; std::string name;
std::cin >> n >> name;
std::cout << "n=" << n << ' ' << name << '\n';
std::cerr << "error\n"; // stderr
Pointers & References
int x = 10;
int *p = &x; // address-of
*p = 20; // dereference -> x == 20
int *n = nullptr; // C++ null (NULL in C)
int arr[3] = {1,2,3};
int *q = arr; // array decays to pointer
*(q + 2); // 3 (pointer arithmetic)
int (*fn)(int) = □ // function pointer
void *raw = &x; // typeless, cast to use
// C++ reference: alias, non-null, non-rebindable
int &r = x; // r IS x
Memory Management
C — malloc / free
int *buf = malloc(n * sizeof(int));
if (!buf) { /* handle failure */ }
free(buf);
buf = NULL; // avoid dangling
C++ — new / delete
int *one = new int(7); delete one;
int *many = new int[10]; delete[] many; // [] must match
C++ — Smart pointers (prefer these)
#include <memory>
auto u = std::make_unique<T>(args); // exclusive owner
auto s = std::make_shared<T>(args); // refcounted
std::weak_ptr<T> w = s; // non-owning
if (auto sp = w.lock()) { /* use *sp */ }
Structs & Classes
// C struct
struct Point { int x, y; };
struct Point p = {3, 4};
// C++ class
class Counter {
int n_ = 0; // private by default
public:
Counter() = default; // constructor
~Counter() = default; // destructor
void inc() { ++n_; }
int get() const { return n_; } // const method
};
Counter c; c.inc();
Inheritance & Virtual
class Base {
public:
virtual ~Base() = default; // virtual dtor!
virtual int f() const { return 0; }
};
class Derived : public Base {
public:
int f() const override { return 1; } // override keyword
};
Base *b = new Derived();
b->f(); // 1 (dynamic dispatch)
delete b;
Templates
template<class T>
T max_of(T a, T b) { return a > b ? a : b; }
template<class T>
class Box { T v_; public: explicit Box(T v):v_(v){} };
Box<int> bi{1};
max_of<double>(1.5, 2.5);
// C++20 concepts
#include <concepts>
template<std::integral T>
T twice(T x) { return x * 2; }
STL Containers
| Container | Use for | Lookup |
vector<T> | Dynamic array | O(1) index |
map<K,V> | Sorted keys | O(log n) |
unordered_map<K,V> | Hashed keys | avg O(1) |
set<T> | Unique sorted | O(log n) |
std::vector<int> v = {3, 1, 2};
v.push_back(4);
for (int x : v) { /* range-for */ }
std::map<std::string, int> m;
m["a"] = 1;
if (m.count("a")) { /* present */ }
STL Algorithms
#include <algorithm>
#include <numeric>
std::sort(v.begin(), v.end());
std::sort(v.begin(), v.end(), std::greater<>()); // desc
auto it = std::find(v.begin(), v.end(), 2);
int sum = std::accumulate(v.begin(), v.end(), 0);
int cnt = std::count_if(v.begin(), v.end(),
[](int x){ return x > 1; });
Move Semantics
std::vector<int> a = {1,2,3};
auto b = std::move(a); // steal, no copy; a now empty
// rvalue ref parameter
void take(std::string &&s); // binds to temporaries
Exceptions
#include <stdexcept>
try {
throw std::runtime_error("boom");
} catch (const std::exception &e) {
std::cerr << e.what() << '\n';
} catch (...) { /* catch-all */ }
// C style: return codes + errno
#include <errno.h>
if (!fopen("x","r")) perror("fopen");
Compile & Build
# C
gcc -std=c17 -Wall -Wextra app.c -o app
# C++
g++ -std=c++20 -Wall -Wextra app.cpp -o app
# Sanitizers (catch UB / memory bugs)
g++ -std=c++20 -fsanitize=address,undefined app.cpp -o app
# Leak check + debugger
valgrind --leak-check=full ./app
gdb ./app
# CMake
cmake -B build -S . && cmake --build build