diff --git a/README.md b/README.md index f75f857f..c3472373 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,97 @@ -# Podstawy C++ #1 - Coders School -## [Moduł 1](module1/) +# Podstawy C++ + +## [Moduł 1](module1/index.pl.html) + +### [Typy](module1/01_types.pl.md) + +### [Funkcje](module1/02_functions.pl.md) + +### [Instrukcje warunkowe](module1/03_branches.pl.md) + +### [Pętle](module1/04_loops.pl.md) + +### [Tablice](module1/05_arrays.pl.md) + +### [Praca domowa](module1/06_homework.pl.md) + +## [Moduł 2](module2/index.pl.html) + +### [STL](module2/01_stl_intro.pl.md) + +### [`std::vector`](module2/02_vector.pl.md) + +### [`for` po kolekcji](module2/03_range_for.pl.md) + +### [`std::string`](module2/04_string.pl.md) + +### [`std::list`](module2/05_list.pl.md) + +### [`std::map`](module2/06_map.pl.md) + +### [Praca domowa](module2/07_homework.pl.md) + +## [Moduł 3](module3/index.pl.html) + +### [Zasięg zmiennych](module3/01_scopes.pl.md) + +### [Referencje](module3/02_references.pl.md) + +### [Wskaźniki](module3/03_pointers.pl.md) + +### [Zagrożenia](module3/04_hazards.pl.md) + +### [`enum` i `enum class`](module3/05_enums.pl.md) + +### [Praca domowa](module3/07_homework.pl.md) + +___ + +# C++ basics + +## [Module 1](module1/index.en.html) -### [Typy](module1/presentation_types.md) +### [Types](module1/01_types.en.md) -### [Funkcje](module1/presentation_functions.md) +### [Functions](module1/02_functions.en.md) -### [Instrukcje warunkowe](module1/presentation_branches.md) +### [Conditional statements](module1/03_branches.en.md) -### [Pętle](module1/presentation_loops.md) +### [Loops](module1/04_loops.en.md) -### [Tablice](module1/presentation_arrays.md) +### [Arrays](module1/05_arrays.en.md) -### [Praca domowa](module1/presentation_homework.md) +### [Homework](module1/06_homework.en.md) -## [Moduł 2](module2/) +## [Module 2](module2/index.en.html) -### [STL](module2/presentation_stl_intro.md) +### [STL](module2/01_stl_intro.en.md) -### [`std::vector`](module2/presentation_vector.md) +### [`std::vector`](module2/02_vector.en.md) -### [`for` po kolekcji](module2/presentation_range_for.md) +### [`for` over collection](module2/03_range_for.en.md) -### [`std::string`](module2/presentation_string.md) +### [`std::string`](module2/04_string.en.md) -### [`std::list`](module2/presentation_list.md) +### [`std::list`](module2/05_list.en.md) -### [`std::map`](module2/presentation_map.md) +### [`std::map`](module2/06_map.en.md) -### [Praca domowa](module2/presentation_homework.md) +### [Homework](module2/07_homework.en.md) -## [Moduł 3](module3/) +## [Module 3](module3/index.en.html) -### [Zasięg zmiennych](module3/presentation_scopes.md) +### [Variables scope](module3/01_scopes.en.md) -### [Referencje](module3/presentation_references.md) +### [References](module3/02_references.en.md) -### [Wskaźniki](module3/presentation_pointers.md) +### [Pointers](module3/03_pointers.en.md) -### [Zagrożenia](module3/presentation_hazards.md) +### [Threats](module3/04_hazards.en.md) -### [`enum` i `enum class`](module3/presentation_enums.md) +### [`enum` and `enum class`](module3/05_enums.en.md) -### [Praca domowa](module3/presentation_homework.md) +### [Homework](module3/07_homework.en.md) diff --git a/module1/01_types.en.md b/module1/01_types.en.md new file mode 100644 index 00000000..d0319145 --- /dev/null +++ b/module1/01_types.en.md @@ -0,0 +1,206 @@ + + +# C++ basics + +## Data types + + + Coders School + + +___ + +## Some simple math + +* 1 byte == 8 bits +* In a binary lottery, randomly selected numbers may have values 0 or 1 +* Thus, when drawing 8 numbers, we can get, for example: 1 0 1 0 1 0 1 0 +* There are exactly 256 -> (2^8) such combinations +* Thus, in 1 byte (8 bits) we can write 256 numbers, e.g. from 0 to 255 +* If we draw 32 numbers in the lottery, (32/8 = 4), i.e. 4 bytes, there are 2^32 such combinations (i.e. over 4 billion) + +___ + +## Empty type - `void` + +* Objects of void type cannot be created +* It is used to indicate that the function does not return anything +* You can create void* pointers (bad practice in C++) +* It is NOT used to indicate that the function takes no arguments + +```cpp +int fun(void) { /* ... */ } // bad practice, C style +int fun() { /* ... */ } // good practice, C++ style +``` + + +___ + +## Boolean - `bool` + +* Size: at least 1 byte (usually equal to just 1) + * `sizeof(bool) >= 1` +* 2 possible values + * `false` + * `true` + +___ + +## Character types + +* Size: 1 byte +* 256 possible values +* `char` -> from `-128` to `127` +* `unsigned char` -> from `0` to `255` + +Prefix `unsigned` means that there are no negative numbers i.e. from 0 to some positive value. + + +The size of character types is always 1 byte. + + +The sizes of further types are platform dependent e.g. 32 bits or 64 bits. + + +___ + +## Integer types + +* `short (unsigned short)` - at least 2 bytes +* `int (unsigned int)` - at least 2 bytes +* `long (unsigned long)` - at least 4 bytes +* `long long (unsigned long long)` - at least 8 bytes + +___ + +## Floating-point types + +* `float` - usually 4 bytes +* `double` - usually 8 bytes +* `long double` - usually 10 bytes (rarely used) +* Floating point types can always be negative (unsigned versions do not exist) +* They have special values: + * `0`, `-0` (negative zero) + * `-Inf`, `+Inf` (infinity) + * `NaN` (Not a Number) + +Warning! Comparison `NaN == NaN` gives `false` + + +Advanced Reading: [The IEEE754 standard that defines floating point types](https://en.wikipedia.org/wiki/IEEE_754) + + +___ + +## Type aliases + +There are also types that are aliases (different naming for better understanding of type). + +`std::size_t` depending on the compiler may be the type (`unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`). Usually it is the type `unsigned int`. It is worth using it when our variable will refer to some size, e.g. the size of an array. + + +We can create our own type aliases using `typedef` or `using` + + +```cpp +typedef int Number; +Number a = 5; // int a = 5; + +using Fraction = double; +Fraction b = 10.2; // double b = 10.2; +``` + + +___ + +## `auto` type + +In some places we can use `auto` type. The compiler will deduce the type itself, e.g. based on the assigned value. + +```cpp + auto num = 5; // int + auto num = 5u; // unsigned int + auto num = 5.5; // double + auto num = 5.f; // float + auto letter = 'a'; // char + auto num = false; // bool + auto sth; // compilation error, unable to deduce type +``` + +___ + +## Type Sizes + +The C++ standard defines such a relationship between the sizes of integer types + +```cpp +1 == sizeof(char) \ + <= sizeof(short) \ + <= sizeof(int) \ + <= sizeof(long) \ + <= sizeof(long long); +``` + +___ + +## Arithmetic operations + +* Basic: + - * / +* Modifying a variable: += -= *= /= +* Incrementing (+1) variable: ++ +* Decrementing (-1) variable: -- + +### Examples + +```cpp +int a = 5 + 7; // a = 12 +``` + + +```cpp +int a = 5; +a += 7; // a = 12 +``` + + +```cpp +int a = 5; +++a; // a = 6 +a--; // a = 5 +``` + + +___ + +## Questions + +```cpp +int i = 5; +auto j = i++ - 1; +``` + +What are the values `i` and `j`? + +`i = 6` + +`j = 4` + +What type is `j`? + +`int` + +___ + +## A little joke + +What do you call 8 hobbits? + +A Hobbyte :) + + +___ + +## Links for extending knowledge + +* [Fundamental types on cppreference.com](https://en.cppreference.com/w/cpp/language/types) +* [The IEEE754 standard that defines floating point types](https://en.wikipedia.org/wiki/IEEE_754) diff --git a/module1/presentation_types.md b/module1/01_types.pl.md similarity index 94% rename from module1/presentation_types.md rename to module1/01_types.pl.md index eb48d726..bbd704ec 100644 --- a/module1/presentation_types.md +++ b/module1/01_types.pl.md @@ -13,19 +13,19 @@ ___ ## Prosta matematyka * 1 bajt == 8 bitów -* W binarnym totolotku wylosowane liczby mogą mieć `0` lub `1` -* Zatem podczas losowania 8 numerków możemy otrzymać przykładowo: `1 0 1 0 1 0 1 0` -* Takich kombinacji jest dokładnie `256 -> (2^8)` +* W binarnym totolotku wylosowane liczby mogą mieć 0 lub 1 +* Zatem podczas losowania 8 numerków możemy otrzymać przykładowo: 1 0 1 0 1 0 1 0 +* Takich kombinacji jest dokładnie 256 -> (2^8) * Zatem na 1 bajcie (8 bitach) możemy zapisać 256 liczb, np. od 0 do 255 -* Jeżeli w totolotku losujemy 32 numerki, (32/8 = 4) czyli 4 bajty to takich kombinacji jest `2^32` (czyli ponad 4 miliardy) +* Jeżeli w totolotku losujemy 32 numerki, (32/8 = 4) czyli 4 bajty to takich kombinacji jest 2^32 (czyli ponad 4 miliardy) ___ ## Typ pusty - `void` -* Nie można tworzyć obiektów typu `void` +* Nie można tworzyć obiektów typu void * Służy do zaznaczenia, że funkcja nic nie zwraca -* Można tworzyć wskaźniki `void*` (zła praktyka w C++) +* Można tworzyć wskaźniki void* (zła praktyka w C++) * NIE służy do oznaczania, że funkcja nie przyjmuje argumentów ```cpp diff --git a/module1/02_functions.en.md b/module1/02_functions.en.md new file mode 100644 index 00000000..61ad7691 --- /dev/null +++ b/module1/02_functions.en.md @@ -0,0 +1,71 @@ + + +# C++ basics + +## Functions + + + Coders School + + +___ + +## Functions + +A function is a fragment of a program that was given a name and we can execute it by calling its name and pass it possible arguments. + +Function == subprogram == procedure + +For example, when cycling, our main function is to move from point A to B. However, we also perform several subroutines such as gear shifting, braking, accelerating, turning. Similarly, in a program, we can isolate specific behaviors and transfer them to functions that we will name to suggest what they do. It is important that the function only does one thing. One function changes gears, the other brakes, the third turns. + +___ + +## Function signatures (declarations) + +`void fun(int)` - the function is named fun, returns nothing, and takes one int. + +### Guess signatures by description + +A function called `foo` that returns nothing and takes one argument of type `double`. + + +`void foo(double)` + + +A function called `bar` that returns type double and takes 2 arguments. The first is `float` and the second is `const int` (`const` means the value cannot be modified). + + +`double bar(float, const int)` + + +___ + +## Function calls + +`foo(5.0)` -> we call the function `foo` with an argument `double` which is equal to `5.0` + + +`double result = bar(5.4f, 10)` -> we call the function `bar` with an argument `float (5.4f)` and `int (10)` and we assign its result to a variable of type `double` named `result`. + + +___ + +## Exercise + +Add the missing function `multiply`. It is supposed to multiply two numbers given as its parameters. [Download the exercise][homework] + +```cpp +#include + +// Write missing function here + +int main() { + std::cout << "4 * 5: " << multiply(4, 5) << "\n"; + std::cout << "10 * 5: " << multiply(10, 5) << "\n"; + std::cout << "-5 * 5: " << multiply(-5, 5) << "\n"; + + return 0; +} +``` + +[homework]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task1.cpp diff --git a/module1/presentation_functions.md b/module1/02_functions.pl.md similarity index 76% rename from module1/presentation_functions.md rename to module1/02_functions.pl.md index c863d617..54003cd1 100644 --- a/module1/presentation_functions.md +++ b/module1/02_functions.pl.md @@ -16,7 +16,7 @@ Funkcja jest to fragment programu, któremu nadano nazwę i który możemy wykon Funkcja == podprogram == procedura -Przykładowo, w trakcie jazdy na rowerze naszą główną funkcją jest przemieszczanie się z punktu a do b. Jednak wykonujemy także kilka podprogramów, jak zmiana biegów, hamowanie, rozpędzanie, skręcanie. Podobnie w programie możemy wydzielić konkretne zachowania i przenieść je do funkcji, które nazwiemy tak, by sugerowały co robią. Ważne, aby funkcja robiła tylko jedną rzecz. Jedna funkcja zmienia biegi, druga hamuje, trzecia skręca. +Przykładowo, w trakcie jazdy na rowerze naszą główną funkcją jest przemieszczanie się z punktu A do B. Jednak wykonujemy także kilka podprogramów, jak zmiana biegów, hamowanie, rozpędzanie, skręcanie. Podobnie w programie możemy wydzielić konkretne zachowania i przenieść je do funkcji, które nazwiemy tak, by sugerowały co robią. Ważne, aby funkcja robiła tylko jedną rzecz. Jedna funkcja zmienia biegi, druga hamuje, trzecia skręca. ___ @@ -26,13 +26,17 @@ ___ ### Odgadnijcie sygnatury po opisie -Funkcja o nazwie foo, która nic nie zwraca a przyjmuje jeden argument typu double. +Funkcja o nazwie `foo`, która nic nie zwraca a przyjmuje jeden argument typu `double`. + -`void foo(double)` +`void foo(double)` + -Funkcja o nazwie bar, która zwraca typ double a przyjmuje 2 argumenty. Pierwszy to float, a drugi to const int (const oznacza, że wartość ta nie może zostać zmodyfikowana). +Funkcja o nazwie `bar`, która zwraca typ double a przyjmuje 2 argumenty. Pierwszy to `float`, a drugi to `const int` (`const` oznacza, że wartość ta nie może zostać zmodyfikowana). + -`double bar(float, const int)` +`double bar(float, const int)` + ___ @@ -64,4 +68,4 @@ int main() { } ``` -[zadanie-domowe]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task1.cpp \ No newline at end of file +[zadanie-domowe]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task1.cpp diff --git a/module1/03_branches.en.md b/module1/03_branches.en.md new file mode 100644 index 00000000..78d5df4f --- /dev/null +++ b/module1/03_branches.en.md @@ -0,0 +1,111 @@ + + +# C++ basics + +## Conditional statements + + + Coders School + + +___ + +## `if` statement + +A conditional statement is nothing more than asking the program a question, for example: + +* Have you received all the data? +* Has the boss's life dropped to 0? +* Has the achievement been earned by the player? +* Is the number greater than the maximum allowed? + +___ + +## `if` construction + +```cpp +if (condition) { + // do sth +} +``` + +___ + +## Combining conditions + +What if a lot of conditions have to be met? +We can combine conditions with an operator **or** (`||`, `or`) or **and** (`&&`, `and`) + +```cpp +if (are_potatoes_eatten && is_meat_eatten && is_salad_eatten) +``` + + +All 3 conditions must be met + +```cpp +if (player_has_20_dex || player_has_18_int || player_has_22_str) +``` + + +In this case, it is enough to meet one of 3 conditions. They can all be met, but it is enough for any of them to be met. + +___ + +## `else` statement + +If the program can react differently to meeting certain conditions, we can use `if else` constructions + +```cpp +if (number < 2) { + critical_miss(); +} else if (number < 18) { + hit(); +} else { + critical_hit(); +} +``` + +___ + +## `switch/case` statement + +```cpp +char option = getInput(); +switch (option) { +case 'l': + goLeft(); + break; +case 'r': + goRight(); + break; +default: + exit(); +} +``` + +* `case` stands for a specific case +* `break` announces that we are exiting the conditional statement `switch` and we continue with the rest of the program. Its absence will result in the execution of the instructions from the next `case`. +* `default` is place where program will end up if no other condition is met + +___ + +## Exercise + +Add a function `max`. It is supposed to return the maximum of the three given values. [Download the exercise][homework] + +```cpp +#include + +// Write your function here + +int main() { + std::cout << "max (1, 2, 3): " << max(1, 2, 3) << "\n"; + std::cout << "max (2, 3, 1): " << max(2, 3, 1) << "\n"; + std::cout << "max (3, 2, 1): " << max(3, 2, 1) << "\n"; + + return 0; +} +``` + +[homework]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task2.cpp diff --git a/module1/presentation_branches.md b/module1/03_branches.pl.md similarity index 97% rename from module1/presentation_branches.md rename to module1/03_branches.pl.md index e23fe615..f27cec64 100644 --- a/module1/presentation_branches.md +++ b/module1/03_branches.pl.md @@ -86,7 +86,7 @@ default: * `case` oznacza konkretny przypadek * `break` informuje, że wychodzimy z instrukcji warunkowej `switch` i konstytuujemy dalej program. Jego brak spowoduje, że wykonają się instrukcje z kolejnego `case`. -* `deafult` jest to miejsce gdzie program dotrze, gdy żaden inny warunek nie zostanie spełniony +* `default` jest to miejsce gdzie program dotrze, gdy żaden inny warunek nie zostanie spełniony ___ diff --git a/module1/04_loops.en.md b/module1/04_loops.en.md new file mode 100644 index 00000000..02bb6a5f --- /dev/null +++ b/module1/04_loops.en.md @@ -0,0 +1,125 @@ + + +# C++ basics + +## Loops + + + Coders School + + +___ + +## Loops + +A loop is used to repeat statements that we want to execute more than once without having to write them over and over in the code. + +Basic loops: `while`, `for` + +___ + +## `while` loop + + We use `while` when we want to do something until some condition is met. Usually we have no idea when it is going to happen (we don't know the number of steps), e.g .: + +* We browse the shirts on the Internet until we find a match for us +* We repeat the fight with the same boss until we defeat him +* We eat the soup until the plate is empty +* We search through the contacts on the phone until we find the person we want to talk to + +___ + +### `while` loop construction + +```cpp +while (condition) { + // Do sth +} +``` + +### Example + +```cpp +while (a == b) { + std::cin >> a; + std::cin >> b; +} +``` + + +___ + +## `for` loop + +We use `for` when we want to do something a certain number of times. We usually know the number of steps, e.g. + +* We fill out a questionnaire consisting of 10 questions -> number of steps: 10 +* We move from point A to B -> number of steps = distance / step length +* We are writing an exam consisting of 4 tasks -> the number of steps (if we are prepared, 4, if not, we do the subroutine `cheat`) +* We fasten our shirts (as long as we don't tear any button out) + +___ + +### `for` loop construction + +```cpp +for (variable = initial_value; condition; variable_change) { + // Do sth +} +``` + +### Example + +```cpp +for (size_t i = 0 ; i < 10 ; i+=2) { + std::cout << "i: " << i << '\n'; +} +``` + + +___ + +Every loop `for` can be changed to `while` and vice versa. We choose the more convenient notation for us, usually depending if we know the number of steps. + +But there is another type of loop. + +___ + +## `do/while` loop + +```cpp +do { + // Do sth +} while(condition) +``` + +Code in `while` or `for` loops may not be executed even once if the condition is never met. + +Code in `do/while` loop will be performed at least once. + +___ + +## Exercise + +Add a function `printString`. It is supposed to print the text given in the first argument as many times as the value of the number given in the second argument. [Download the exercise][homework] + +```cpp +#include + +// Write your function here + +int main() { + printString("Hello", 5); + std::cout << "\n"; + + printString("AbC", 2); + std::cout << "\n"; + + printString("HiHi ", 6); + std::cout << "\n"; + + return 0; +} +``` + +[homework]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task3.cpp diff --git a/module1/presentation_loops.md b/module1/04_loops.pl.md similarity index 97% rename from module1/presentation_loops.md rename to module1/04_loops.pl.md index 827b545c..066e9862 100644 --- a/module1/presentation_loops.md +++ b/module1/04_loops.pl.md @@ -20,7 +20,7 @@ ___ ## Pętla `while` -`while` używamy, gdy chcemy coś wykonać dopóki nie zostanie spełniony jakiś warunek. Przeważnie nie mamy pojęcia, kiedy to następy (nie znamy liczby kroków) np: +`while` używamy, gdy chcemy coś wykonać dopóki nie zostanie spełniony jakiś warunek. Przeważnie nie mamy pojęcia, kiedy to nastąpi (nie znamy liczby kroków) np: * Przeglądamy koszule w Internecie dopóki nie znajdziemy pasującej do nas * Powtarzamy walkę z tym samym bossem aż go nie pokonamy @@ -122,4 +122,4 @@ int main() { } ``` -[zadanie-domowe]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task3.cpp \ No newline at end of file +[zadanie-domowe]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task3.cpp diff --git a/module1/05_arrays.en.md b/module1/05_arrays.en.md new file mode 100644 index 00000000..5ace110e --- /dev/null +++ b/module1/05_arrays.en.md @@ -0,0 +1,84 @@ + + +# C++ basics + +## Arrays + + + Coders School + + +___ + +## Introduction to arrays + +# 🚃🚃🚃🚃🚃🚃🚃🚃🚃🚃 + +* Arrays can be treated like wagons in a train +* Arranged one by one and connected to each other +* They can hold different types like human, coal, etc. +* We can write 10 coal wagons as Coal tab[10] - it means that we create an array that stores 10 elements of type Coal. + +___ + +Array in memory + +* In C++, the array is in one continuous area in memory and is inseparable (its elements cannot be removed) +* All items are of the same type +* The array is always indexed from 0 +* `tab[0]` - the first element of the array `tab` +* `tab[9]` - the last element of a 10-element array `tab` + +___ + +## Example of array modification + +```cpp +int tab[10]; +tab[0] = 1; +tab[1] = 2; +// ... +tab[9] = 10; +``` + +This could be done better with a loop. + +___ + +### `operator[]` + +We refer to an array element with `operator[]`. We must remember to always refer to an existing array element. Otherwise the program will have undefined behavior as we will try to access memory that is not in the array. It's called garbage. At best, the operating system will detect it and we'll get a **crash** (segmentation fault). At worst, we will work on some incorrect random data. The effects can be very serious (space shuttle crashes, irradiation from medical apparatus). + +```cpp +int tab[10]; +tab[10] = 42; // !!! undefined behavior (UB) +``` + + +___ + +## Exercise + +Modify the program so that it fills the array with the following odd numbers: 1, 3, 5, 7, ... [Download the exercise][homework] + +```cpp +#include + +constexpr size_t tab_size = 100; + +int main() { + int tab[tab_size]; + + for (size_t i = 0; i < tab_size; ++i) { + tab[i] = i; + } + + for (size_t i = 0; i < tab_size; ++i) { + std::cout << tab[i] << "\n"; + } + + return 0; +} +``` + +[homework]: https://github.com/coders-school/cpp-fundamentals/blob/master/module1/task4.cpp diff --git a/module1/presentation_arrays.md b/module1/05_arrays.pl.md similarity index 92% rename from module1/presentation_arrays.md rename to module1/05_arrays.pl.md index 1f82087a..f01c93b0 100644 --- a/module1/presentation_arrays.md +++ b/module1/05_arrays.pl.md @@ -17,11 +17,11 @@ ___ * Tablice można traktować jak wagony w pociągu * Ustawione kolejno jeden po drugim i połączone ze sobą * Mogą pomieścić różne typy, jak człowiek, węgiel, itp. -* 10 wagonów z węglem możemy zapisać jako `Coal tab[10]` - oznacza to, że tworzymy tablicę, która przechowuje 10 elementów typu Coal (węgiel). +* 10 wagonów z węglem możemy zapisać jako Coal tab[10] - oznacza to, że tworzymy tablicę, która przechowuje 10 elementów typu Coal (węgiel). ___ -Tablica w pamięci +Tablica w pamięci * W C++ tablica znajduje się w jednym, ciągłym obszarze w pamięci i jest nierozłączna (nie można usuwać jej elementów) * Wszystkie elementy są tego samego typu diff --git a/module1/06_homework.en.md b/module1/06_homework.en.md new file mode 100644 index 00000000..fcd81823 --- /dev/null +++ b/module1/06_homework.en.md @@ -0,0 +1,133 @@ + + +# C++ basics + +## Summary + + + Coders School + + +___ + +## What do you remember from today? + +### Write as many keywords as possible in the chat + + +1. Data types + * `void`, `bool`, `char`, `int`, `double` + their varieties +1. Functions + * signature (declaration) = return type, name, arguments +1. Conditional statements + * `if`, `switch/case` +1. Loops + * `for`, `while`, `do/while` +1. Arrays + * `Type t[N]`, `operator[]` + +___ + + +## Homework + +### Post-work + + +* Read about [std::string](https://en.cppreference.com/w/cpp/string/basic_string) in the documentation. You will find there, among others, description of `std::to_string` function. It will be useful 🙂 +* Task 1 - Calculate (5 points) +* Task 2 - Fibonacci - recursion and iteration (6 points) + + +#### Bonus for punctuality + +For delivering each task before May 24, 2020 (Sunday) until 23:59 you will get 2 bonus points (4 points in total for 2 tasks). + +### Pre-work + +* Read about the [std :: vector](https://en.cppreference.com/w/cpp/container/vector) type documentation. Click on the different functions and look mainly at the usage examples at the bottom of the pages. +* You can look at the test files in the tasks and try to add your own test cases + +#### [Repo tasks](https://github.com/coders-school/cpp-fundamentals/tree/master/module1/homework) + +___ + + +## Task 1 - Calculate + +Implement a function whose task is to perform arithmetic operations on two numbers. + +Signature - `std::string calculate(const std::string& command, int first, int second)`. + +### Parameters + +* `const std::string& command` - type of arithmetic operation. One of `add`, `subtract`, `multiply`, `divide` +* `int first` - first number +* `int second` - second number + +### Return value + +* `std::string` - the result of the operation as text + +In case of a wrong parameter `command` the function should return the string "Invalid data". + +### Examples + +```cpp +auto result = calculate("add", 2, 3); // result = "5" +result = calculate("multiply", 2, 3); // result = "6" +result = calculate("hello", 2, 3); // result = "Invalid data" +``` + +___ + +## Task 2 - Fibonacci + +Implement two functions. Both are supposed to count the n-th number of [Fibonacci sequence](https://pl.wikipedia.org/wiki/Ciąg_Fibonacci), but in different ways. + +* iterative (using loops) +* recursively (the function is supposed to call itself) + +Functions must have specific signatures: + +```cpp +int fibonacci_iterative(int sequence); +int fibonacci_recursive(int sequence); +``` + +___ + + +## Task delivery + +1. Fork a repo [cpp-fundamentals](https://github.com/coders-school/cpp-fundamentals) +2. Get your fork - `git clone https://github.com/YOURNICK/cpp-fundamentals.git` +3. Go to the cpp-fundamentals directory - `cd cpp-fundamentals` +4. Create a branch named `calculate` for calculate problem solution - `git checkout -b calculate` +5. Go to the directory module1/homework/calculate - `cd module1/homework/calculate` +6. Here is the backbone of the program that you must complete. It already includes tests to verify that your implementation is correct. Before starting the implementation, enter the following commands: + +```bash +mkdir build # creates build directory +cd build # change directory to build +cmake .. # generates Makefile by following instructions from ../CMakeLists.txt +make # compilation +ctest -V # running tests +``` + +7. Implement the functionality (piece by piece, e.g. start from adding operation only) +8. Check if the implementation passes the tests - `make` (compilation) and `ctest -V` (test launch) +9. Make a commit with a description of the functionality - `git commit -am"adding works"` +10. Go back to step 7 and implement next functionality. If the solution passes all tests, go to the next step +11. Push changes to your fork - `git push origin calculate` +12. Click on Pull Request on GitHub. +13. Wait a moment for the Continuous Integration (CI) report to see if the solution compiles and tests pass on GitHub as well. +14. If there is ✅ - good job, the solution is correct. If there is ❌ click on it and check the error description. Correct it (points 7-11) and wait for the next CI report. + +___ + +## Delivery of remaining tasks + +First, go back to the main branch - `git checkout master` and proceed from step 4 for the next task (creating a new branch with a different name) + +You may notice that switching to a different branch has resulted in you missing the solution for the first task. Don't worry, it's just on a different branch. You can return to it by going to the branch of this task - `git checkout nazwa`. diff --git a/module1/presentation_homework.md b/module1/06_homework.pl.md similarity index 100% rename from module1/presentation_homework.md rename to module1/06_homework.pl.md diff --git a/module1/img/array.gif b/module1/img/array.gif deleted file mode 100644 index 74352787..00000000 Binary files a/module1/img/array.gif and /dev/null differ diff --git a/module1/img/array.png b/module1/img/array.png new file mode 100644 index 00000000..0c26cf44 Binary files /dev/null and b/module1/img/array.png differ diff --git a/module1/index.en.html b/module1/index.en.html new file mode 100644 index 00000000..0b854364 --- /dev/null +++ b/module1/index.en.html @@ -0,0 +1,137 @@ + + + + + + + C++ - basics - Coders School + + + + + + + + + + + + + + + +
+
+
+
+ +

