
- Главная
- Каталог
- Интернет технологии
- C/C++ | Вопросы собесов
C/C++ | Вопросы собесов
Разбираем вопросы с собеседований на С/С++ разработчика
Статистика канала
Полная статистикаchevron_rightstd::vector использует динамическую память, выделяемую в куче (heap). Его размер может изменяться во время выполнения.
std::array использует статическую память, выделяемую в стеке (stack) или в статической области памяти, и его размер фиксирован на этапе компиляции.
#include <vector>
#include <array>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3}; // Размер может изменяться динамически
vec.push_back(4); // Добавляем новый элемент
std::array<int, 3> arr = {1, 2, 3}; // Размер фиксирован, нельзя добавить новый элемент
std::cout << "Vector size: " << vec.size() << std::endl; // Выведет 4
std::cout << "Array size: " << arr.size() << std::endl; // Выведет 3
return 0;
}{}
std::vector позволяет изменять размер в процессе работы, автоматически выделяя новую память при необходимости.
std::array имеет фиксированный размер, который нельзя изменить после создания.
std::vector<int> v = {1, 2, 3};
v.push_back(4); // Увеличиваем размер
std::array<int, 3> a = {1, 2, 3};
// a.push_back(4); // Ошибка! У std::array нет метода push_back{}
std::array работает быстрее, так как все данные хранятся в непрерывном участке памяти и нет затрат на динамическое выделение.
std::vector может требовать дополнительное время при изменении размера, так как может потребоваться новое выделение памяти и копирование элементов.
#include <vector>
#include <array>
#include <chrono>
#include <iostream>
int main() {
constexpr int N = 1'000'000;
std::vector<int> vec(N, 1); // Динамический массив
std::array<int, N> arr{}; // Статический массив
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) vec[i] += 1;
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Vector time: "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
<< " us" << std::endl;
start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; ++i) arr[i] += 1;
end = std::chrono::high_resolution_clock::now();
std::cout << "Array time: "
<< std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
<< " us" << std::endl;
return 0;
}{}
std::array хранит данные как обычный C-массив, поэтому можно легко передавать его в функции, ожидающие int*.
std::vector использует динамическую память, но можно получить указатель на внутренний буфер с помощью data().
void processArray(int* arr, size_t size) {
for (size_t i = 0; i < size; ++i) {
std::cout << arr[i] << " ";
}
}
int main() {
std::array<int, 3> arr = {1, 2, 3};
std::vector<int> vec = {4, 5, 6};
processArray(arr.data(), arr.size()); // std::array можно передавать в C-функции
processArray(vec.data(), vec.size()); // std::vector тоже можно передавать
return 0;
}{}
#include <algorithm>
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5};
std::array<int, 5> arr = {3, 1, 4, 1, 5};
std::sort(vec.begin(), vec.end());
std::sort(arr.begin(), arr.end());
for (int n : vec) std::cout << n << " "; // 1 1 3 4 5
std::cout << std::endl;
for (int n : arr) std::cout << n << " "; // 1 1 3 4 5
return 0;
}{}
Ставь 👍 и забирай 📚 Базу знаний
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
std::swap(arr[j], arr[j + 1]);
}
}
}
}{}
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}
std::swap(arr[i], arr[minIdx]);
}
}{}
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}{}
void merge(int arr[], int l, int m, int r) {
int n1 = m - l + 1, n2 = r - m;
int L[n1], R[n2];
for (int i = 0; i < n1; i++) L[i] = arr[l + i];
for (int i = 0; i < n2; i++) R[i] = arr[m + 1 + i];
int i = 0, j = 0, k = l;
while (i < n1 && j < n2) arr[k++] = (L[i] < R[j]) ? L[i++] : R[j++];
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
}
void mergeSort(int arr[], int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}{}
Ставь 👍 и забирай 📚 Базу знаний
#include <iostream>
class A {
public:
void show() {
std::cout << "Class A" << std::endl;
}
};
class B : public A {};
class C : public A {};
class D : public B, public C {};
int main() {
D obj;
// obj.show(); // Ошибка: неоднозначность, show() есть и в B, и в C
return 0;
}{}
virtual при наследовании.
#include <iostream>
class A {
public:
void show() {
std::cout << "Class A" << std::endl;
}
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
int main() {
D obj;
obj.show(); // Корректно: вызов метода show() из A
return 0;
}{}
#include <iostream>
class A {
public:
A() {
std::cout << "Constructor of A" << std::endl;
}
};
class B : virtual public A {
public:
B() {
std::cout << "Constructor of B" << std::endl;
}
};
class C : virtual public A {
public:
C() {
std::cout << "Constructor of C" << std::endl;
}
};
class D : public B, public C {
public:
D() {
std::cout << "Constructor of D" << std::endl;
}
};
int main() {
D obj; // Вывод: Constructor of A, Constructor of B, Constructor of C, Constructor of D
return 0;
}{}
Ставь 👍 и забирай 📚 Базу знанийstd::map реализован как самобалансирующееся красно-чёрное дерево (Red-Black Tree).
Вставка (insert)
Поиск (find)
Удаление (erase)
выполняются за O(log n) в худшем и среднем случае.
Однако std::map не имеет амортизированной O(1) сложности, как std::unordered_map.
Амортизированная сложность O(1) появляется в std::unordered_map, но не в std::map!
insert, erase) перестраивает дерево так, чтобы его высота оставалась O(log n). Это достигается с помощью поворотов (rotate left, rotate right) и перекраски узлов.
Вставка нового элемента иногда требует перестройки дерева, но в среднем это занимает O(log n).
10
/ \
5 20{}
std::unordered_map используется хеш-таблица, где:
Операции insert, find, erase – O(1) в среднем (поиск по хешу).
Но если возникает коллизия (несколько ключей в одном бакете), сложность ухудшается до O(n).
Чтобы избежать O(n), std::unordered_map использует rehash (перехеширование).
При увеличении элементов контейнер расширяет бакеты.
Операции разделяются по разным вызовам → за счёт этого амортизированная сложность O(1).
Ставь 👍 и забирай 📚 Базу знаний= в C++ принято возвращать ссылку на текущий объект (*this). Это позволяет цепочечное присваивание (a = b = c), а также улучшает производительность и удобство использования.
class MyClass {
public:
MyClass& operator=(const MyClass& other) {
if (this != &other) { // Защита от самоприсваивания
// Копируем данные
}
return *this; // Возвращаем ссылку на текущий объект
}
};{}
a = b = c)
a = b = c; // Интерпретируется как a = (b = c);{}
Пример
#include <iostream>
class MyClass {
public:
int value;
MyClass(int v) : value(v) {}
MyClass& operator=(const MyClass& other) {
if (this != &other) { // Защита от самоприсваивания
value = other.value;
}
return *this;
}
};
int main() {
MyClass a(1), b(2), c(3);
a = b = c; // Работает, потому что `b = c` возвращает ссылку на `b`
std::cout << "a: " << a.value << ", b: " << b.value << ", c: " << c.value << std::endl;
}{}
Вывод
a: 3, b: 3, c: 3{}
= вернёт не ссылку, а объект, то произойдёт лишнее копирование.
Плохо (возвращаем объект, а не ссылку)
MyClass operator=(const MyClass& other) { // ⚠️ Ошибка: возвращаем объект
value = other.value;
return *this; // Здесь создаётся временный объект (лишняя копия!)
}{}
Хорошо (возвращаем T&)
MyClass& operator=(const MyClass& other) { // ✅ Возвращаем ссылку
value = other.value;
return *this;
}{}
= вернёт ссылку, мы можем использовать его в условии:
if ((a = b).value == 42) { // ОК
std::cout << "Присваивание выполнено, a == 42";
}{}
= вернёт void, цепочка a = b = c; не будет работать.
class MyClass {
public:
void operator=(const MyClass& other) { // ⚠️ Ошибка!
value = other.value;
}
};
int main() {
MyClass a, b, c;
a = b = c; // ❌ Ошибка: `b = c` возвращает void, а `a = void` не работает!
}{}
Ставь 👍 и забирай 📚 Базу знанийОтзывы канала
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
C/C++ | Вопросы собесов — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 4.3K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 5.2, количество отзывов – 1, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 4055.94 ₽, а за 3 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий