ШПАРГАЛКА

C++

Шпаргалка по C++: структура программы, ввод-вывод, типы, строки, векторы, циклы, функции, указатели, ООП, STL, алгоритмы, шаблоны и умные указатели.

C++ — компилируемый язык общего назначения с поддержкой процедурного, объектно-ориентированного и обобщённого программирования. Эта шпаргалка собирает базовый синтаксис современного C++ (стандарт C++11 и новее): от структуры программы до STL, шаблонов и умных указателей. Все примеры рабочие — их можно скомпилировать командой g++ -std=c++17 file.cpp -o app.

Структура программы

Любая программа на C++ начинается с подключения заголовочных файлов через #include и содержит функцию main() — точку входа. Директива using namespace std; позволяет не писать префикс std:: перед именами из стандартной библиотеки.

#include <iostream>   // подключаем библиотеку ввода-вывода
using namespace std;   // чтобы не писать std:: каждый раз

int main() {
    cout << "Привет, мир!" << endl;
    return 0;          // 0 — программа завершилась успешно
}
// Вывод: Привет, мир!

Без using namespace std; к именам обращаются через std:: — это считается более чистым стилем в больших проектах.

#include <iostream>

int main() {
    std::cout << "Без using" << std::endl;
    return 0;
}
// Вывод: Без using

Ввод и вывод

Поток cout с оператором << выводит данные, поток cin с оператором >> читает их. Оператор >> читает до пробела, поэтому для строк с пробелами используют getline.

#include <iostream>
#include <string>
using namespace std;

int main() {
    int age;
    cout << "Возраст: ";
    cin >> age;                  // читаем число
    cout << "Вам " << age << " лет" << endl;
    return 0;
}
// Ввод: 25
// Вывод: Вам 25 лет

getline читает всю строку целиком, включая пробелы, до символа перевода строки.

#include <iostream>
#include <string>
using namespace std;

int main() {
    string name;
    cout << "Имя: ";
    getline(cin, name);         // читаем строку с пробелами
    cout << "Привет, " << name << "!" << endl;
    return 0;
}
// Ввод: Иван Петров
// Вывод: Привет, Иван Петров!

Переменные и типы

C++ — статически типизированный язык: тип переменной указывается при объявлении. Основные типы: int, double, char, bool. Ключевое слово auto позволяет компилятору вывести тип автоматически, а const объявляет неизменяемое значение.

#include <iostream>
using namespace std;

int main() {
    int count = 10;             // целое число
    double price = 99.9;        // число с плавающей точкой
    char grade = 'A';           // один символ
    bool isReady = true;        // логический тип
    const double PI = 3.14159;  // константа
    auto sum = count + 5;       // тип выведен: int

    cout << count << " " << price << " " << grade << " " << isReady << endl;
    cout << "sum = " << sum << ", PI = " << PI << endl;
    return 0;
}
// Вывод: 10 99.9 A 1
// sum = 15, PI = 3.14159

Таблица основных типов:

ТипОписаниеПример значения
intцелое число42, -7
doubleдробное число3.14, -0.5
charодин символ'A', '9'
boolистина/ложьtrue, false
std::stringстрока"привет"

Строки

Тип std::string из заголовка <string> — это удобная обёртка над массивом символов. Строки можно складывать оператором +, измерять методом size() и обращаться к символам по индексу.

#include <iostream>
#include <string>
using namespace std;

int main() {
    string a = "Hello";
    string b = "World";
    string c = a + ", " + b;    // конкатенация

    cout << c << endl;            // Hello, World
    cout << "Длина: " << c.size() << endl;     // 12
    cout << "Первый символ: " << c[0] << endl;  // H
    return 0;
}
// Вывод: Hello, World
// Длина: 12
// Первый символ: H

Полезные методы строк:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "программирование";

    cout << s.substr(0, 5) << endl;         // програ — подстрока
    cout << s.find("рам") << endl;           // позиция вхождения
    cout << (s.empty() ? "пусто" : "есть") << endl;
    s.append("!");                          // добавить в конец
    cout << s << endl;
    return 0;
}
// substr возвращает первые 5 символов
// find возвращает индекс подстроки

Массивы и векторы

Классический массив C++ имеет фиксированный размер. В современном C++ предпочитают std::vector — динамический массив, который умеет менять размер во время работы программы.

#include <iostream>
using namespace std;

int main() {
    int arr[3] = {10, 20, 30};  // массив фиксированного размера

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    return 0;
}
// Вывод: 10 20 30

std::vector<int> — динамический массив из заголовка <vector>. Элементы добавляют методом push_back, размер узнают через size().

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> nums = {1, 2, 3};
    nums.push_back(4);          // добавить элемент
    nums.push_back(5);

    cout << "Размер: " << nums.size() << endl;
    for (int x : nums) {        // range-based for
        cout << x << " ";
    }
    cout << endl;
    return 0;
}
// Вывод: Размер: 5
// 1 2 3 4 5

