C++ — мощный, универсальный и широко используемый язык программирования, который остается актуальным в мире разработки программного обеспечения уже более трех десятилетий. В этом коротком посте мы познакомим вас с основами C++ и поможем заложить прочную основу для начала пути программирования.

Краткая история C++
C++ был создан Бьярном Страуструпом в 1985 году как расширение языка программирования C. Страуструп хотел добавить в C объектно-ориентированные возможности, что привело к рождению C++. С тех пор C++ претерпел несколько изменений и обновлений, самой последней версией является C++20.
Важность C++ в современном программировании
C++ является важным языком в современном мире программирования по нескольким причинам:
- Он очень эффективен и обеспечивает детальный контроль над системными ресурсами.
- Он поддерживает как процедурные, так и объектно-ориентированные парадигмы программирования.
- Он имеет обширную стандартную библиотеку (STL), которая упрощает сложные задачи.
- Он широко используется в таких отраслях, как разработка игр, встроенные системы и высокопроизводительные вычисления.
Обзор поста
Этот пост разделен на несколько разделов, каждый из которых посвящен ключевым аспектам программирования на C++:
- Настройка среды
- Базовый синтаксис C++
- Функции
- Объектно-ориентированного программирования
- Стандартная библиотека шаблонов (STL)
- Ввод и вывод
- Обработка ошибок
- Расширенные темы
- Рекомендации и отладка
К концу этой статьи вы получите четкое представление об основах C++ и будете готовы заняться более сложными темами.
Настройка среды
Прежде чем мы начнем программировать, давайте настроим нашу среду разработки.
Выбор IDE
Интегрированная среда разработки (IDE) — это программное приложение, предоставляющее полный набор инструментов для кодирования, отладки и создания программного обеспечения. Некоторые популярные IDE C++ включают в себя:
- Visual Studio: мощная и многофункциональная интегрированная среда разработки от Microsoft.
- Code::Blocks: бесплатная кроссплатформенная среда разработки с открытым исходным кодом.
- CLion: коммерческая среда разработки от JetBrains с расширенными функциями и отличной поддержкой.
Выберите IDE, которая лучше всего соответствует вашим потребностям и предпочтениям.
Установка компилятора
Компилятор — это программа, которая преобразует ваш код C++ в машинный код, который затем может быть выполнен на компьютере. Некоторые распространенные компиляторы C++:
- GCC: Коллекция компиляторов GNU — это широко используемый компилятор с открытым исходным кодом, поддерживающий несколько платформ.
- Clang: компилятор на основе LLVM, известный своей быстрой компиляцией и полезными сообщениями об ошибках.
- Microsoft Visual C++: компилятор, входящий в состав Visual Studio, оптимизированный для разработки под Windows.
Установите компилятор, совместимый с выбранной вами IDE и операционной системой.
Создание вашего первого проекта на C++
После настройки IDE и компилятора пришло время создать свой первый проект C++. Выполните следующие общие шаги:
- Откройте выбранную вами IDE и создайте новый проект.
- В качестве типа проекта выберите «C++».
- Выберите имя и местоположение для вашего проекта.
- Добавьте в свой проект новый исходный файл C++ (обычно с расширением .cpp).
Базовый синтаксис C++
Теперь, когда наша среда настроена, давайте углубимся в основы синтаксиса C++.
Структура программы на C++
Типичная программа на C++ состоит из следующих элементов:
- Директивы препроцессора. Это команды, которые инструктируют компилятор выполнить определенные задачи перед компиляцией кода. Например,
#includeиспользуется для включения файлов заголовков. - Объявления и определения функций. Они используются для объявления и определения функций, которые представляют собой блоки кода, выполняющие определенные задачи.
- Переменные и типы данных: они используются для хранения данных и управления ими в вашей программе.
- Структуры управления: они используются для управления ходом вашей программы, например операторы
if,elseиswitch. - Циклы. Они используются для многократного выполнения блоков кода, таких как циклы
for,whileиdo-while.
Вот простой пример программы на C++:
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
Переменные и типы данных
В C++ мы используем переменные для хранения данных и управления ими. Каждая переменная имеет определенный тип данных, который определяет тип данных, которые она может хранить. Некоторые распространенные типы данных C++:
- int: целые значения (например, -2, 0, 42).
- float: значения с плавающей запятой одинарной точности (например, 3,14f, -0,001f).
- double: значения с плавающей запятой двойной точности (например, 3,141592653589793, -0,000001).
- char: отдельные символы (например, «a», «Z», «9»).
- bool: логические значения (истина или ложь).
Вот пример объявления и инициализации переменных в C++:
int age = 30; float weight = 65.5f; double pi = 3.141592653589793; char initial = 'A'; bool is_adult = true;
Операторы и выражения
Операторы — это специальные символы, которые выполняют операции с операндами (переменными или значениями). Некоторые распространенные операторы C++:
- Арифметические операторы:
+,-,*,/,%. - Операторы отношения:
<,>,<=,>=,==,!=. - Логические операторы:
&&,||,!
Выражения — это комбинации переменных, значений и операторов, которые приводят к одному значению. Вот пример использования операторов и выражений в C++:
int a = 10; int b = 20; int sum = a + b; bool is_greater = a > b;
Структуры управления (если, иначе, переключатель)
Структуры управления используются для управления потоком вашей программы на основе определенных условий. Вот некоторые распространенные структуры управления C++:
- if: выполняет блок кода, если указанное условие истинно.
- else: выполняет блок кода, если условие в предыдущем операторе
ifявляется ложным. - switch: выполняет блок кода на основе значения указанного выражения.
Вот пример использования управляющих структур в C++:
int x = 42;
if (x > 0) {
std::cout << "x is positive" << std::endl;
} else {
std::cout << "x is non-positive" << std::endl;
}
switch (x % 2) {
case 0:
std::cout << "x is even" << std::endl;
break;
case 1:
std::cout << "x is odd" << std::endl;
break;
}
Циклы (for, while, do- while)
Циклы используются для многократного выполнения блоков кода на основе определенных условий. Некоторые распространенные циклы C++:
- for: выполняет блок кода указанное количество раз.
- while: выполняет блок кода, пока заданное условие истинно.
- do- while: выполняет блок кода хотя бы один раз, а затем несколько раз, пока заданное условие истинно.
Вот пример использования циклов в C++:
// for loop
for (int i = 0; i < 10; ++i) {
std::cout << i << std::endl;
}
// while loop
int count = 0;
while (count < 10) {
std::cout << count << std::endl;
++count;
}
// do-while loop
int num;
do {
std::cout << "Enter a positive number: ";
std::cin >> num;
} while (num <= 0);
Функции
Функции — это блоки кода, которые выполняют определенные задачи и могут вызываться по имени. Они могут принимать входные данные (параметры) и возвращать выходные данные (возвращаемые значения).
Определение и объявление функций
Функции определяются с использованием следующего синтаксиса:
return_type function_name(parameter_list) {
// function body
}
Например, вот простая функция, которая складывает два числа и возвращает результат:
int add(int a, int b) {
return a + b;
}
Объявления функций (также называемые прототипами) используются для информирования компилятора о существовании функции до ее определения. Они имеют следующий синтаксис:
return_type function_name(parameter_list);
Например, вот объявление функции add:
int add(int a, int b);
Параметры функции и возвращаемые значения
Параметры функции — это переменные, которые содержат входные значения, передаваемые в функцию. Они указаны в определении и объявлении функции.
Возвращаемые значения — это выходные значения, создаваемые функцией. Они указываются с помощью оператора return, за которым следует выражение или значение.
Вот пример функции, которая вычисляет площадь прямоугольника:
double area(double length, double width) {
return length * width;
}
Перегрузка функций
Перегрузка функций — это возможность определять несколько функций с одинаковым именем, но с разными списками параметров. Компилятор выбирает подходящую функцию для вызова на основе количества и типов переданных аргументов.
Вот пример перегрузки функции:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
Рекурсия
Рекурсия — это процесс вызова функции прямо или косвенно. Его часто используют для решения проблем, которые можно разбить на более мелкие, похожие проблемы.
Вот пример рекурсивной функции, которая вычисляет факториал числа:
int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
Объектно-ориентированного программирования
Объектно-ориентированное программирование (ООП) — это парадигма программирования, которая фокусируется на организации кода в «объекты», представляющие объекты реального мира. Он построен на концепциях классов, объектов, наследования и полиморфизма.
Введение в концепции ООП
Основными понятиями ООП являются:
- Классы: шаблоны для создания объектов, состоящих из членов данных и функций-членов.
- Объекты: экземпляры классов, представляющие объекты реального мира.
- Наследование: процесс создания новых классов, которые наследуют свойства и методы существующих классов.
- Полиморфизм: способность функции или метода работать с несколькими типами данных или объектов.
Классы и объекты
Классы определяются с помощью ключевого слова class, за которым следует имя класса и набор фигурных скобок, содержащий элементы данных класса и функции-члены.
Объекты — это экземпляры классов, созданные с помощью конструктора класса.
Вот пример определения класса и создания объекта:
class Dog {
public:
std::string name;
int age;
void bark() {
std::cout << "Woof!" << std::endl;
}
};
int main() {
Dog my_dog;
my_dog.name = "Buddy";
my_dog.age = 3;
my_dog.bark();
}
Конструкторы и деструкторы
Конструкторы — это специальные функции-члены, которые вызываются при создании объекта. Они используются для инициализации элементов данных объекта. Деструкторы — это специальные функции-члены, которые вызываются при уничтожении объекта. Они используются для выполнения любой необходимой очистки.
Вот пример класса с конструкторами и деструктором:
class Dog {
public:
std::string name;
int age;
// Default constructor
Dog() : name("Unnamed"), age(0) {}
// Parameterized constructor
Dog(std::string n, int a) : name(n), age(a) {}
// Destructor
~Dog() {
std::cout << "Dog destroyed" << std::endl;
}
void bark() {
std::cout << "Woof!" << std::endl;
}
};
Наследование
Наследование — это процесс создания новых классов, которые наследуют свойства и методы существующих классов. Это позволяет повторно использовать код и модульную конструкцию.
Вот пример наследования в C++:
class Animal {
public:
std::string name;
int age;
void make_sound() {
std::cout << "Generic animal sound" << std::endl;
}
};
class Dog : public Animal {
public:
void make_sound() {
std::cout << "Woof!" << std::endl;
}
};
Полиморфизм
Полиморфизм — это способность функции или метода работать с несколькими типами данных или объектов. Это позволяет создавать более гибкий и модульный код.
Вот пример полиморфизма в C++:
class Animal {
public:
virtual void make_sound() {
std::cout << "Generic animal sound" << std::endl;
}
};
class Dog : public Animal {
public:
void make_sound() {
std::cout << "Woof!" << std::endl;
}
};
class Cat : public Animal {
public:
void make_sound() {
std::cout << "Meow!" << std::endl;
}
};
int main() {
Animal *animals[] = {new Dog(), new Cat()};
for (Animal *animal : animals) {
animal->make_sound();
}
}
Стандартная библиотека шаблонов (STL)
Стандартная библиотека шаблонов (STL) — это набор классов и функций шаблонов, которые предоставляют общие структуры данных и алгоритмы для программирования на C++.
Обзор STL
Основными компонентами STL являются:
- Контейнеры: структуры данных, в которых хранятся и упорядочиваются данные (например, вектор, список, карта).
- Итераторы: объекты, обеспечивающие доступ к элементам контейнера и их перемещение.
- Алгоритмы: функции, выполняющие операции с контейнерами (например, сортировку, поиск).
Контейнеры (вектор, список, карта и т. д.)
Контейнеры — это структуры данных, которые хранят и организуют данные. Некоторые распространенные контейнеры STL:
- вектор: динамический массив, размер которого может увеличиваться или уменьшаться.
- список: двусвязный список, позволяющий эффективно вставлять и удалять.
- map: ассоциативный контейнер, в котором хранятся пары «ключ-значение» с уникальными ключами.
Вот пример использования векторного контейнера в C++:
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
numbers.push_back(6); // Add an element to the end
numbers.pop_back(); // Remove the last element
int first = numbers.front(); // Get the first element
int last = numbers.back(); // Get the last element
}
Итераторы
Итераторы — это объекты, которые предоставляют способ доступа и перемещения по элементам контейнера. Они похожи на указатели, но более гибки и могут работать с разными типами контейнеров.
Вот пример использования итераторов с векторным контейнером:
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::vector<int>::iterator it;
for (it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << std::endl;
}
}
Алгоритмы
Алгоритмы — это функции, которые выполняют операции с контейнерами, такие как сортировка, поиск и преобразование данных.
Вот пример использования алгоритма sort с векторным контейнером:
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {5, 3, 1, 4, 2};
std::sort(numbers.begin(), numbers.end()); // Sort the vector in ascending order
}
Ввод и вывод
C++ предоставляет несколько способов обработки ввода и вывода, включая консольный ввод/вывод, файловый ввод/вывод и манипулирование строками.
Консольный ввод и вывод
Консольный ввод и вывод выполняются с помощью объектов cin и cout, входящих в состав библиотеки iostream. Они позволяют вам читать и записывать данные в консоль и обратно.
Вот пример использования консольного ввода и вывода:
#include <iostream>
int main() {
int age;
std::cout << "Enter your age: ";
std::cin >> age;
std::cout << "You are " << age << " years old" << std::endl;
}
Ввод и вывод файлов
Ввод и вывод файлов осуществляется с помощью классов ifstream и ofstream, входящих в состав библиотеки fstream. Они позволяют вам читать и записывать данные в файлы и из них.
Вот пример использования файлового ввода и вывода:
#include <fstream>
#include <iostream>
int main() {
std::ofstream outfile("output.txt");
outfile << "Hello, file!" << std::endl;
outfile.close();
std::ifstream infile("output.txt");
std::string line;
getline(infile, line);
std::cout << line << std::endl;
infile.close();
}
Манипулирование строками
Манипулирование строками осуществляется с помощью класса string, который является частью библиотеки string. Он предоставляет различные функции и операторы для работы со строками.
Вот пример использования манипуляций со строками:
#include <string>
#include <iostream>
int main() {
std::string greeting = "Hello, World!";
std::string name = "John";
std::string personalized_greeting = greeting + " " + name;
std::cout << personalized_greeting << std::endl;
}
Обработка ошибок
Обработка ошибок — важный аспект программирования, который помогает вам справляться с непредвиденными ситуациями и предотвращать сбои вашей программы. В C++ обработка ошибок в основном осуществляется с помощью исключений.
Исключения
Исключения — это события, которые происходят во время выполнения программы при возникновении ошибки. Они создаются с использованием ключевого слова throw и перехватываются с помощью блоков try и catch.
Вот пример использования исключений для обработки ошибок:
#include <iostream>
double divide(double a, double b) {
if (b == 0) {
throw "Division by zero";
}
return a / b;
}
int main() {
try {
double result = divide(10, 0);
std::cout << "Result: " << result << std::endl;
} catch (const char *error) {
std::cout << "Error: " << error << std::endl;
}
}
Попробуй, поймай и брось
Ключевые слова try, catch и throw используются для обработки исключений в C++.
- try: включает блок кода, который может вызвать исключение.
- catch: определяет блок кода, который обрабатывает исключение определенного типа.
- throw: выдает исключение при обнаружении ошибки.
Пользовательские классы исключений
Вы можете создавать собственные классы исключений, наследуя класс std::exception и переопределяя его метод what().
Вот пример создания собственного класса исключений:
#include <iostream>
#include <stdexcept>
class DivisionByZeroException : public std::exception {
public:
const char *what() const noexcept override {
return "Division by zero";
}
};
double divide(double a, double b) {
if (b == 0) {
throw DivisionByZeroException();
}
return a / b;
}
int main() {
try {
double result = divide(10, 0);
std::cout << "Result: " << result << std::endl;
} catch (const DivisionByZeroException &ex) {
std::cout << "Error: " << ex.what() << std::endl;
}
}
Расширенные темы
Теперь, когда мы рассмотрели основы, давайте углубимся в некоторые более сложные темы C++.
Указатели и управление памятью
Указатели — это переменные, в которых хранится адрес памяти другой переменной. Они используются для прямого доступа к памяти и управления ею, обеспечивая большую гибкость и контроль над ресурсами вашей программы.
Вот пример использования указателей в C++:
int x = 42; int *p = &x; // p points to the memory address of x *p = 10; // Change the value of x through the pointer
Управление памятью — это процесс выделения и освобождения памяти по мере необходимости вашей программы. В C++ вы можете использовать операторы new и delete для динамического выделения и освобождения памяти.
Вот пример управления памятью в C++:
int *p = new int; // Allocate memory for an int *p = 42; // Assign a value to the memory delete p; // Deallocate the memory
Шаблоны
Шаблоны — это мощная функция C++, позволяющая писать универсальный код, способный работать с различными типами данных. Они используются для создания повторно используемых классов и функций, которые могут работать с любым типом данных.
Вот пример использования шаблонов в C++:
template<typename T>
T add(T a, T b) {
return a + b;
}
int main() {
int x = add<int>(1, 2);
double y = add<double>(3.14, 2.71);
}
Лямбда-выражения
Лямбда-выражения — это краткий способ создания анонимных функций (функций без имени). Они полезны для создания коротких одноразовых функций, которые можно передавать в качестве аргументов другим функциям.
Вот пример использования лямбда-выражения в C++:
#include <algorithm>
#include <vector>
int main() {
std::vector<int> numbers = {5, 3, 1, 4, 2};
std::sort(numbers.begin(), numbers.end(),
[](int a, int b) { return a > b; }); // Sort in descending order using a lambda
}
Многопоточность
Многопоточность — это процесс одновременного выполнения нескольких потоков, позволяющий вашей программе выполнять несколько задач одновременно. C++ предоставляет библиотеку <thread> для работы с потоками.
Вот пример использования многопоточности в C++:
#include <iostream>
#include <thread>
void print_hello() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t(print_hello);
t.join(); // Wait for the thread to finish
}
Рекомендации и отладка
Написание чистого, эффективного и удобного в сопровождении кода важно для любого программиста. В этом разделе мы обсудим лучшие практики и методы отладки программирования на C++.
Организация кода
Организация кода в отдельные функции, классы и файлы упрощает чтение, понимание и поддержку.
- Функции. Разбейте код на небольшие многократно используемые функции, выполняющие конкретные задачи.
- Классы. Организуйте связанные данные и функции в классы для моделирования реальных объектов.
- Файлы. Разделите код на разные файлы в зависимости от их функциональности и используйте файлы заголовков для объявлений.
Соглашения об именах
Использование согласованных соглашений об именах для переменных, функций и классов упрощает чтение и понимание вашего кода.
- Переменные. Используйте строчные буквы и подчеркивания (например,
my_variable). - Функции. Используйте строчные буквы и подчеркивания (например,
my_function). - Классы: используйте PascalCase (например,
MyClass).
Методы отладки
Отладка — это процесс поиска и исправления ошибок в коде. Некоторые распространенные методы отладки включают в себя:
- Проверка кода. Проверьте свой код на наличие синтаксических и логических ошибок, а также других проблем.
- Операторы печати. Добавьте в свой код операторы печати, чтобы отображать значения переменных и отслеживать выполнение программы.
- Точки останова. Используйте точки останова в вашей IDE, чтобы приостановить выполнение программы и проверить ее состояние.
- Пошаговая отладка. Используйте пошаговую отладку в интегрированной среде разработки, чтобы выполнять программу построчно и наблюдать за ее поведением.
Оптимизация производительности
Оптимизация производительности вашего кода может помочь вашей программе работать быстрее и использовать меньше ресурсов. Некоторые общие советы по оптимизации производительности включают в себя:
- Используйте эффективные алгоритмы. Выбирайте алгоритмы с меньшей временной сложностью, чтобы сократить время выполнения вашей программы.
- Минимизировать использование памяти. Используйте соответствующие структуры данных и методы распределения памяти, чтобы минимизировать использование памяти.
- Профилируйте свой код. Используйте инструменты профилирования, чтобы выявить узкие места в производительности вашего кода и оптимизировать их.
Заключение
Поздравляем! Теперь вы изучили основы программирования на C++, включая настройку среды разработки, понимание основного синтаксиса, работу с функциями и классами, использование стандартной библиотеки шаблонов, обработку ввода и вывода и многое другое.
Обзор ключевых концепций
Вот краткий обзор некоторых ключевых понятий, которые мы рассмотрели:
- C++ — мощный, универсальный и широко используемый язык программирования.
- Он поддерживает как процедурные, так и объектно-ориентированные парадигмы программирования.
- Стандартная библиотека шаблонов (STL) предоставляет набор классов и функций шаблонов для общих структур данных и алгоритмов.
- Обработка ошибок в C++ в основном осуществляется с помощью исключений.
- Расширенные темы C++ включают указатели, управление памятью, шаблоны, лямбда-выражения и многопоточность.
Ресурсы для дальнейшего обучения
Чтобы продолжить изучение и расширить свои знания C++, рассмотрите следующие ресурсы:
- Справочные веб-сайты C++, такие как cplusplus.com и cppreference.com.
- Онлайн-курсы и обучающие материалы по программированию, такие как Изучаем C++ и C++ для программистов.
- Книги по C++, такие как «C++ Primer» Стэнли Б. Липпмана, Жозе Лажуа и Барбары Э. Му и «Эффективный C++» Скотта Мейерса.
Следующие шаги в вашем путешествии по C++
Теперь, когда у вас есть прочный фундамент в C++, вы можете приступить к изучению более сложных тем, таких как:
- Программирование графического пользовательского интерфейса (GUI) с использованием таких библиотек, как Qt или GTK.
- Разработка игр с использованием таких движков, как Godot Engine, Unreal Engine или Unity (с написанием сценариев на C++).
- Сеть и веб-разработка с использованием таких библиотек, как Boost.Asio или Poco.
- Встраиваемые системы и программирование Интернета вещей на таких платформах, как Arduino и Raspberry Pi.
Продолжайте практиковаться и создавать проекты, и вы в кратчайшие сроки станете опытным программистом на C++!