This repository has been archived on 2024-08-23. You can view files and clone it, but cannot push or open issues or pull requests.
lessons/C++/C++.md

788 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# УДАЧИ НАМ
## Statement
> Наименьшая независимая еденица в языке C++
### Основные
* declaration:
```C++
int i;
```
* assigment :
```C++
i = 5;
```
* Output (хоть Коля и не согласен, что это основной)
```C++
std::cout << i;
```
declaration и assigment можно вместе
```C++
int i = 5;
```
## Expression
> Любое выражение: число, строка, вызов функции, мат(на английском). выражения
## Функции
> Последовательность statement'ов. Исполнение начинается с функции main()
## Библиотеки
> Набор скомпилированного кода, для использования в других программах
### Примеры библиотек
* iostream - для ввода / вывода
## Коментарии
* Однострочные
```C++
// Коментарий
```
* Многострочные
```C++
/* Длинный
Коментарий */
```
## Пример простой программы
```C++
#include <iostream>
int main() {
std::cout << "Hello, world!\n";
}
```
## Переменные
> В C++ есть переменные, они жрут оперативку
* Копирующая инициализация
```C++
int val = 5;
```
* Прямая инициализация
```C++
int val(5);
```
### Неинициализированные переменные
> Неинициализированные переменные могут иметь в себе мусор, что может привести к ошибкам
### Инициализация и объявление нескольких переменных
```C++
int a, b;
```
```C++
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
```C++
#include <iostream>;
```
### *cout*
> *cout* - объект для вывода в терминал
```C++
#include <iostream>;
std::cout << 5 << '\n';
```
### *endl*
> endl можно использовать как '\n'
```C++
#include <iostream>;
std::cout << 5 << std::endl;
```
### *cin*
> cin используется для ввода значений из терминала
```C++
#include <iostream>;
int a = 0;
std::cin >> a;
```
## Ветвление
```C++
#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 (инициализация; условие; изменение)
```C++
#include <iostream>;
// Выводит числа от 0 до 5 включительно
for (int i = 0; i <= 5; i++) {
std::cout << i << '\n';
}
```
### Цикл while (с пред условием)
```C++
#include <iostream>;
// Аналогичен коду сверху
int i = 0;
while (i <= 5) {
std::cout << i << '\n';
i++;
}
```
### Цикл do while
> Цикл do while выполнит тело хотя бы один раз, даже если условие изначально false
```C++
#include <iostream>;
// Выведет 0 (не смотря на то, что 0 чётное) и 1
int i = 0
do {
std::cout << i << '\n';
i++;
} while (i % 2 != 0)
```
### Операторы прерывания
* *break*
* *continue*
Они аналогичны оным из Python
## switch
```C++
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 позволяет перейти к исполнению другого блока кода. Если будете его использовать, то придёт страшный Николай и даст по рукам книжкой о правильном написании кода
```C++
mark:
// do-something
// 1 eternity later (возможно даже в другой функции)
goto mark;
```
## Массивы
> Структура данных позволяющая хранить набор элементов одного типа. Объявление состоит из указания типа и размерности. Массивы в C++ имеют нумерацию элементов, начинающуюся с 0
### Объявление массива
```C++
int number[5]; // пять интов. Массив называется numbers
char chars[20];
bool flags[3];
```
### Инициализация массива
```C++
int numbers[3] = {10, 20, 30};
int foo[] = {10, 20, 30}; // Тоже будет на 3 элемента
int bar[10] = {10, 20, 30} // Оставшиеся 8 не инициализированны
```
### Обход массива
```C++
#include <iostream>
int numbers[] = {10, 20, 30}
for (int i = 0; i < 3; i++) {
std::cout << i << '\n';
}
```
### Размер массива
```C++
int arr[5];
int n = sizeof(arr) / sizeof(int); // n - длинна массива
```
### Многомерные массивы
```C++
#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* для освобождения памяти.
```C++
int* dynamic_array = new int[5]; // dynamic_array - список из 5 чисел
delete[] dynamic_array;
```
```C++
#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
```C++
#include <iostream>
// Функция, возвращает int который получила
int foo(int n) {
return n;
}
// Процедура
void bar(int n) {
std::cout << n << '\n';
}
```
### Передача значений в функцию
> При передаче аргумента, как значения, создаётся его копия, а при передаче по ссылки, копия не создаётся и может менять его
```C++
#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
}
```
### Передача массивов в функцию
> При передаче массивов в функцию, нужно кинуть туда ещё и длину. Функция может менять оригинальный массив. Копия не создаётся
```C++
#include <iostream>
void foo(int bar[], int size) {
if (size >= 1) {
std::cout << bar[1] << '\n';
} else {
std::cout << "Not enough elements\n";
}
}
```
## Ссылки и указатели
> *Ссылка* (*reference*) - псевдоним джя существующей переменной. Может иметь не валидный адрес или быть не инициализированной
```C++
int a = 5;
int& b = a; // При изменении b, будет меняться a
b++; // a и b станут 6
```
> Указатель (*pointer*) содержит адрес существующей переменной
```C++
int a = 5;
int* b = &a; // При изменении b, будет меняться a
(*b)++ // a станет равна 6
```
## Строки (углубление)
```C++
#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'
}
```
### Перебор символов
```C++
#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';
}
```
### Ввод строки с клавиатуры
```C++
#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.(*)
```C++
void boo(int* ptr) {
(*ptr)++;
}
```
## Возврат значений из функции
* Возврат по значению return
* Важно не вернуть ссылку или указатель на локальную переменную
## Структуры
> Структура - тип данных, позоляющий объединить несколько переменных в одной еденице.
```C++
#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*
```C++
#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
## Объединение
> Объединение - это пользовательский тип данных, позволяющий хранить различные типы данных в одной области памяти. Объединение занимает память, достаточную для хранения переменной имеющий самый большой размер.
```C++
union MyUnion{
int intValue;
char charValue;
};
MyUnion val = 65;
int a = val.intValue; // 65
char b = val.charValue; // 'A'
```
## Передача значений в функцию (Подробнее)
* Передача по значению (создаётся копия, может быть медленно, используется для примитивов)
```C++
void increment(int a) {
a++;
}
int a = 5;
increment(&a); // a остаётся 5
```
* Передача по ссылке (копия не создаётся, используется для больших значений / структур, аналогична передаче по значению, но синтаксис проще)
```C++
void increment(int& a) {
a++;
}
int a = 5;
increment(a); // a становится 6
```
* Передача по указателю (копия не создаётся, используется в основном для массивов)
```C++
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 - достпуно внутри класса и наследникам
### Конструктор и деструктор
> Конструктор - функция, которая вызывается при инициализации класса (может быть несколько)
> Деструктор - функция, которая вызывается при уничтожении объекта
```C++
#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 - указатель на объект вызвовший метод
```C++
#include <string>
class Foo{
public:
Person(std::string val) {
this->name = val;
}
};
```
## ООП
> Инкапсуляция - данные класса скрыты от прямого доступа и манипулиций извне класса
> Наследование - создаёт классы-потомки
> Полимарфизм - разные классы используют один и тот же интерфейс
```C++
#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;
}
```