Основы программирования на C++: составные типы данных, ссылки и указатели
Прежде чем читать мою статью - реши для себя, зачем ты это делаешь. Даже если ты просто нормальный человек, лишним не будет.
Если вы настоящий профессионал программирования, то зачем вы тут сидите и читайте статью на пикабу? Если вы ради интереса зашли почитать, то претензий ноль, но если вы просто захотели задушить нового пользователя Пикабу минусами, то немедленно покиньте статью, вам однозначно интересно не будет.
Сегодня мы разберем базовые концепции C++, которые помогут вам писать эффективный и читаемый код. Мы рассмотрим:
Составные типы данных : перечисления, структуры, кортежи и пары.
Ссылки и указатели : как они работают и зачем нужны.
Константность : как использовать const для создания надежного кода.
Дополнительные темы : динамическая память, умные указатели и практические советы.
1. Составные типы данных
Перечисления
Перечисления (enum) позволяют определять ограниченный набор именованных констант. Это удобно, когда нужно работать с фиксированным набором значений, например, цветами или состояниями объекта.
enum class Color {
White,
Red,
Orange,
Blue,
};
Теперь вы можете использовать эти значения через префикс Color:::
Color color = Color::Red;
По умолчанию значения перечислений хранятся как целые числа, начиная с нуля. Их можно преобразовать в числа и обратно с помощью static_cast:
int value = static_cast<int>(color); // Преобразование в число
Color color2 = static_cast<Color>(2); // Преобразование обратно
Структуры
Структуры позволяют объединять несколько переменных под одним именем. Например, если вы работаете с точками в трехмерном пространстве, можно создать структуру:
struct Point {
double x = 0.0;
double y = 0.0;
double z = 0.0;
Color color; // Цвет точки
};
Инициализировать структуру можно несколькими способами:
Point point1 = {1.4, -2.2, -3.98, Color::Red};
Point point2 = {.x = 1.4, .y = -2.2}; // C++20 и выше
Кортежи и пары
Для хранения нескольких значений можно использовать std::pair или std::tuple:
#include <tuple>
std::tuple<int, double, Color> t = {42, 3.14, Color::Orange};
std::cout << std::get<0>(t); // Выведет 42
Выравнивание данных
Размер структуры может быть больше, чем сумма размеров её полей, из-за выравнивания данных . Например:
struct Point {
double x; // 8 байт
double y; // 8 байт
double z; // 8 байт
int color; // 4 байта
};
Размер этой структуры будет 32 байта, а не 28, потому что компилятор добавляет "пустые" байты для выравнивания.
2. Ссылки и указатели
Ссылки
Ссылка — это псевдоним для существующей переменной. Она должна быть инициализирована при объявлении:
int x = 42;
int& ref = x; // Теперь ref — это другое имя для x
ref = 10; // Изменит значение x
Ссылки удобны для работы с большими объектами, такими как строки или векторы, чтобы избежать копирования:
std::string s1 = "Hello";
std::string& s2 = s1; // s2 — это ссылка на s1
s2 += " World"; // Изменит s1
Указатели
Указатель хранит адрес переменной в памяти. Его можно получить с помощью оператора &:
int x = 42;
int* ptr = &x; // ptr хранит адрес x
std::cout << *ptr; // Разыменование: выведет 42
Указатели можно переназначать, а также использовать специальное значение nullptr, которое означает "пустой" указатель:
int* ptr = nullptr; // Пустой указатель
ptr = &x; // Теперь ptr указывает на x
Опасности указателей
Не обращайтесь к памяти, которая уже вышла из области видимости:
int* ptr = nullptr;
{
int x = 42;
ptr = &x;
}
// *ptr — неопределённое поведение!
3. Константность
Константы — это переменные, которые нельзя изменять после инициализации:
const int c = 42;
// c = 10; // Ошибка компиляции
Константность можно комбинировать со ссылками и указателями:
const int* ptr = &x; // Указатель на константу
int* const ptr = &x; // Константный указатель
4. Дополнительные темы
Динамическая память
Динамическая память используется, когда размер данных заранее неизвестен. Для этого применяются операторы new и delete:
int* arr = new int[10]; // Выделение памяти
delete[] arr; // Освобождение памяти
Умные указатели
Умные указатели (std::unique_ptr, std::shared_ptr) автоматически освобождают память, когда она больше не нужна:
#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(42);
Практические советы
Используйте ссылки в циклах :
for (const auto& item : vector) {
std::cout << item;
}
Избегайте "висячих" ссылок и указателей : Не обращайтесь к памяти, которая уже вышла из области видимости.
Проверяйте границы массивов : Используйте метод at() вместо оператора [], чтобы избежать ошибок доступа.
Задачи для практики
1. Перечисления: "Трафик-свет"
Описание:
Создайте программу, которая моделирует работу светофора. Используйте перечисление enum class TrafficLight с тремя состояниями: Red, Yellow, Green. Программа должна циклически переключать светофор каждую секунду (можно использовать std::this_thread::sleep_for для задержки).
Пример вывода:
Red
Yellow
Green
Red
...
2. Структуры: "Координаты точек"
Описание:
Создайте структуру Point3D, которая представляет точку в трехмерном пространстве. Добавьте метод distanceTo, который вычисляет расстояние между двумя точками.
Пример использования:
Point3D p1 = {1.0, 2.0, 3.0};
Point3D p2 = {4.0, 5.0, 6.0};
std::cout << p1.distanceTo(p2); // Выведет ~5.196
3. Кортежи и пары: "Анализ данных"
Описание:
Напишите программу, которая хранит информацию о студентах в виде кортежей. Каждый кортеж содержит имя студента (строка), возраст (целое число) и средний балл (число с плавающей точкой). Создайте вектор таких кортежей и найдите студента с максимальным средним баллом.
Пример данных:
std::vector<std::tuple<std::string, int, double>> students = {
{"Alice", 20, 4.5},
{"Bob", 22, 3.8},
{"Charlie", 21, 4.9}
};
Пример вывода:
Студент с максимальным баллом: Charlie, балл: 4.9
4. Указатели: "Менеджер памяти"
Описание:
Напишите программу, которая динамически выделяет память под массив целых чисел, заполняет его случайными значениями и выводит их на экран. После этого освободите память.
Дополнительно:
Добавьте проверку на утечку памяти (например, используя инструменты, такие как Valgrind или AddressSanitizer).
5. Константность: "Защита данных"
Описание:
Создайте функцию printVector, которая принимает константную ссылку на вектор и выводит его элементы. Убедитесь, что внутри функции нельзя изменить содержимое вектора.
Пример использования:
std::vector<int> nums = {1, 2, 3, 4, 5};
printVector(nums);
Пример вывода:
1 2 3 4 5
6. Умные указатели: "Управление ресурсами"
Описание:
Создайте класс FileHandler, который управляет открытием и закрытием файла. Используйте std::unique_ptr для автоматического управления ресурсами.
Пример использования:
FileHandler file("example.txt");
file.write("Hello, world!");
7. Ссылки в циклах: "Фильтрация данных"
Описание:
Напишите программу, которая фильтрует строки из вектора, оставляя только те, которые начинаются с заглавной буквы. Используйте ссылки в цикле for для эффективной работы с данными.
Пример данных:
std::vector<std::string> words = {"Apple", "banana", "Cherry", "date"};
Пример вывода:
Apple
Cherry
8. Выравнивание данных: "Размер структуры"
Описание:
Создайте структуру с полями разных типов (например, char, int, double) и выведите её размер с помощью sizeof. Затем измените порядок полей так, чтобы минимизировать размер структуры за счет выравнивания.
Пример структуры:
struct Example {
char c;
double d;
int i;
};
Пример вывода:
Исходный размер: 24 байта
Оптимизированный размер: 16 байт
9. "Висячие" ссылки: "Безопасное обращение"
Описание:
Напишите программу, которая демонстрирует проблему "висячих" ссылок. Создайте ссылку на локальную переменную внутри блока и попробуйте использовать её после выхода из блока. Объясните, почему это приводит к неопределенному поведению.
Пример кода:
int* ptr = nullptr;
{
int x = 42;
ptr = &x;
}
std::cout << *ptr; // Неопределенное поведение!
10. Комбинированная задача: "Управление библиотекой"
Описание:
Создайте программу для управления библиотекой книг. Каждая книга описывается структурой Book с полями: название, автор, год издания. Реализуйте следующие функции:
Добавление книги в библиотеку.
Поиск книги по названию.
Удаление книги из библиотеки.
Используйте std::vector для хранения книг и умные указатели для управления памятью.
Пример использования:
Library lib;
lib.addBook({"The C++ Programming Language", "Bjarne Stroustrup", 1985});
lib.findBook("The C++ Programming Language");
lib.removeBook("The C++ Programming Language");
Заключение
Теперь вы знаете основы работы с составными типами данных, ссылками, указателями и константностью в C++. Эти инструменты — фундамент для написания эффективного кода. Продолжайте практиковаться, и скоро вы сможете создавать сложные программы!
Отличная реклама, ни чего лишнего, прямо руководство к действию!
https://pay.cloudtips.ru/p/94932afa
вы помогаете инвалиду первой группы, огромное вам спасибо, люди добрые!
Дай Бог вам здоровья!
Ответ на пост «Власти Москвы объяснили появление в метро надписей на таджикском и узбекском»2
Дарю бесплатный дизайн выхода из Метро.
Просто стеклянная приоткрытая дверь, сквозь которую видно улицу. Всё. Не надо ни залеплять наклейками, ни разводить национальные срачи по поводу переводов на разные языки слова "выход". Разве что цифры оставить.
Без надисей непонятно, что это выход? Зачем вообще что-то писать? Там и собаке будет понятно, что это выход.
Мыши, осьминоги из лабиринта выход находят, вороны решают головоломки, даже гриб-слизевик может строить маршруты. А тут русские, таджики и узбеки, если им не подписать на всех языках, будут стоять перед стеклянной дверью и не смогут выйти... Атас
Ответ на пост «Инновации о потерянном времени»4
Мне не понятны ваши жалобы.
Все указатели и разметка как минимум единожды продублирована.
И направление движения поездов по 1 и 2 путям, и список станций по пути следования.
В центре есть таблички на путевых стенах, помимо подвесных указателей -- есть указатели напольные. (Наклейки на полу с направлениями переходов и выходов.)
Если вы не в состоянии ориентироваться в метро -- проверьте зрение или голову. Потому что кроме как тем, что вы, граждане, ебётесь в глаза -- я вашу избирательную слепоту объяснить не могу.
Указателей более чем достаточно, дополнение в виде анимированных указателей -- вполне себе логичное продолжение, ОСОБЕННО с учетом того, что дубли статичных указателей есть.
Вот типичная станция метро: Мичуринский пр-т.
направление движения поездов на колоннах возле платформ, лицом к людям, идущим по центральному проходу. (В обе стороны направлены).