Операторы

C++ поддерживает арифметические, сравнения и логические операторы. Деление целых чисел отбрасывает дробную часть, а оператор % возвращает остаток.

#include <iostream>
using namespace std;

int main() {
    int a = 17, b = 5;
    cout << a + b << endl;   // 22
    cout << a / b << endl;   // 3  (целочисленное деление)
    cout << a % b << endl;   // 2  (остаток)

    bool x = (a > b) && (b > 0);  // логическое И
    bool y = (a < b) || (b > 0);  // логическое ИЛИ
    cout << x << " " << y << endl;  // 1 1
    return 0;
}
// Вывод: 22
// 3
// 2
// 1 1

Условия: if и switch

Конструкция if / else if / else выбирает ветку по логическому условию.

#include <iostream>
using namespace std;

int main() {
    int score = 75;

    if (score >= 90) {
        cout << "Отлично" << endl;
    } else if (score >= 60) {
        cout << "Хорошо" << endl;
    } else {
        cout << "Нужно повторить" << endl;
    }
    return 0;
}
// Вывод: Хорошо

Оператор switch удобен для выбора по конкретным значениям. Не забывайте break, иначе выполнение «провалится» в следующий case.

#include <iostream>
using namespace std;

int main() {
    int day = 3;
    switch (day) {
        case 1: cout << "Понедельник"; break;
        case 3: cout << "Среда"; break;
        default: cout << "Другой день";
    }
    cout << endl;
    return 0;
}
// Вывод: Среда

Циклы

Цикл for с тремя частями (инициализация; условие; шаг) удобен для счётчиков.

#include <iostream>
using namespace std;

int main() {
    for (int i = 1; i <= 5; i++) {
        cout << i << " ";
    }
    cout << endl;
    return 0;
}
// Вывод: 1 2 3 4 5

Range-based for (C++11) перебирает элементы коллекции без индексов. Ссылка & позволяет менять элементы на месте.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v = {2, 4, 6};
    for (int& x : v) {       // ссылка — меняем оригинал
        x *= 10;
    }
    for (int x : v) cout << x << " ";
    cout << endl;
    return 0;
}
// Вывод: 20 40 60

Цикл while повторяется, пока условие истинно.

#include <iostream>
using namespace std;

int main() {
    int n = 8;
    while (n > 1) {
        cout << n << " ";
        n /= 2;
    }
    cout << endl;
    return 0;
}
// Вывод: 8 4 2

Функции

Функция объявляется с типом возвращаемого значения, именем и списком параметров. По умолчанию аргументы передаются по значению — функция работает с копией.

#include <iostream>
using namespace std;

int square(int x) {          // передача по значению
    return x * x;
}

int main() {
    cout << square(6) << endl; // 36
    return 0;
}
// Вывод: 36

Передача по ссылке через & позволяет функции изменить оригинальную переменную без копирования.

#include <iostream>
using namespace std;

void doubleIt(int& x) {       // ссылка — меняем оригинал
    x *= 2;
}

int main() {
    int a = 5;
    doubleIt(a);
    cout << a << endl;         // 10
    return 0;
}
// Вывод: 10

Перегрузка: несколько функций с одним именем, но разными параметрами. Компилятор выбирает нужную по типам аргументов.

#include <iostream>
using namespace std;

int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }

int main() {
    cout << add(2, 3) << endl;       // 5  (int)
    cout << add(2.5, 3.1) << endl;   // 5.6 (double)
    return 0;
}
// Вывод: 5
// 5.6

Указатели и ссылки

Указатель хранит адрес переменной. Оператор & берёт адрес, оператор * разыменовывает указатель (получает значение по адресу). Ссылка — это псевдоним существующей переменной.

#include <iostream>
using namespace std;

int main() {
    int value = 42;
    int* ptr = &value;       // указатель на value
    int& ref = value;        // ссылка на value

    cout << *ptr << endl;     // 42 — значение по адресу
    *ptr = 100;              // меняем через указатель
    cout << value << endl;    // 100
    ref = 7;                 // меняем через ссылку
    cout << value << endl;    // 7
    return 0;
}
// Вывод: 42
// 100
// 7

Главное отличие: указатель можно перенаправить на другой объект или сделать nullptr, а ссылка привязана к одной переменной навсегда.

ООП: классы и структуры

class объединяет данные и методы. По умолчанию члены класса private (скрыты), а public делает их доступными извне. Конструктор инициализирует объект при создании.

#include <iostream>
#include <string>
using namespace std;

class Person {
private:
    string name;
    int age;
public:
    Person(string n, int a) {   // конструктор
        name = n;
        age = a;
    }
    void greet() {
        cout << "Я " << name << ", мне " << age << endl;
    }
};

