⚙️ C++

Voici la traduction de l'article du russe vers le français, en respectant toutes les règles spécifiées :

What is it and why? (real-life analogy)

Imagine you are a PE teacher and you have a list of students in a class. This list is an array (or collection). In programming, arrays and collections are containers that store many elements of the same type (e.g., numbers, strings, objects).

But simply storing data is not enough. You need to be able to work with it: find the tallest student, calculate the average height, add a new student, remove someone who transferred to another school, sort everyone alphabetically. This is exactly what array and collection methods are for — ready-made tools that do all the routine work for you.

Analogy: Imagine an array is a box of colorful blocks. Methods are your hands: you can pick up a block (access by index), put a new one in (add), throw an old one out (delete), rearrange all the blocks by color (sort), or count how many are red (search). Without methods, you would have to write complex instructions for your hands every time — but with them, everything is simple and fast.

In C++, there are two main types of containers: static arrays (fixed size, like an old cabinet — as many shelves as there are, that's it) and dynamic collections (e.g., std::vector — like an elastic backpack that stretches when you put new things in it).

Why do you need to know this? Because 90% of programs work with data sets: a list of users, game results, temperature for a week, coordinates of points on a map. Being able to manage these sets is a fundamental programming skill.

Theory: how it works internally

Let's look "under the hood" and understand how arrays and collections work in C++.

Static array (C-style array)

This is the simplest type. You allocate memory on the stack (fast memory, but limited) and say: "Here are 10 cells for integers." The size is fixed forever. Internally, it's just a contiguous block of memory. To get element #3, the computer takes the starting address of the array and adds 3 * sizeof(int) bytes. It's very fast, but inflexible.

int scores[5] = {10, 20, 30, 40, 50}; // 5 cells, no more, no less
// scores[0] = 10, scores[4] = 50
// scores[5] — already an error, going out of bounds!

std::vector (dynamic array)

This is a "smart" array from the C++ standard library. It stores data on the heap (slower, but larger memory). When you add an element and there's no space, the vector automatically allocates a new memory block twice as large, copies all the old elements there, and deletes the old block. This is called reallocation.

Important: Reallocation is an expensive operation. If you know there will be many elements, it's better to reserve space in advance using reserve().

Other collections (std::list, std::set, std::map)

  • std::list — doubly linked list. Each element stores pointers to the next and previous ones. Fast to insert/delete in the middle, but slow to search (you have to traverse the chain).
  • std::set — a set. Stores unique elements in sorted order. Internally, it's a red-black tree. Fast search, but you cannot change an element (only delete and add a new one).
  • std::map — a dictionary. Key-value pairs. Also a tree. Ideal for searching by key.

All collections support iterators — special objects that "walk" through elements, like a cursor in text. This is a universal way to iterate.

Syntax in C++: all forms and variants

Let's go over the main methods using std::vector as an example — the most popular collection. I'll show the syntax, and you remember it.

Inclusion and creation

#include <vector>  // must include the library
#include <iostream>
#include <algorithm> // for sort, find and other algorithms

int main() {
    // Empty vector
    std::vector<int> numbers;
    
    // Vector with 5 zeros
    std::vector<int> zeros(5);
    
    // Vector with 5 tens
    std::vector<int> tens(5, 10);
    
    // Vector from initializer list
    std::vector<int> values = {1, 2, 3, 4, 5};
    
    return 0;
}

Main methods (reference table)

Method What it does Example Complexity
push_back(value) Adds an element to the end vec.push_back(42); O(1) average
pop_back() Removes the last element vec.pop_back(); O(1)
size() Returns the number of elements int n = vec.size(); O(1)
empty() Checks if the vector is empty if (vec.empty()) O(1)
clear() Removes all elements vec.clear(); O(n)
at(index) Access element with bounds checking vec.at(2) = 100; O(1)
operator[] Access without checking (faster, but more dangerous) vec[2] = 100; O(1)
front() First element int first = vec.front(); O(1)
back() Last element int last = vec.back(); O(1)