C++ basics

+ + Coders School + +

Mateusz Adamski

+

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +

Coders School

+ Coders School + +
+
+
+ + + + + + diff --git a/module1/index.html b/module1/index.pl.html similarity index 93% rename from module1/index.html rename to module1/index.pl.html index 9fb36ba3..f84cf026 100644 --- a/module1/index.html +++ b/module1/index.pl.html @@ -79,27 +79,27 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
-
-
diff --git a/module2/01_stl_intro.en.md b/module2/01_stl_intro.en.md new file mode 100644 index 00000000..b3c97417 --- /dev/null +++ b/module2/01_stl_intro.en.md @@ -0,0 +1,21 @@ + + +# C++ basics + +## STL + + + Coders School + + +___ + +## Standard Template Library + +* Standard Template Library is available in the C++ language standard +* frequently used items from STL: + * `std::vector` + * `std::string` + * `std::map` + * `std::cout` and `std::cin` + * iterators diff --git a/module2/presentation_stl_intro.md b/module2/01_stl_intro.pl.md similarity index 100% rename from module2/presentation_stl_intro.md rename to module2/01_stl_intro.pl.md diff --git a/module2/02_vector.en.md b/module2/02_vector.en.md new file mode 100644 index 00000000..fdd88bd6 --- /dev/null +++ b/module2/02_vector.en.md @@ -0,0 +1,62 @@ + + +# C++ basics + +## `std::vector` + + + Coders School + + +___ + +## Features `std::vector` + +* very widely used +* dynamic array +* we do not have to specify how many elements we want in advance +* it is in one continuous memory area (like an array) +* it manages the memory itself + * it will take care of allocating new memory when it is needed + * it will take care of memory deallocation when we no longer need it + +___ + +## Creating a vector + +```cpp +std::vector numbers; +``` + +* a vector always needs to know what type of data it is holding +* the data type is given in angle brackets <> + +___ + +## Vector initialization with values + +```cpp +std::vector numbers = {1, 2, 3, 4, 5}; +std::vector numbers {1, 2, 3, 4, 5}; +``` + + +* both types of initialization (with = and without) are equivalent in the case of vector + +___ + +## Vector operations + +* adding an element to the vector + * `numbers.push_back(5)` +* reading an element from a vector + * `numbers[1]` +* assigning multiple elements to a vector + * `numbers = {1,2,3,4,5}` +* getting the first element from the vector + * `numbers.front()` +* getting the last element from the vector + * `numbers.back()` + +[Documentation on cppreference.org](https://en.cppreference.com/w/cpp/container/vector) + diff --git a/module2/presentation_vector.md b/module2/02_vector.pl.md similarity index 100% rename from module2/presentation_vector.md rename to module2/02_vector.pl.md diff --git a/module2/03_range_for.en.md b/module2/03_range_for.en.md new file mode 100644 index 00000000..f0967c2b --- /dev/null +++ b/module2/03_range_for.en.md @@ -0,0 +1,101 @@ + + +# C++ basics + +## `for` loop over container + + + Coders School + + +___ + +## Ranges + +* Each container (including an array or vector) has its end and beginning + * function `begin()` returns the beginning of the container + * function `end()` returns the end of the container + * (in a very simplified way, we will elaborate on this topic with iterators) + +___ + +## Range based `for` loop + +Thanks to the information about start and end of range, we can write a loop iterating through the entire scope of the container. + + +```cpp +for (auto i = vec.begin(); i != vec.end(); ++i) { + auto element = *i; + // do sth on element +} +``` + + +However, this notation is unnecessarily complex and unreadable. +That is why `range loop` were created which allow easy notation `for (type name : container)`. + +The compiler can generate code above, if we use the notation below. + +```cpp +for (auto element : vec) { + // do sth on element +} +``` + + +___ + +## Task + +Write a function `printVector` which will take `std::vector` as an argument and print its contents using a `for` loop over the collection. +Each item on a new line. +[Download the task][task1] + +```cpp +#include +#include +#include + +// Implement printVector + +int main() { + std::vector vec { + "Hello Coders School!", + "Welcome to the best C++ course ever", + "Man, this is crazy :)" + }; + printVector(vec); + return 0; +} +``` + +[task1]: https://github.com/coders-school/cpp-fundamentals/tree/master/module2/task1.cpp + +___ + +## Task + +Write a function `concatenateVector` which will take 2 vectors as arguments and then return one which will contain alternating elements from the first and second vector. +For example, for the following `vec1` and `vec2` it should return: `{1, 11, 2, 12, 3, 13, 4, 14, 5, 15}` +[Download the task][task2] + +```cpp +#include +#include + +// Implement concatenateVector + +int main() { + std::vector vec1 {1, 2, 3, 4, 5}; + std::vector vec2 {11, 12, 13, 14, 15}; + + auto vec = concatenateVector(vec1, vec2); + for (const auto& el : vec) { + std::cout << el << " "; + } + return 0; +} +``` + +[task2]: https://github.com/coders-school/cpp-fundamentals/tree/master/module2/task2.cpp diff --git a/module2/presentation_range_for.md b/module2/03_range_for.pl.md similarity index 95% rename from module2/presentation_range_for.md rename to module2/03_range_for.pl.md index 2088d2f8..c00eee93 100644 --- a/module2/presentation_range_for.md +++ b/module2/03_range_for.pl.md @@ -48,7 +48,7 @@ ___ ## Zadanie -Napisz funkcję `printVector`, która przyjmie jako argument `std::vector` i wypisze jego zawartość przy użyciu pętli for przy kolekcji. +Napisz funkcję `printVector`, która przyjmie jako argument `std::vector` i wypisze jego zawartość przy użyciu pętli `for` przy kolekcji. Każdy element w nowej linii. [Pobierz zadanie][task1] @@ -77,7 +77,7 @@ ___ ## Zadanie Napisz funkcję `concatenateVector`, która przyjmie jako argumenty 2 wektory a następnie zwróci jeden, który będzie zawierał naprzemiennie elementy z pierwszego i drugiego wektora. -Np. dla poniższych vec1 i vec2 powinna zwrócić: `{1, 11, 2, 12, 3, 13, 4, 14, 5, 15}` +Np. dla poniższych `vec1` i `vec2` powinna zwrócić: `{1, 11, 2, 12, 3, 13, 4, 14, 5, 15}` [Pobierz zadanie][task2] ```cpp diff --git a/module2/04_string.en.md b/module2/04_string.en.md new file mode 100644 index 00000000..513c16ff --- /dev/null +++ b/module2/04_string.en.md @@ -0,0 +1,36 @@ + + +# C++ basics + +## `std::string` + + + Coders School + + +___ + +## Character container - `std::string` + +* a special container that stores characters +* std::string also has a beginning and an end, like any container +* similar functions to std::vector + +___ + +## Operations on `std::string` + +* adding a character at the end + * `str.push_back('a')` (nobody does that 🙂) + * we recommend `str += 'a';` +* reading a single character + * `str[1]` +* initialization + * `std::string str("Hello")` + * `std::string str = "Hello"` +* assigning the entire string + * `str = "Hello"` +* getting the first character + * `str.front()` +* getting the last character + * `str.back()` diff --git a/module2/presentation_string.md b/module2/04_string.pl.md similarity index 100% rename from module2/presentation_string.md rename to module2/04_string.pl.md diff --git a/module2/05_list.en.md b/module2/05_list.en.md new file mode 100644 index 00000000..250de094 --- /dev/null +++ b/module2/05_list.en.md @@ -0,0 +1,120 @@ + + +# C++ basics + +## `std::list` + + + Coders School + + +___ + +## List + +### Question: what features did `std::vector` have? + + +Unlike a vector, the list is scattered around the memory. Which is sometimes convenient, because we can use fragments of memory, +that could be inaccessible to the vector. + + +### Question: How do list elements know about each other's existence? + + +Each list item stores a pointer to either the next item (one-way linked list) or the next and previous item (two-way linked list). + + +___ + + +## Operations on `std::list` + +* getting the first and last item in a list + * `front()` + * `back()` +* the beginning and the end of the map + * `begin()` + * `end()` +* information about the number of items in the list + * `size()` +* information whether the list is empty + * `empty()` +* adding an item to the end of the list + * `push_back()` +* NEW adds an item to the beginning of the list + * `push_front()` +* NEW sorting list items (can't use std::sort for list) + * `sort()` + +[Documentation on cppreference.org](https://en.cppreference.com/w/cpp/container/list) + + +___ + +## Question: how do I get to the 10th list item? + +Since each list item knows only about the previous and next items, we can't get to the 10th item that easily. + + +We can access the first item via `front()` or `*begin()` + + +```cpp +int main() { + std::list list {1, 2, 3, 4, 5}; + std::cout << *list.begin(); + std::cout << list.front(); +} +``` + + +___ + +We can access the 10th element by going from 1 to 10. + +```cpp +int main() { + std::list list {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto it = list.begin(); + for (size_t i = 0 ; i < 10 ; ++i) { + ++it; // jump to next element + } + std::cout << *it; +} +``` + + +It takes more time than getting to the 10th element in `std::vector`. + + +___ + +## Task + +Write a function that takes a vector and returns a list that contains the sorted values ​​from the vector. [Download the task][task3] + +```cpp +#include +#include + +// Implement createSortedList +// It should take a vector and return a list of sorted elements +// add proper include :) + +int main() { + std::vector vec{2, 3, 4, 1, 6, 5, 8, 7, 9, 0}; + auto list = createSortedList(vec); + + for (const auto& el : list) + std::cout << el << " "; + + return 0; +} +``` + +[task3]: https://github.com/coders-school/cpp-fundamentals/tree/master/module2/task3.cpp + +___ + +## Question: when is it profitable to use `std::list` and when `std::vector`? diff --git a/module2/presentation_list.md b/module2/05_list.pl.md similarity index 97% rename from module2/presentation_list.md rename to module2/05_list.pl.md index 7bc09a4e..52736dc0 100644 --- a/module2/presentation_list.md +++ b/module2/05_list.pl.md @@ -16,7 +16,7 @@ ___ Lista w przeciwieństwie do wektora jest porozrzucana po pamięci. Co czasami jest wygodne, gdyż możemy wykorzystać fragmenty pamięci, -które mogłyby, by być niedostępne dla wektora. +które mogłyby być niedostępne dla wektora. ### Pytanie: skąd elementy listy wiedzą o swoim wzajemnym istnieniu? @@ -67,7 +67,7 @@ int main() { std::cout << list.front(); } ``` - + ___ diff --git a/module2/06_map.en.md b/module2/06_map.en.md new file mode 100644 index 00000000..51b8e905 --- /dev/null +++ b/module2/06_map.en.md @@ -0,0 +1,156 @@ + + +# C++ basics + +## `std::map` + + + Coders School + + +___ + +## Map, dictionary + +* map is a set of pairs (key, value) +* `std::map` in C++ is equivalent to `dict` from Python + +For example, we create a collection of favorite CDs and arrange them on a shelf. + +Of course, we have a huge number of these CDs and we would like to be able to find the CD easily when we search for it. + +For this purpose, we number all the CDs and write down information on a piece of paper under which number which title is placed. This is how we create a map. + + +```cpp +std::map discs { + {1, "The Lord of the Rings: The Fellowship of the Ring"}, + {2, "The Lord of the Rings: The Two Towers"}, + {3, "The Lord of the Rings: The Return of the King"} +}; +``` + + +The key here is the number, while the value is the title of the movie. + + +___ + +## Operations on `std::map` + +* beginning and end of range + * `begin()` + * `end()` +* information about the number of items in the map + * `size()` +* information if the map is empty + * `empty()` +* access to the item for the specified key + * `operator[key]` +* adding a pair (key, value) to the map if such a pair does not exist in it yet + * `insert({key, value})` + +[Documentation on cppreference.org](https://en.cppreference.com/w/cpp/container/map) + + +___ + +## Question + +What will happen when we call on the mentioned map: + +```cpp +discs[4] = "Harry Potter"; +``` + +Assigning something to a map element with `operator[]` makes it so: + + +* if there is already a value for a given key, we will replace it. +* if there is no value for a given key, we will create a new pair (key, value) + +___ + + +## Let's execute this code + +```cpp +#include +#include +#include + +void Print(const std::map& map) { + for (const auto& pair : map) { + std::cout << pair.first << " | " << pair.second << '\n'; + } +} + +int main() { + std::map discs { + {1, "The Lord of the Rings: The Fellowship of the Ring"}, + {2, "The Lord of the Rings: The Two Towers"}, + {3, "The Lord of the Rings: The Return of the King"} + }; + + Print(discs); + std::cout << "\nAfter adding a new element\n"; + discs[4] = "Harry Potter"; + Print(discs); + std::cout << "\nAfter modification of an element\n"; + discs[4] = "Harry Potter and the Philosopher's Stone"; + Print(discs); +} +``` + +___ + +## Result + +```txt +1 | The Lord of the Rings: The Fellowship of the Ring +2 | The Lord of the Rings: The Two Towers +3 | The Lord of the Rings: The Return of the King + +After adding a new element +1 | The Lord of the Rings: The Fellowship of the Ring +2 | The Lord of the Rings: The Two Towers +3 | The Lord of the Rings: The Return of the King +4 | Harry Potter + +After modification of an element +1 | The Lord of the Rings: The Fellowship of the Ring +2 | The Lord of the Rings: The Two Towers +3 | The Lord of the Rings: The Return of the King +4 | Harry Potter and the Philosopher's Stone +``` + +___ + + +## Task + +Write a function that takes `std::vector` and `std::list` and returns the map `std::map`. [Download the task][task4] + +```cpp +#include +#include +#include +#include + +// Implement createMap. It should take a vector and list and +// return a map of merge them as keys from the vector and values from the list + + +int main() { + std::vector vec{1, 2, 3, 4, 5}; + std::list list{"One", "Two", "Three", "Four", "Five"}; + auto map = createMap(vec, list); + + for (const auto& pair : map) + std::cout << pair.first << " | " << pair.second << '\n'; + + return 0; +} +``` + +[task4]: https://github.com/coders-school/cpp-fundamentals/tree/master/module2/task4.cpp diff --git a/module2/presentation_map.md b/module2/06_map.pl.md similarity index 95% rename from module2/presentation_map.md rename to module2/06_map.pl.md index 4ac90e17..ae418c1c 100644 --- a/module2/presentation_map.md +++ b/module2/06_map.pl.md @@ -16,11 +16,11 @@ ___ * `std::map` w C++ to odpowiednik `dict` z Pythona Przykładowo tworzymy kolekcję ulubionych płyt i układamy je w szafce. - + Oczywiście płyt tych mamy ogromną liczbę i chcielibyśmy móc łatwo odnaleźć płytę, gdy będziemy jej poszukiwać. - + W tym celu numerujemy sobie wszystkie płyty i zapisujemy sobie na kartce informacje, pod jakim numerem znajduje się określony tytuł. W ten sposób tworzymy właśnie mapę. - + ```cpp std::map discs { @@ -29,10 +29,10 @@ std::map discs { {3, "The Lord of the Rings: The Return of the King"} }; ``` - + Kluczem jest tutaj numer, natomiast wartością jest tytuł filmu. - + ___ @@ -53,7 +53,6 @@ ___ [Dokumentacja na cppreference.org](https://en.cppreference.com/w/cpp/container/map) - ___ ## Pytanie diff --git a/module2/07_homework.en.md b/module2/07_homework.en.md new file mode 100644 index 00000000..8708943d --- /dev/null +++ b/module2/07_homework.en.md @@ -0,0 +1,167 @@ + + +# C++ basics + +## Summary + + + Coders School + + +___ + +## What do you remember from today? + +### Write as many keywords as possible in the chat + + +1. What is STL? +2. std::vector +3. for loop over collection +4. std::string +5. std::list +6. std::map + +___ + + +## Homework + +### Post-work + +* If you don't know what `operator %` is then you have to read about it. It will prove useful in homework 🙂 +* Task 1 - AddEven (4 points) +* Task 2 - LCM and GCD (6 points) +* Task 3 - MaxOfVector (5 points) +* Task 4 - GenerateSequence (5 points) + +#### Bonus for punctuality + +For delivering each task before 31/05/2020 (Sunday) until 23:59 you will get 2 bonus points (a total of 8 points for 4 tasks). + +#### [Repo tasks](https://github.com/coders-school/cpp-fundamentals/tree/master/module2/homework) + +___ + +### Pre-work + +* Recall information about pointers, e.g. from [Mr. Zelent's video](https://www.youtube.com/watch?v=0DQl74alJzw) +* [Read about `enum`](http://cpp0x.pl/kursy/Kurs-C++/Typ-wyliczeniowy-enum/318) +* Get interested in the topic of smart pointers and look for information about what is `std::shared_ptr` and `std::unique_ptr` +* Take a look at the files with tests in homework and try to add your own test cases + +___ + +## Task 1 - AddEven + +Write a function that takes `std::vector` and returns the sum of its all even elements. + +Signature - `int addEven(const std::vector& numbers)` + +If you don't know what the function should return in some cases, read the tests. + +### Example + +```cpp +std::vector vec{1, 2, 3, 4, 5}; +auto result = addEven(vec); // result = 6; +``` + +___ + +## Task 2 - LCM and GCD + +Implement two functions - GCD, which finds Greatest Common Divisor, and LCM, which finds the Least Common Multiple of 2 numbers. +Watch out for unusual cases like 0 or negative numbers 🙂 + +### Example + +```cpp +std::cout << "NWW(255, 15) = " << NWW(255, 15) << "\n"; +std::cout << "NWD(255, 15) = " << NWD(255, 15) << "\n"; +``` + +___ + +## Task 3 - MaxOfVector + +Write a function that takes `std::vector` and returns the largest element of this vector. + +### Example + +```cpp +std::vector numbers = {6, 78, 12, 54, -11, 0}; +auto result = maxOfVector(numbers); // result = 78 +``` + +___ + +## Task 4 - GenerateSequence + +Write a function that takes 2 arguments: + +* `int count` +* `int step` + +and returns `std::vector` which has `count` elements and each of them is greater than the previous by `step`. The first element is equal to `step`. + +### Example + +```cpp +auto result = generateSequence(5, 3); // result = {3, 6, 9, 12, 15} +``` + +___ + +#### Bonus for working in pairs + +For delivering tasks together with someone else, you will get an additional 3 points (per person). The commits of both people must be visible in the PR and it must be properly described: + +Title: `Homework C++ basics #2` + +Description: `Authors: @github_nick1, @github_nick2 \n Some additional info` + +All tasks should be delivered on one branch this time. The reporting person will get 2 points for the PR submission alone, but I will compensate this by adding 2 extra points to the other person. +The easiest way is for the second person to clone the repository of the former and the former to write permission to the latter. +You can also add a new remote repository in your previously cloned fork using `git remote add name address`. + +___ + +#### Adding a contributor to the GitHub repo + +![Add Collaborator](https://raw.githubusercontent.com/coders-school/cpp-fundamentals/master/module2/img/add_collaborator.png) + +___ + + + +## Task delivery (difference from Basics #1) + +1. You already have a fork repo [cpp-fundamentals](https://github.com/coders-school/cpp-fundamentals), you can't fork again +2. If you're going to work in a pair, it's easiest if you give the other person permission to push into your repo. Choose `Role: Write` +3. You have already pulled your fork +4. Go to the repo directory - `cd cpp-fundamentals` +5. Add new remote repository - `git remote add coders https://github.com/coders-school/cpp-fundamentals.git` +6. Update the repository from the newly added address - `git fetch coders` +7. Switch to branch module2 - `git checkout module2` +8. You can now send the newly downloaded branch to your repo on GH - `git push origin module2` +9. Create a separate branch for homework - `git checkout -b homework2` +10. Send this branch to GitHub right away, before implementing anything - `git push origin homework2` +11. Implement (alone or together) solutions, making lots of tiny commits. In group work, you can share tasks so as not to get into a parade and create conflicts, but if you want to try the hardcore version right away, do the same task together 🙂 +12. When submitting changes to GitHub, use the command `git push origin homework2` +13. When submitting a Pull Request, select that you want to deliver it to `coders-school/cpp-fundamentals` branch `module2` + +___ + + +## Version for a person using a colleague's fork + +1. Wait for your coworker to complete steps 1-10 +2. Select an option: + * Make `git clone address_repo_coworker` and work on it + * Add a colleague's repo address to your clone repo `git remote add nick address` and download changes from it - `git fetch nick` +3. Switch to the homework2 branch - `git checkout homework2` +4. Build projects, share the work, implement the solution. +5. Send changes to a colleague's GH - `git push nick homework2` +6. A co-worker will report a PR, you don't have to click anything 🙂 +7. In case of problems, you can always switch to independent work diff --git a/module2/presentation_homework.md b/module2/07_homework.pl.md similarity index 100% rename from module2/presentation_homework.md rename to module2/07_homework.pl.md diff --git a/module2/index.en.html b/module2/index.en.html new file mode 100644 index 00000000..a60b83ad --- /dev/null +++ b/module2/index.en.html @@ -0,0 +1,155 @@ + + + + + + + C++ - basics - Coders School + + + + + + + + + + + + + + + +
+
+
+
+ +

