19 KiB
УДАЧИ НАМ
Statement
Наименьшая независимая еденица в языке C++
Основные
-
declaration:
int i;
-
assigment :
i = 5;
-
Output (хоть Коля и не согласен, что это основной)
std::cout << i;
declaration и assigment можно вместе
int i = 5;
Expression
Любое выражение: число, строка, вызов функции, мат(на английском). выражения
Функции
Последовательность statement'ов. Исполнение начинается с функции main()
Библиотеки
Набор скомпилированного кода, для использования в других программах
Примеры библиотек
- iostream - для ввода / вывода
Коментарии
-
Однострочные
// Коментарий
-
Многострочные
/* Длинный Коментарий */
Пример простой программы
#include <iostream>
int main() {
std::cout << "Hello, world!\n";
}
Переменные
В C++ есть переменные, они жрут оперативку
- Копирующая инициализация
int val = 5;
- Прямая инициализация
int val(5);
Неинициализированные переменные
Неинициализированные переменные могут иметь в себе мусор, что может привести к ошибкам
Инициализация и объявление нескольких переменных
int a, b;
int a = 5, b = 6;
Типы данных
- void - ничего
Числа
- short - число 16 бит
- int - число 16 или 32 бита
- long - число 32 бита
- long long - число 64 бита
- char - число или символ. 8 бит
Отрицательные числа
- signed - может быть отрицательным (по умолчанию, кроме char)
- unsigned - число не отрицательно
Переполнение
- Переполнение случается при потере бит из-за того, что значение после операции выходит за границу их значений
65635 как unsigned int + 1 выдаст 0
Целочисленное деление
Деление двух цилочисленных значений всегда выдаёт целое число (округление вниз)
Символьные тип char
char представляет собой 1 символ (не всегда) и всегда весит 1 байт.
Для инициализации char символом используется одинарные ковычки
Строки
Для строк используется библиотека string. Строки указываются в двойных ковычках
Типы данных с плавающией точкой
Типы с плавающей могут показывать дробные числа
- float - 32 бита
- double - 64 бита (двойная точность по сравнению с float)
- long double - от 8 до 16 байт (зависит от компилятора)
Логические значения
- true
- false
Константы
Величины, которые остаются неизменными. Они должны быть инициализированны при объявлении
IOSTREAM
Подключение IOSTREAM
#include <iostream>;
cout
cout - объект для вывода в терминал
#include <iostream>;
std::cout << 5 << '\n';
endl
endl можно использовать как '\n'
#include <iostream>;
std::cout << 5 << std::endl;
cin
cin используется для ввода значений из терминала
#include <iostream>;
int a = 0;
std::cin >> a;
Ветвление
#include <iostream>;
int a = 5;
if (a == 5) {
std::cout << 5 << '\n';
} else if (a == 6) {
std::cout << 6 << '\n';
} else {
std::cout << "Neither\n";
}
Логические операторы
- && - и
- || - или
- ! - не
Циклы
Цикл for
for (инициализация; условие; изменение)
#include <iostream>;
// Выводит числа от 0 до 5 включительно
for (int i = 0; i <= 5; i++) {
std::cout << i << '\n';
}
Цикл while (с пред условием)
#include <iostream>;
// Аналогичен коду сверху
int i = 0;
while (i <= 5) {
std::cout << i << '\n';
i++;
}
Цикл do while
Цикл do while выполнит тело хотя бы один раз, даже если условие изначально false
#include <iostream>;
// Выведет 0 (не смотря на то, что 0 чётное) и 1
int i = 0
do {
std::cout << i << '\n';
i++;
} while (i % 2 != 0)
Операторы прерывания
- break
- continue
Они аналогичны оным из Python
switch
int a = 5;
switch(a){
case 1:
std::cout << "1" << '\n';
break;
case 2:
std::cout << "2" << '\n';
break;
default:
std::cout << "Other" << '\n';
break;
}
Goto
Goto позволяет перейти к исполнению другого блока кода. Если будете его использовать, то придёт страшный Николай и даст по рукам книжкой о правильном написании кода
mark:
// do-something
// 1 eternity later (возможно даже в другой функции)
goto mark;
Массивы
Структура данных позволяющая хранить набор элементов одного типа. Объявление состоит из указания типа и размерности. Массивы в C++ имеют нумерацию элементов, начинающуюся с 0
Объявление массива
int number[5]; // пять интов. Массив называется numbers
char chars[20];
bool flags[3];
Инициализация массива
int numbers[3] = {10, 20, 30};
int foo[] = {10, 20, 30}; // Тоже будет на 3 элемента
int bar[10] = {10, 20, 30} // Оставшиеся 8 не инициализированны
Обход массива
#include <iostream>
int numbers[] = {10, 20, 30}
for (int i = 0; i < 3; i++) {
std::cout << i << '\n';
}
Размер массива
int arr[5];
int n = sizeof(arr) / sizeof(int); // n - длинна массива
Многомерные массивы
#include <iostream>
int arr[2][2] = {{10, 20}, {30, 40}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
std::cout << arr[i][j] << '\n';
}
}
Динамический массив
Массив, размер которого может быть указан в runtime. Ключевое слово new используется для создания, a delete для освобождения памяти.
int* dynamic_array = new int[5]; // dynamic_array - список из 5 чисел
delete[] dynamic_array;
#include <iostream>
int n;
std::cin >> n;
int* nums = new int[n];
for (int i = 0; i < n; i++) {
std::cin >> nums[i];
}
for (int i = 0; i < n; i ++) {
std::cout << nums[i] << ' ';
}
std::cout << std::endl;
delete[] nums;
Процедуры и функции
Процедуры - функции, которые возвращают void
#include <iostream>
// Функция, возвращает int который получила
int foo(int n) {
return n;
}
// Процедура
void bar(int n) {
std::cout << n << '\n';
}
Передача значений в функцию
При передаче аргумента, как значения, создаётся его копия, а при передаче по ссылки, копия не создаётся и может менять его
#include <iostream>
void increment1(int i) {
i++;
std::cout << i << '\n';
}
void increment2(int& i) {
i++;
std::cout << i << '\n';
}
int main() {
int i = 5;
increment1(i) // Выведет 6, но i останется 5
increment2(i) // Выведет 6, и i станет 6
}
Передача массивов в функцию
При передаче массивов в функцию, нужно кинуть туда ещё и длину. Функция может менять оригинальный массив. Копия не создаётся
#include <iostream>
void foo(int bar[], int size) {
if (size >= 1) {
std::cout << bar[1] << '\n';
} else {
std::cout << "Not enough elements\n";
}
}
Ссылки и указатели
Ссылка (reference) - псевдоним джя существующей переменной. Может иметь не валидный адрес или быть не инициализированной
int a = 5;
int& b = a; // При изменении b, будет меняться a
b++; // a и b станут 6
Указатель (pointer) содержит адрес существующей переменной
int a = 5;
int* b = &a; // При изменении b, будет меняться a
(*b)++ // a станет равна 6
Строки (углубление)
#include <iostream>
#include <string>
int main() {
std::string a = "abc";
// b - копия a
std::string b = a;
// c содержит 'c'
сhar c = a[2];
// последний символ a стал z
a[2] = 'z'
}
Перебор символов
#include <string>
std::string a = "abc"
for (char c: a) {
std::cout << c << '\n';
}
for (int i = 0; i < a.length(); i++) {
std::cout << a[i] << '\n';
}
Ввод строки с клавиатуры
#include <iostream>
#include <string>
std::string str;
// Ввести 1 слово
std::cin >> str;
// Ввести строку
std::getLine(std::cin, str);
Полезные методы строк
- length(), size() - длина строки
- substr(start,length) - извлекает часть строки
- find(substring) - первое вхождение
- replace(oldString, NewString) - заменяет все вхождения из старой в новую строку (ничего не возвращает, изменения на месте)
- toupper(), tolower() - меняет регистр соответсвенно названию
- empty() - проверяет пустая ли строка
- compare() -сравнивает две строки. Возвращает 0, если строкми одинаковые.
- insert(index,string) - вставляет строку в указанную позицию.
- erase(start,length) - удалает часть строки
Полезные функции для строк
- getLine(inputStream, string) - считывает строку из потока и тсохраняет в переменную str
Способы передачи аргументов в функию
- по значению (pass by value) - создание копии
- Изначальное не меняется
- Создание копии может занимать много времени
- Используется для передачи примитивов
- по сслылке (pass by reference) - передача в функцию указатель на объект
- Изначальное значение может меняться
- Копия не создаётся
- Используется для составных типов и больших объектов
- Передача по указателю (pass by pointer) - pass by reference без кучки синтактического сахара Разименование - операция, которая позволяет получить доступ к значению, на которое указывает pointer.(*)
void boo(int* ptr) {
(*ptr)++;
}
Возврат значений из функции
- Возврат по значению return
- Важно не вернуть ссылку или указатель на локальную переменную
Структуры
Структура - тип данных, позоляющий объединить несколько переменных в одной еденице.
#include <iostream>
struct Employee {
short id;
int age;
double salary;
};
Employee john = {5, 20, 30.0};
std::cout << john.id << ' ' << john.age << ' ' << john.salary << '\n';
Перечисления
Перечисление - это пользовательский тип данных, который представляет собой набор именованных констант, которым присваиваются целочисленные значения. Весит как int
#include <iostream>
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
};
enum Weekday2 {
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
};
Weekday today = Saturday;
Weekday полностью аналогичен Weekday2
Объединение
Объединение - это пользовательский тип данных, позволяющий хранить различные типы данных в одной области памяти. Объединение занимает память, достаточную для хранения переменной имеющий самый большой размер.
union MyUnion{
int intValue;
char charValue;
};
MyUnion val = 65;
int a = val.intValue; // 65
char b = val.charValue; // 'A'
Передача значений в функцию (Подробнее)
-
Передача по значению (создаётся копия, может быть медленно, используется для примитивов)
void increment(int a) { a++; } int a = 5; increment(&a); // a остаётся 5
-
Передача по ссылке (копия не создаётся, используется для больших значений / структур, аналогична передаче по значению, но синтаксис проще)
void increment(int& a) { a++; } int a = 5; increment(a); // a становится 6
-
Передача по указателю (копия не создаётся, используется в основном для массивов)
void increment(int* a) { (*a)++; } int a = 5; increment(&a); // a тоже становится 6
Классы
Классы - шаблон или описание, определяющее структуру поведения объектов. Объект - экземляр класса
class ClassName{
// Поля и методы класса
};
Поля класса - переменные, котроые представляют состояие объетогв класса Методы класа - функции, которые определяют поведение объектов класса
ClassName objectName; // создание объекта класса просто
ClassName objectName = new ClassName(); //создание объекта класса сложно
delete objectName;
Пример
#include <iostream>
#include <string>
class Person{
public:
std::string name;
int age;
void displayInfo(){
std::count << "Name: " << name << ", Age: " << age << '\n';
}
}
int main(){
Person person1;
person1.name = "Alice";
person1.age = 25;
person1.displayInfo();
Person* person2 = new Person();
person2 -> name = "Bob";
person2 -> age = 30;
person2 -> displayInfo();
delete person2;
return 0;
}
Пользовательский тип данных
Модификаторы доступа
- public - доступно всем (по умолчанию в struct)
- private - доступно только внутри класса (по умолчанию в class)
- protected - достпуно внутри класса и наследникам
Конструктор и деструктор
Конструктор - функция, которая вызывается при инициализации класса (может быть несколько) Деструктор - функция, которая вызывается при уничтожении объекта
#include <iostream>
class MyClass {
public:
MyClass() {
std::cout << "Constructed\n";
}
MyClass(int val) {
std::cout << "Constucted" << val << '\n';f
}
~MyClass() {
std::cout << "Destroyed\n";
}
};
this
this - указатель на объект вызвовший метод
#include <string>
class Foo{
public:
Person(std::string val) {
this->name = val;
}
};
ООП
Инкапсуляция - данные класса скрыты от прямого доступа и манипулиций извне класса Наследование - создаёт классы-потомки Полимарфизм - разные классы используют один и тот же интерфейс
#include <iostream>
class Figure {
public:
virtual void draw() {
std::cout << "Draw figure\n";
}
};
class Circe: public Figure {
public:
void draw() override {
std::cout << "Draw circle\n";
}
};
class Rectangle: public Figure {
public:
void draw() override {
std::cout << "Draw rectangle\n";
}
};
int main() {
Figure* figure = new Figure();
Figure* circle = new Circle():
Figure* rectangle = new Rectangle();
figure->draw();
circle->draw();
rectangle->draw();
delete figure;
delete circle;
delete rectangle;
}