int main() {
    Person p("Анна", 30);
    p.greet();
    return 0;
}
// Вывод: Я Анна, мне 30

struct работает почти как класс, но по умолчанию все члены public — удобно для простых контейнеров данных.

#include <iostream>
using namespace std;

struct Point {
    int x;
    int y;
};

int main() {
    Point p = {3, 4};
    cout << p.x << ", " << p.y << endl;
    return 0;
}
// Вывод: 3, 4

Наследование и виртуальные методы: производный класс наследует базовый, а virtual обеспечивает полиморфизм — вызов нужной версии метода по реальному типу объекта.

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void sound() {      // виртуальный метод
        cout << "..." << endl;
    }
};

class Dog : public Animal {     // наследование
public:
    void sound() override {
        cout << "Гав!" << endl;
    }
};

int main() {
    Animal* a = new Dog();
    a->sound();                  // Гав! — выбран метод Dog
    delete a;
    return 0;
}
// Вывод: Гав!

STL: контейнеры

Standard Template Library предоставляет готовые контейнеры. std::vector<int> — динамический массив, std::map<K,V> — ассоциативный массив (ключ-значение), std::set<T> — множество уникальных значений.

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main() {
    map<string, int> ages;
    ages["Иван"] = 25;          // ключ -> значение
    ages["Мария"] = 30;

    for (auto& pair : ages) {
        cout << pair.first << ": " << pair.second << endl;
    }
    return 0;
}
// Вывод: Иван: 25
// Мария: 30  (отсортировано по ключу)

std::set<int> хранит только уникальные элементы в отсортированном порядке.

#include <iostream>
#include <set>
using namespace std;

int main() {
    set<int> nums;
    nums.insert(5);
    nums.insert(2);
    nums.insert(5);             // дубликат игнорируется

    for (int x : nums) cout << x << " ";
    cout << endl;
    cout << "Есть 2? " << (nums.count(2) ? "да" : "нет") << endl;
    return 0;
}
// Вывод: 2 5
// Есть 2? да

Краткий обзор контейнеров:

КонтейнерНазначениеЗаголовок
vectorдинамический массив<vector>
mapпары ключ-значение (отсортированы)<map>
setуникальные значения<set>
stringстрока символов<string>

Алгоритмы STL

Заголовок <algorithm> содержит готовые функции для работы с диапазонами. sort сортирует, find ищет элемент.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {5, 2, 8, 1, 9};
    sort(v.begin(), v.end());   // по возрастанию

    for (int x : v) cout << x << " ";
    cout << endl;
    return 0;
}
// Вывод: 1 2 5 8 9

find возвращает итератор; если элемент не найден — это end().

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {10, 20, 30};
    auto it = find(v.begin(), v.end(), 20);

    if (it != v.end()) {
        cout << "Найдено на позиции " << (it - v.begin()) << endl;
    } else {
        cout << "Не найдено" << endl;
    }
    return 0;
}
// Вывод: Найдено на позиции 1

Шаблоны (templates)

Шаблоны позволяют писать обобщённый код, работающий с любым типом. Компилятор сам подставляет конкретный тип при вызове.

#include <iostream>
#include <string>
using namespace std;

template <typename T>
T getMax(T a, T b) {         // работает с любым типом
    return (a > b) ? a : b;
}

int main() {
    cout << getMax(3, 7) << endl;            // 7
    cout << getMax(4.5, 1.2) << endl;        // 4.5
    cout << getMax(string("abc"), string("xyz")) << endl; // xyz
    return 0;
}
// Вывод: 7
// 4.5
// xyz

Именно на шаблонах построена вся STL — vector<int>, vector<string> и map<string,int> это разные подстановки одного шаблона.

Умные указатели

Умные указатели из <memory> автоматически освобождают память — не нужно вручную вызывать delete. unique_ptr владеет объектом единолично, shared_ptr разделяет владение через счётчик ссылок.

#include <iostream>
#include <memory>
using namespace std;

int main() {
    unique_ptr<int> p = make_unique<int>(42);
    cout << *p << endl;       // 42
    *p = 100;
    cout << *p << endl;       // 100
    // память освободится автоматически при выходе из main
    return 0;
}
// Вывод: 42
// 100

shared_ptr ведёт счётчик: память освобождается, когда последний владелец уничтожен.

#include <iostream>
#include <memory>
using namespace std;

int main() {
    shared_ptr<int> a = make_shared<int>(5);
    shared_ptr<int> b = a;   // оба указывают на одно значение

    cout << *a << " " << *b << endl;          // 5 5
    cout << "Владельцев: " << a.use_count() << endl; // 2
    return 0;
}
// Вывод: 5 5
// Владельцев: 2

Совет: в современном C++ предпочитайте умные указатели «голым» new/delete — это избавляет от утечек памяти.

Поддержать проект