C++ basics #2

+ + Coders School + +

Mateusz Adamski

+

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +

Coders School

+ Coders School + +
+
+
+ + + + + + diff --git a/module2/index.html b/module2/index.pl.html similarity index 93% rename from module2/index.html rename to module2/index.pl.html index 794535cd..2ccc89e1 100644 --- a/module2/index.html +++ b/module2/index.pl.html @@ -93,31 +93,31 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
-
-
-
diff --git a/module3/01_scopes.en.md b/module3/01_scopes.en.md new file mode 100644 index 00000000..ef845ba5 --- /dev/null +++ b/module3/01_scopes.en.md @@ -0,0 +1,87 @@ + + +# C++ basics + +## Scope of variables + + + Coders School + + +___ + +## Local variables + +Local variables are variables that are viewed within a scope. + + +```cpp +{ + int local_variable = 5; + // ... +} +local_variable = 10; // error -> local_variable doesn't exists +``` + + +The range is always formed by curly braces, including: + +* only parentheses - { /* ... */ } +* function body - void fun() { /* ... */ } +* conditional statements - if (condition) { /* ... */ } +* loops - while (condition) { /* ... */ } + +___ + +## Global variables + +A global variable is visible to all scopes. We can always refer to it. + + +```cpp +int global_value = 5; + +void foo() { + std::cout << global_value; +} + +int main() { + std::cout << global_value; +} +``` + + +Generating global variables is usually bad practice. + + +___ + +## What will appear on the screen? + +```cpp +int number = 1; + +int main() { + int number = 2; + { + int number = 3; + std::cout << number; + std::cout << ::number; + } + std::cout << number; + std::cout << ::number; +} +``` + + +### 3121 + + +___ + +## Overriding names + +* we can have many variables with the same name if they are in different scopes + * to avoid ambiguity this is rather not recommended +* a name from the local scope always overrides the name from a wider scope (e.g. global) +* you can refer to names from global scope using :: (scope resolution operator) diff --git a/module3/presentation_scopes.md b/module3/01_scopes.pl.md similarity index 100% rename from module3/presentation_scopes.md rename to module3/01_scopes.pl.md diff --git a/module3/02_references.en.md b/module3/02_references.en.md new file mode 100644 index 00000000..aaf98c99 --- /dev/null +++ b/module3/02_references.en.md @@ -0,0 +1,129 @@ + + +# C++ basics + +## References + + + Coders School + + +___ + +## & + +Magic symbol `&` stands for reference. + +```cpp +int value = 5; +int & number = value; +``` + +The above notation gives a variable `number` type `int&`, which is a reference to a type `int`. + + +It doesn't matter if we stick the reference to the type or name of the variable, but the reference is a separate type, so we suggest not to stick it to the variable name. + + +```cpp +int& number = value; // left +int &number = value; // right (not recommended) +int & number = value; // neutral +``` + +___ + +### What is a reference? + +Let's look at a code snippet. + +```cpp +int number = 5; +int& refer = number; + +std::cout << refer << '\n'; // 5 +std::cout << ++refer << "\n"; // 6 +std::cout << number << "\n"; // 6 +``` + +* The reference refers to an existing object +* If we create an object int value through references int& reference = value we will be able to refer to it directly. +* Reference is another, additional name for the same variable (alias) +* Modifying a reference = modifying the original object + +___ + +### What do we gain this way? + +* We don't need to copy variables. It is enough to provide references. + * This way, we can freely read the value of this variable in many places in the program, without unnecessarily copying it. +* A reference takes up as much in memory as an address (4 or 8 bytes). +* Building a reference to a type int (usually 4 bytes) does not always make sense from optimization point, unless you want to modify this element inside a function. +* Passing arguments by reference will make more sense when we get to know classes and objects 🙂 + +[How much space does a reference take? - stackoverflow.com](https://stackoverflow.com/questions/1179937/how-does-a-c-reference-look-memory-wise) + + +___ + +### How to pass an element by reference? + +```cpp +void foo(int& num) { + std::cout << num; // good + num += 2; // good +} +``` + + +If we want to be sure that the function will not modify the value (we want to pass it read-only), we add `const`. + + +```cpp +void bar(const int& num) { + std::cout << num; // good + num += 2; // compilation error, num is const reference +} +``` + + +We call function simply like this: + + +```cpp +int num = 5; +foo(num); +bar(num); +``` + + +___ + +## Task + +Implement the function `foo()`. It has to modify the text provided. On the screen we want to see `"Other string"`. + +```cpp +#include +#include + +// TODO: Implement foo() +// It should modify passed string to text "Other string" + +int main() { + std::string str("Some string"); + foo(str); + std::cout << str << '\n'; + return 0; +} +``` + +___ + +## Summary + +* reference is an alias (another name for a variable) +* a reference modification is a modification of the original object +* when passing a parameter by reference: + * we avoid unnecessary copies + * object modification will result in modification of the original passed to the function diff --git a/module3/presentation_references.md b/module3/02_references.pl.md similarity index 97% rename from module3/presentation_references.md rename to module3/02_references.pl.md index eb39a760..7a2b1003 100644 --- a/module3/presentation_references.md +++ b/module3/02_references.pl.md @@ -19,7 +19,7 @@ int value = 5; int & number = value; ``` -Powyższy zapis oznacza zmienną `num` typu `int&`, czyli referencję na typ `int`. +Powyższy zapis oznacza zmienną `number` typu `int&`, czyli referencję na typ `int`. Nie ma znaczenia, czy referencję dokleimy do typu, czy nazwy zmiennej, ale referencja jest oddzielnym typem, więc sugerujemy nie doklejać jej do nazwy zmiennej. @@ -59,7 +59,7 @@ ___ * W ten sposób możemy swobodnie w wielu miejscach programu odczytywać wartość tej zmiennej, bez zbędnego jej kopiowania. * Referencja zajmuje w pamięci tyle, ile zajmuje adres (4 lub 8 bajtów). * Tworzenie referencji do typu int (zazwyczaj 4 bajty) nie zawsze ma sens optymalizacyjny, chyba, że chcemy zmodyfikować ten element wewnątrz funkcji. -* Przekazywanie argumentów przez referencje nabierze więcej sensu, kiedy poznamy już klasy i obiekty :) +* Przekazywanie argumentów przez referencje nabierze więcej sensu, kiedy poznamy już klasy i obiekty 🙂 [Ile miejsca zajmuje referencja? - stackoverflow.com](https://stackoverflow.com/questions/1179937/how-does-a-c-reference-look-memory-wise) diff --git a/module3/03_pointers.en.md b/module3/03_pointers.en.md new file mode 100644 index 00000000..d3ede7c7 --- /dev/null +++ b/module3/03_pointers.en.md @@ -0,0 +1,275 @@ + + +# C++ basics + +## Pointers + + + Coders School + + +___ + +## Pointers - an analogy + +In addition to references, there are also pointers. Pointers work much like references. + + +Imagine you are planning a trip to Majorca. We get on the plane and fly. +On the destination, it turns out that we have forgotten the hotel address 😦 +In order to find it, we have to call the travel agency, wait for the service, explain the whole complex story, and finally, after a long time, we get the address of our hotel. +The process of obtaining this information was time-consuming for us. + + +Let's imagine, however, that we have previously saved the address of our hotel on our phone. To remember where it was, we just need to check the phone. The process took much less time. + + +___ + +## Pointers in C++ + +It is similar in C++. Pointers are used to indicate the location in memory where the desired object is located. + + +The processor does not have to ask the memory bus each time where the given variable is because it knows immediately what its address is (we avoid intermediaries like a phone call to the service office). + + +Also, if a function takes a pointer, it doesn't have to copy the entire contents of the object, which is time consuming. You can indicate where this object already exists much faster. + + +___ + +### How do I pass a variable by a pointer? + +```cpp +void foo (int* num) { + std::cout << *num; // good + *num += 2; // good +} +``` + + +When we want to be sure that no one will modify the value for us (we want to pass it read-only), we add `const`. + + +```cpp +void bar (int const* num) { + std::cout << *num; // good + *num += 2; // compilation error, num is a pointer to const +} +``` + + +This is how you call this function: + + +```cpp + int num = 5; + foo(&num); + bar(&num); +``` + + +___ + +## Where to put `const`? + +### What is this? + +```cpp +const int * ptr; +``` + + +A pointer to a constant (`const int`). + + +```cpp +int const * ptr; +``` + + +Also the pointer to the constant (`const int = int const`). + + +```cpp +int * const ptr; +``` + + +A constant pointer to a variable (`int`). + + +___ + +## Constant pointers versus pointers on constant + +```cpp +int const * const ptr; +const int * const ptr; +``` + + +Constant pointer to constant (`int const = const int`). + + +This is a common question from job interviews. For pointer to be constant, `const` must be after the asterisk. + + +___ + +## Differences + +### Pointer to a constant + +```cpp +const int * ptr = new int{42}; +*ptr = 43; // compilation error: assignment of read-only location ‘* ptr’ +ptr = nullptr; // ok +``` + +* We cannot modify the object pointed to by the pointer + * Referring with `*` cannot modify the object +* We can modify the pointer itself, e.g. to point to another object + * Referring without `*` can modify the pointer + +___ + +## Differences + +### Constant pointer + +```cpp +int * const ptr = new int{42}; +*ptr = 43; // ok +ptr = nullptr; // compilation error: assignment of read-only variable ‘ptr’ +``` + +* We can modify the object pointed to by the pointer + * Referring with `*` can modify the object +* We cannot modify the pointer itself, e.g. to point to another object + * Referring without `*` cannot modify the pointer + +___ + +### Constant pointer to constant + +```cpp +const int * const ptr = new int{42}; +*ptr = 43; // compilation error: assignment of read-only location ‘* ptr’ +ptr = nullptr; // compilation error: assignment of read-only variable ‘ptr’ +``` + +* We cannot modify the object pointed to by the pointer + * Referring with `*` cannot modify the object +* We cannot modify the pointer itself, e.g. to point to another object + * Referring without `*` cannot modify the pointer + +___ + + +## Task + +Implement functions `foo()` and `bar()`. + +`foo()` should modify the value passed by the pointer to 10, and `bar()` to 20. + +Can either `foo()` or `bar()` take the pointer to a constant or constant pointer? + +```cpp +#include + +// TODO: Implement foo() and bar() +// foo() should modify value under passed pointer to 10 +// bar() should modify value under passed pointer to 20 +// Can we have a pointer to const or a const pointer? +int main() { + int number = 5; + int* pointer = &number; + std::cout << number << '\n'; + foo(&number); + std::cout << number << '\n'; + bar(pointer); + std::cout << number << '\n'; + + return 0; +} +``` + +___ + + +## Differences between pointer and reference + +### References + +* We refer to references in the same way as to an ordinary object - by name +* To get the item pointed to by the pointer we need to add * before the name of the indicator + +### Passing as an argument + +* The argument is a reference or a regular variable (copy) - we pass the name +* The argument is a pointer and we pass the variable - we have to add & before the variable name. + +### Symbols + +* Symbol * (dereference operator) gives access to the referenced object +* If we don't put * before the pointer we get the address of the pointed object +* Symbol & means getting the address of our variable +* The above makes sense because the pointer points to a memory location (the address of the pointed object) + +___ + +## Differences in the code + +```cpp +void copy(int a) { a += 2; } +void ref(int& a) { a += 2; } +void ptr(int* a) ( *a += 2; ) + +void example() { + int c = 10; + int& r = a; + int* p = &a; // typically int* p = new int{10}; + copy(c); + copy(r); + copy(*p); + ref(c); + ref(r); + ref(*p); + ptr(&c); + ptr(&r); + ptr(p); +} +``` + +___ + +## What does `*` mean in code? + +```cpp +int a = 5 * 4; // arithmetic operation - multiplying +int* b = &a; // next to type - pointer to the type +int *c = &a; // next to type - pointer to the type +std::cout << *b; // next to pointer - access to object +int fun(int* wsk); // in function argument - passing pointer (address) +``` + + +## What does `&` mean in code? + + +```cpp +int a = 5 & 4; // as arithmetic operation - bitwise AND +int& b = a; // next to type - reference on type +int &c = a; // next to type - reference on type +std::cout << &a; // next to variable - address of this variable in memory +int fun(int& ref); // in function argument - passing the address +``` + + +___ + +## Important rule + +Unless absolutely necessary, we don't use pointers at all. diff --git a/module3/presentation_pointers.md b/module3/03_pointers.pl.md similarity index 99% rename from module3/presentation_pointers.md rename to module3/03_pointers.pl.md index 4e64fa30..052b0cc8 100644 --- a/module3/presentation_pointers.md +++ b/module3/03_pointers.pl.md @@ -16,7 +16,7 @@ Poza referencjami istnieją także wskaźniki. Wskaźniki działają podobnie ja Wyobraźmy sobie, że planujemy wycieczkę na Majorkę. Wsiadamy do samolotu i lecimy. -Na miejscu okazuje się, ze zapomnieliśmy jaki jest adres hotelu :( +Na miejscu okazuje się, ze zapomnieliśmy jaki jest adres hotelu 😦 W celu znalezienia go musimy zadzwonić do biura podróży, poczekać na obsługę, wytłumaczyć całą zawiłą historię, aż w końcu po długim czasie otrzymujemy adres naszego hotelu. Proces zdobycia tych informacji był dla nas czasochłonny. @@ -72,7 +72,7 @@ Wywołanie funkcji to: ___ -## Gdzie dać const? +## Gdzie dać `const`? ### Co to jest? diff --git a/module3/04_hazards.en.md b/module3/04_hazards.en.md new file mode 100644 index 00000000..e94bdc46 --- /dev/null +++ b/module3/04_hazards.en.md @@ -0,0 +1,251 @@ + + +# C++ basics + +## Threats + +### while using references and pointers + + + Coders School + + +___ + +## Empty pointers + +```cpp +int* a = nullptr; +std::cout << *a; +``` + +Accessing a variable pointed to by an empty pointer is undefined behavior. + + +Always mark an empty pointer with `nullptr`. + + +We do not use `NULL` known from the C language or earlier standards, because it is less secure. + + +```cpp +void foo(int); +foo(NULL); // bad - no error +foo(nullptr); // good - compilation error +``` + + +___ + +## Uninitialized pointers + +```cpp +int* a; +std::cout << *a; +``` + +Pointer `a` contains the so-called garbage. +Accessing the object pointed to it is undefined behavior. + + +___ + +## References to deleted variables + +As we already know, local variables are removed when they are out of the scope we created them in. +You can already guess what problems pointers and references will cause us when they still exist and the object they refer to is already destroyed. +It will be at best "Crash" and "Undefined behavior" at worst. + +### How to prevent such cases? + + +We must always ensure that the lifetime of the variable is longer than the lifetime of its pointer or reference. + + +___ + +## Removed variables - example + +```cpp +std::vector vec; + +void createAndAddToVec(int amount) { + for (int i = 0 ; i < amount ; ++i) { + vec.push_back(&i); + } + // local variable i does not exist here anymore + // vec contains addresses to not existing local variables +} + +int main() { + createAndAddToVec(5); + for (const auto& el : vec) { + std::cout << *el << '\n'; // UB + } +} +``` + +___ + +## How to deal with such a problem? + +The answer may be dynamically allocated memory. + + +The easiest way to do this is by using a library `#include ` that has `std::shared_ptr`. + + +This pointer is called _intelligent_ for a reason. It is responsible for managing dynamic memory and releases the resource itself when we no longer need it. + + +### How to create such pointer? + + +```cpp +auto ptr = std::make_shared(5); // preferred +auto ptr = std::shared_ptr(new int{5}); +``` + + +___ + +## Corrected code snippet + +```cpp +std::vector> vec; // previously: std::vector vec; + +void createAndAddToVec(int amount) { + for (int i = 0 ; i < amount ; ++i) { + vec.push_back(std::make_shared(i)); + // previously: vec.push_back(&i); + + // the same in 2 lines: + // auto num = std::make_shared(i); + // vec.push_back(num); + } +} + +int main() { + createAndAddToVec(5); + for (const auto& el : vec) { + std::cout << *el << '\n'; + } +} +``` + +___ + + +## Task + +Write a function `foo()`. It is supposed to accept `shared_ptr` on `int` and assign value 20 to the object pointed to by it. + +Also `foo()` has to display the value of the `int` pointed to by the pointer and the number of `shared_ptrs` that point to this object. + +Also display above in `main()` before and after calling `foo()`. + +```cpp +#include +#include + +// TODO: Implement foo() +// It should take shared_ptr to int and assign value 20 to the pointed int. +// It should also display the value of this int and the number of how many pointers are pointing to it - use `use_count()`. +// Display the same information in main() before and after calling foo() + +int main() { + std::shared_ptr number = std::make_shared(10); + // display the value under number pointer and use_count() of it + foo(number); + // display the value under number pointer and use_count() of it + + return 0; +} +``` + +___ + +## Task + +Write a function `foo()`. It is supposed to take 2 values ​​of the type `int` and return their product as `shared_ptr`. Check how many owners `shared_ptr` has. + +```cpp +#include + +// TODO: Implement foo() +// It should take 2 int values and return their product as a shared_ptr. +// Additionally, check how many owners are there. + +int main() { + auto number = foo(10, 20); + std::cout << "num: " << *number << " | owners: " << number.use_count() << "\n"; + + return 0; +} +``` + +___ + +## Intelligent pointers as solution to all problems? + +Now that we've created a smart pointer, we don't have to worry about the variable's lifetime. +We can safely print these values ​​after exiting the function. + + +If a function needs to accept a raw pointer, i.e. `int* i` we can do it +using the function `std::shared_ptr::get()` as in the example: + + +```cpp +void foo(int* num) { + do_sth(num); +} + +int main() { + auto ptr = std::make_shared(5); + foo(ptr.get()) +} +``` + + +___ + + +## The danger returns + +```cpp +void foo(int* num) { + if (num) { + do_sth(num); + } +} + +int main() { + auto ptr = std::make_shared(5); + int* raw = ptr.get(); + ptr.reset(); // delete object, deallocate memory + foo(raw); // problem, dangling pointer is passed + foo(ptr.get()); // not a problem, nullptr is passed +} +``` + +If all objects of `shared_ptr` referencing to this variable are deleted, the resource is released. + + +Our raw pointer we downloaded earlier with `get()` will have an address for a resource that no longer exists. + + +Attempting to use it will result in an UB or a crash. Be very careful with raw pointers. + + +___ + +## Conclusions + +* pointers may not point to anything (nullptr), the references must point to some previously created object +* pointers and references can be dangerous (more often pointers) if they are associated with objects that no longer exist + * these are the so-called dangling pointers/references +* The reference cannot be assigned an object other than the one specified during its initialization +* pointers can be assigned to new addresses to point to other objects (except constant pointers) +* it's better not to use raw pointers +* it's better to use smart pointers diff --git a/module3/presentation_hazards.md b/module3/04_hazards.pl.md similarity index 98% rename from module3/presentation_hazards.md rename to module3/04_hazards.pl.md index aeeb5bba..7e0f7c8e 100644 --- a/module3/presentation_hazards.md +++ b/module3/04_hazards.pl.md @@ -138,7 +138,7 @@ ___ ## Zadanie -Napisz funkcję `foo()`. Ma ona przyjmować shared_ptr na int i ma przypisać wartość 20 do wskazywanego przez niego obiektu. +Napisz funkcję `foo()`. Ma ona przyjmować `shared_ptr` na `int` i ma przypisać wartość 20 do wskazywanego przez niego obiektu. Ponadto `foo()` ma wyświetlić wartość inta wskazywanego przez wskaźnik oraz liczbę shared_ptrów, które wskazują na ten obiekt. diff --git a/module3/05_enums.en.md b/module3/05_enums.en.md new file mode 100644 index 00000000..81eb6f42 --- /dev/null +++ b/module3/05_enums.en.md @@ -0,0 +1,161 @@ + + +# C++ basics + +## `enum` and `enum class` + + + Coders School + + +___ + +## Enumerated type + +`enum` is an enumerated type. + +Also `enum class` introduced in C++11, which is called a strong enumeration type. + +### Example + +Suppose we write washing machine software. +We would also like to create an interface that returns an error number, e.g .: + + +* lack of water +* load is too heavy +* problem with bearings +* pump lock + +For this we use type `enum` or better - `enum class`. + + +___ + +### Example implementation + +```cpp +enum ErrorCode { + lack_of_water; + too_much_load; + bearing_problem; + block_of_pump; +}; + +// or better ↓ + +enum class ErrorCode { + lack_of_water; + too_much_load; + bearing_problem; + block_of_pump; +}; +``` + +___ + +## Numbering + +Type `enum` underneath is numbered from `0` to `n - 1`, where `n` is the number of elements. + + +If we want to set different values, we have to do it manually: + + +```cpp +enum class ErrorCode { + lack_of_water = 333; + to_much_load; // will be 334 + bearing_problem = 600; + block_of_pump; // will be 601 +} +``` + + +___ + +## `enum` vs `enum class` + +The main difference between `enum` and `enum class` is that we can implicitly convert the type `enum` to `int` (it's an enumerated type after all). + +However, type `enum class` we can convert to `int`, only by explicit casting. We are not going to discuss casting for now. It's just worth to +remember that we do this by calling: + + +```cpp +int num = static_cast(ErrorCode::lack_of_water) +``` + + +In what other cases would you use the enumeration type? + + +___ + + +## `enum` vs `enum class` + +The second difference - for `enum` we may have a name conflict, whereas for `enum class` not. + +```cpp +enum Color { + RED, // 0 + GREEN, // 1 + BLUE // 2 +}; +``` + + +```cpp +enum TrafficLight { + GREEN, // 0 + YELLOW, // 1 + RED // 2 +}; +``` + + +```cpp +auto lightColor = getColor(); +if (lightColor == RED) { // 0 or 2? + stop(); +} else { + go(); +} +``` + + +___ + + +## Example usage of `enum class` + +To avoid a name conflict, we use `enum class`. + +```cpp +enum class Color { + RED, + GREEN, + BLUE, +} +``` + + +```cpp +enum class TrafficLight { + GREEN, + YELLOW, + RED +} +``` + + +```cpp +auto lightColor = getColor(); +if (lightColor == TrafficLight::RED) { + stop(); +} else { + go(); +} +``` + diff --git a/module3/presentation_enums.md b/module3/05_enums.pl.md similarity index 98% rename from module3/presentation_enums.md rename to module3/05_enums.pl.md index 00b0b3f1..15ff4e6d 100644 --- a/module3/presentation_enums.md +++ b/module3/05_enums.pl.md @@ -26,7 +26,7 @@ Chcielibyśmy utworzyć także interfejs zwracający numer błędu np: * problem z łożyskami * blokada pompy -W celu warto użyć typu `enum` lub lepiej - `enum class`. +W tym celu warto użyć typu `enum` lub lepiej - `enum class`. ___ diff --git a/module3/06_stl_algo_iter.en.md b/module3/06_stl_algo_iter.en.md new file mode 100644 index 00000000..8f1e2e5e --- /dev/null +++ b/module3/06_stl_algo_iter.en.md @@ -0,0 +1,209 @@ + + +# C++ basics + +## Introduction to STL + +### Algorithms and iterators + + + Coders School + + +___ + +Let's go back to begin and end iterators for a moment. As we remember, they returned the beginning and the end of our container, e.g. std :: vector. +in fact, begin and end returns to us an iterator pointing to 1 element of our container and to the element immediately after the last element. (here a photo of a few squares and marked as indicated by the begin and the end). + +What is an iterator? The easiest way is an element that points to a container element. We can freely increment it, i.e. move to the next elements of the container. We distinguish several types of iterators, but at the moment we will only deal with one. +It is called random access iterator. It is important to us that such an iterator can freely refer to any element in our container. We get the random iterator when we call begin or end for std :: vector. To refer to the element the iterator points to, we use `*`. + +What will be listed in the following lines? +``` + std::vector vec {1, 2, 3, 4, 5, 6}; + auto random_iterator = vec.begin(); + std::cout << *random_iterator; + ++random_iterator; + std::cout << *random_iterator; + random_iterator += 2; + std::cout << *random_iterator; +``` + +The STL library has over 100 algorithms, one of them are: + * std :: sort, + * find, + * all_of, + * any_off, + * fill, + * min_max_element; + * for_each. + + All algorithms work for iterators, e.g .: + ``` + template< class RandomIt > + void sort( RandomIt first, RandomIt last ); +``` +The sort algorithm requires 2 iterators to sort a container. Most often the beginning and the end of the range. Such an algorithm is called as follows: +``` + int main() + { + std::vector vec = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3}; + + std::sort(vec.begin(), vec.end()); + for (auto element : vev) { + std::cout << element << " "; + } + std::cout << '\n'; + } +``` +Sorting is really easy. Fun fact for those wondering why you can't just give std :: sort (vec). +It took several years for the standardization committee to notice that this option was useful and that it was only available in the C ++ 20 standard. + +- Question: What construction can std :: find have? + +``` +template< class InputIt, class T > +InputIt find( InputIt first, InputIt last, const T& value ); +``` + +- Question: How to invoke such an algorithm? + +``` +int main() +{ + int n1 = 3; + int n2 = 5; + + std::vector v{0, 1, 2, 3, 4}; + + auto result1 = std::find(std::begin(v), std::end(v), n1); + auto result2 = std::find(std::begin(v), std::end(v), n2); + + if (result1 != std::end(v)) { + std::cout << "v contains: " << n1 << '\n'; + } else { + std::cout << "v does not contain: " << n1 << '\n'; + } + + if (result2 != std::end(v)) { + std::cout << "v contains: " << n2 << '\n'; + } else { + std::cout << "v does not contain: " << n2 << '\n'; + } +} +``` + +You can see a line in the code above `result1 != std::end(v)` this is nothing but checking whether a number has been found. +The algorithm returns `std::end` when no item is found. + +- Question: What design can it have `all_of` and `any_of` ? + +``` +template< class InputIt, class UnaryPredicate > +bool all_of( InputIt first, InputIt last, UnaryPredicate p ); +``` +``` +template< class InputIt, class UnaryPredicate > +bool any_of( InputIt first, InputIt last, UnaryPredicate p ); +``` + +UnaryPredicate -> specifies the condition that must be met. For example, we want to check if all numbers are less than 10, we can write a function: `bool isLessThen5(int num) { return num < 5; }` +When we want to check if no number is greater than 10, we can write a function: `bool isGreaterThen10(int num) { return num > 10; }` + +Example of use: +``` +#include +#include +#include +#include + +bool isLessThen5(int num) { return num < 5; } +bool isGreaterThen10(int num) { return num > 10; } + +int main() { + std::vector vec{1, 2, 3, 4, 5, 6}; + + if (std::all_of(vec.begin(), vec.end(), isLessThen5)) { + std::cout << "Every numbers in vector are less then 5\n"; + } else { + std::cout << "Some numbers in vector aren't less then 5\n"; + } + + if (std::none_of(vec.begin(), vec.end(), isGreaterThen10)) { + std::cout << "None of numbers in vector are grater then 10\n"; + } else { + std::cout << "Some numbers in vector are grater then 10\n"; + } + +} +``` + +- Question: What can the std :: fill algorithm have? +``` +template< class ForwardIt, class T > +void fill( ForwardIt first, ForwardIt last, const T& value ); +``` + +The fill algorithm fills the entire range of a container with some number. +- Question: How to fill a vector with 10 elements equal to 5? +``` + int main() { + std::vector v(10); + std::fill(v.begin(), v.end(), 5); + + for (auto elem : v) { + std::cout << elem << " "; + } + std::cout << "\n"; + } +``` + +- Question: What construction can the min_max_element algorithm have? +``` +template< class ForwardIt > +std::pair + minmax_element( ForwardIt first, ForwardIt last ); +``` +- Question: How do I find the smallest and largest element in std :: vector? +``` + int main() { + const auto v = { 3, 9, 1, 4, 2, 5, 9 }; + const auto [min, max] = std::minmax_element(begin(v), end(v)); + + std::cout << "min = " << *min << ", max = " << *max << '\n'; + } +``` + +- Question: What can the std :: for_each algorithm have? +``` +template< class InputIt, class UnaryFunction > +UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f ); +``` +- Question: What could the predicate for such an algorithm look like? +``` +void(Type& element) { + do_sth_with_element(element); +} +``` +- Question: How do I add the number 1 to each vector element? +``` + +void plus1(int& element) { element += 1; } + +int main() { + std::vector vec {1,2,3,4,5}; + std::for_each(vec.begin(), vec.end(), plus1); +} +``` +- The question and how to list its elements? +``` + +void plus1(int& element) { element += 1; } +void print(const int& element) { std::cout << element << '\n'; } + +int main() { + std::vector vec {1,2,3,4,5}; + std::for_each(vec.begin(), vec.end(), plus1); + std::for_each(vec.begin(), vec.end(), print); +} +``` diff --git a/module3/presentation_stl_algo_iter.md b/module3/06_stl_algo_iter.pl.md similarity index 95% rename from module3/presentation_stl_algo_iter.md rename to module3/06_stl_algo_iter.pl.md index 043006e5..285a3f48 100644 --- a/module3/presentation_stl_algo_iter.md +++ b/module3/06_stl_algo_iter.pl.md @@ -16,7 +16,7 @@ Wróćmy na chwilę do iteratorów begin oraz end. Jak pamiętamy zwracały one tak naprawdę to begin i end zwraca nam iterator wskazujący na 1 element naszego kontenera oraz na element znajdujący się tuż za ostatnim elementem. (tutaj zdjęcie kilku kwadracików i zaznaczone na co wskazuje begin a na co end). Czym jest iterator? Najprościej jest to element, który wskazuje nam na element kontenera. Możemy go swobodnie inkrementować, czyli przesuwać się do kolejnych elementów kontenera. Rozróżniamy kilka typów iteratorów ale na ten moment będziemy zajmować się tylko jednym. -Ma on nazwę random acces iterator. Dla nas ważne jest to, że taki iterator może swobodnie odwoływać się do dowolnego elementu w naszym kontenerze. Random itarator otrzymujemy między innymi gdy wywołamy begin lub end dla std::vector. Aby odwołać się do elementu, na który wskazuje iterator używamy `*`. +Ma on nazwę random access iterator. Dla nas ważne jest to, że taki iterator może swobodnie odwoływać się do dowolnego elementu w naszym kontenerze. Random iterator otrzymujemy między innymi gdy wywołamy begin lub end dla std::vector. Aby odwołać się do elementu, na który wskazuje iterator używamy `*`. Co zostanie wypisane w kolejnych linijkach? ``` diff --git a/module3/07_homework.en.md b/module3/07_homework.en.md new file mode 100644 index 00000000..3f791078 --- /dev/null +++ b/module3/07_homework.en.md @@ -0,0 +1,146 @@ + + +# C++ basics + +## Summary + + + Coders School + + +___ + +## What do you remember from today? + +### Write as many keywords as possible in the chat + + +1. Scopes +2. References +3. Pointers +4. Threats while using references and pointers +5. Enumerated type enum and enum class + +___ + + +## Homework + +### Post-work + +* Task 1 - PasswordCheck +* Task 2 - VectorOfSharedPointers + +#### Bonus for punctuality + +For delivering each task before 7 June 2020 (Sunday) until 23:59 you will get 2 bonus points for each task + +#### [Repo tasks](https://github.com/coders-school/cpp-fundamentals/tree/master/module3/homework) + +___ + +### Pre-work + +* [Playlist on YT regarding STL](https://www.youtube.com/playlist?list=PL5jc9xFGsL8G3y3ywuFSvOuNm3GjBwdkb) - watch as much as you can 🙂 +* Recall what a class is and how it is written - [watch the video of Mirosław Zelent](https://www.youtube.com/watch?v=aDXjubGK0jU). WARNING! From the 22nd minute you can observe some bad practices 😃. Try to guess which ones. + +___ + +## The PasswordCheck task + +You create a password rule checker that receives data from a front-end contact form. The entire module exists of several functions. Their declarations are to be included in the header file `validation.hpp` and the implementations in the source file `validation.cpp`. Your tasks are: + +1. Define a new type in the header file `ErrorCode` with possible values ​​for errors when setting a new password (1 point) + + * Ok + * PasswordNeedsAtLeastNineCharacters + * PasswordNeedsAtLeastOneNumber + * PasswordNeedsAtLeastOneSpecialCharacter + * PasswordNeedsAtLeastOneUppercaseLetter + * PasswordsDoesNotMatch + +___ + + +## PasswordCheck Task continued + +2. Write a function `getErrorMessage()` which will take the defined type of error code and return the appropriate message as a string. (1 point) +3. Write a function `doesPasswordsMatch()` which will receive two passwords and check if they are identical. It should return an appropriate bool value. (1 point) +4. Write a function `checkPasswordRules()` which will accept one password and randomly return one of the codes `PasswordNeedsAtLeast*` or `Ok`. (2 points) +5. Write a function `checkPassword()`. It should accept two passwords and use the function `doesPasswordsMatch()` to determine if the passwords match. If they do not match, it will return the code `PasswordsDoesNotMatch` otherwise, it should return the error code returned by the function call `checkPasswordRules()`. (2 points) +6. For ambitious (optional) - implement in function `checkPasswordRules()` with true validation of the remaining cases which are given as error codes. Ideally, you should use the features of [ header](https://en.cppreference.com/w/cpp/header/cctype) and the algorithm `std::any_of`. Add/modify appropriate tests. (4 points) + +Total: 7 points (+4 for ambitious, +2 for delivery before 7 June 2020 23:59, +3 points/person for working in a pair) + +___ + +## PasswordCheck Task - Example + +```cpp +int main() { + std::string password; + std::string repeatedPassword; + std::cout << "Set new password: "; + std::cin >> password; + std::cout << "Repeat password: "; + std::cin >> repeatedPassword; + auto result = checkPassword(password, repeatedPassword); + std::cout << getErrorMessage(result) << '\n'; + + return 0; +} +``` + +___ + + +## The VectorOfSharedPointers task + +Write a program that will contain 5 functions. Declarations should be included in the header file `vectorFunctions.hpp` and the implementations in the source file `vectorFunctions.cpp`. Create these files. + +* `std::vector> generate(int count)` which will generate a vector of shared pointers with numbers from `0` to `count` +* `void print()` which will print all the elements from the vector pointers +* `void add10()` which will take a vector and add `10` to each number +* `void sub10()` which will take a constant pointer to `int` and subtract `10` from this element +* `void sub10();` Which will take a vector of shared pointers and call the above function overload for each element `sub10()` + +Total: 5 points (1 for each function) (+2 for delivery before 7 June 2020 11:59 pm, +3 points/person for working in a pair) + +### Example of use + +```cpp +int main() { + auto vec = generate(10); + print(vec); + add10(vec); + print(vec); + sub10(vec); + print(vec); +} +``` + +___ + + +## Task delivery + +1. If you don't already have the cpp-fundamentals repo fork and coders remote attached to it, see the earlier C++ Basics #2 and #1 homeworks. +2. Update your repo from coders remote - `git fetch coders` +3. Switch to branch module3 - `git checkout module3` +4. Send branch module3 to your fork - `git push origin module3` +5. Create a separate branch for homework - `git checkout -b homework3` +6. Send this branch to the fork right away, before starting the implementation - `git push origin homework3` +7. Start the implementation alone or in pair. +8. Before you submit your changes with `git push origin homework3` sync with the fork to check if the other person has already delivered something - `git pull --rebase origin homework3`. If there are conflicts, resolve them. +9. When submitting a Pull Request, click that you want to deliver it to `coders-school/cpp-fundamentals` branch `module3`. Describe it appropriately adding information about the authors of the code. + +___ + +## Next lessons + +* Review of C++ basics and tools +* Discussion of solutions to previous tasks +* Overview of the most common errors based on Code Review +* Q&A +* Comments +* Group consultation on Discord diff --git a/module3/presentation_homework.md b/module3/07_homework.pl.md similarity index 99% rename from module3/presentation_homework.md rename to module3/07_homework.pl.md index 659ea77b..4b9cd651 100644 --- a/module3/presentation_homework.md +++ b/module3/07_homework.pl.md @@ -41,8 +41,8 @@ ___ ### Pre-work -* [Playlista na YT odnośnie STLa](https://www.youtube.com/playlist?list=PL5jc9xFGsL8G3y3ywuFSvOuNm3GjBwdkb) - obejrzyj ile możesz :) -* Przypomnij sobie czym jest klasa i jak się ją pisze - [obejrzyj wideo Mirosława Zelenta](https://www.youtube.com/watch?v=aDXjubGK0jU). UWAGA! Od 22 minuty możesz zaobserwować trochę złych praktyk :D Spróbuj odgadnąć jakich. +* [Playlista na YT odnośnie STLa](https://www.youtube.com/playlist?list=PL5jc9xFGsL8G3y3ywuFSvOuNm3GjBwdkb) - obejrzyj ile możesz 🙂 +* Przypomnij sobie czym jest klasa i jak się ją pisze - [obejrzyj wideo Mirosława Zelenta](https://www.youtube.com/watch?v=aDXjubGK0jU). UWAGA! Od 22 minuty możesz zaobserwować trochę złych praktyk 😃 Spróbuj odgadnąć jakich. ___ diff --git a/module3/index.en.html b/module3/index.en.html new file mode 100644 index 00000000..00addc21 --- /dev/null +++ b/module3/index.en.html @@ -0,0 +1,154 @@ + + + + + + + C++ - basics - Coders School + + + + + + + + + + + + + + + +
+
+
+
+ +

C++ basics #3

+ + Coders School + +

Mateusz Adamski

+

Łukasz Ziobroń

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +

Coders School

+ Coders School + +
+
+
+ + + + + + diff --git a/module3/index.html b/module3/index.pl.html similarity index 93% rename from module3/index.html rename to module3/index.pl.html index f9cb57ce..ee830c8b 100644 --- a/module3/index.html +++ b/module3/index.pl.html @@ -92,31 +92,31 @@

Łukasz Ziobroń

You can change the port by using npm start -- --port=8001. --> -
-
-
-
-
- -