diff options
| Commit | f1f2d34e28932486f9f9732be8ffd39b15f93404 (patch) | |
|---|---|---|
| Author | 2023-10-12 15:15:08 +0300 | |
| Committer | 2023-10-12 15:15:08 +0300 | |
| Files | c4dd51f8154254d0300c2a32ae8c0ef7feb093fb | |
| syndamia.com-f1f2d34e28932486f9f9732be8ffd39b15f93404.tar syndamia.com-f1f2d34e28932486f9f9732be8ffd39b15f93404.tar.gz syndamia.com-f1f2d34e28932486f9f9732be8ffd39b15f93404.zip | ||
| Parent | 15158a091cb13abf44ec83d48a74c67ad875c38b (diff) | |
(te/upp-2023/w2) Added revision
1 files changed, 355 insertions, 0 deletions
| -rw-r--r-- | src/teaching/upp-2023/week2/revision.md | 355 |
diff --git a/src/teaching/upp-2023/week2/revision.md b/src/teaching/upp-2023/week2/revision.md new file mode 100644 index 0000000..2e5c285 --- /dev/null +++ b/src/teaching/upp-2023/week2/revision.md @@ -0,0 +1,355 @@ +# Преговор - УПП, Седмица 2, 13.10.2023 + +&&presentation + +&&clide &¢ered + +# Конвертиране на данни, побитови оператори, условни оператори + +&&/centered &&/clide + + + +&&slide + +## Конвертиране на данни + +&&lineb3 + +- Неявно (скрито): компилаторът сам се досеща да промени типа + + ```cpp + int a = 5; + double b = a; + ``` + +- Явно (изрично): казваме как типът да се конвертира + + ```cpp + double a = 5.7, b = 3.42; + int m = (int)a + (int)b; + ``` + +&&/slide + + + +&&slide + +&&lineb5 + +- Експлицитно: със загуба на информация (от по-голям тип в по-малък) + + ```cpp + double a = 5.8371; + int b = a; + ``` + +- Имплицитно: без загуба на информация (от по-малък тип в по-голям) + + ```cpp + int a = 1000; + long b = a; + ``` + +&&/slide + + + +&&slide + +## Побитови оператори + +Първо ще ги погледнем чисто теоретично. + +**Внимавайте, те са различни от логическите оператори!** + +**Означавам побитовите числа с водеща буква "b"!** +Тоест, числото `b1001` е двоичното число `1001`, което е десетичното число `9`. + +&&lineb3 + +- Отрицание/негация, `~`: обръща 0 в 1 и 1 в 0 + + ``` + ~ b0010 = b1101 + ``` + +&&/slide + + + +&&slide + +- Дизюнкция/побитово "и", `&`: за два бита, ако и двете са 1, връща 1, иначе връща 0 + + ``` + 3 & 5 = 1 + b0011 & b0101 = b0001 + ``` + +- Конюнкция/побитово "или", `|`: за два бита, ако и двете са 0, връща 0, иначе връща 1 + + ``` + 3 | 5 = 7 + b0011 | b0101 = b0111 + ``` + +- Изключващо "или", `^`: ако само един от двата бита е 1, връща 1, иначе връща 0 + + ``` + 3 ^ 5 = 6 + b0011 ^ b0101 = b0110 + ``` + +&&/slide + + + +&&clide &&font27 + +- Побитово отместване на ляво, `<<`: отмества всеки бит с n позиции на ляво + Винаги "запълва" с нули (няма разлика между логическо и аритметично ляво отместване) + + ``` + b1010 << 1 = b0100 + b0001 << 3 = b1000 + ``` + + (приемаме, че типа данни съхранява само 4 бита данни) + +- Побитово отместване на дясно, `>>`: отмества всеки бит с n позиции на дясно + При аритметичното отместване, дупките се запъляват с предходната стойност на старшия бит + При логичесткото отместване, винаги запълваме с 0 + В C++ има един оператор, дали е аритметическо или логическо се определя от типа + + ``` + b1000 >> 1 = b0100 или пък b1100 + b1010 >> 3 = b0001 или пък b1111 + ``` + +&&/font &&/clide + + + +&&clide + +Примери с код: + +```cpp +int a = 3, b = 5; + +int n1 = ~ a; // -4 +int n2 = ~ (unsigned int)a; // 4294967292 + +int i1 = 3 & 5; // 1 +int i2 = 3 | 5; // 7 +int i3 = 3 ^ 5; // 6 + +int l1 = b << 1; // 10 +int l2 = b << 3; // 40 + +int r1 = b >> 1; // 2 +int r2 = b >> 2; // 1 +int r3 = -b >> 1; // -3 +int r4 = (unsigned int)b >> 1; // 2 +int r5 = (unsigned int)-b >> 1; // 2147483645 +``` + +&&/clide + + + +&&slide + +## Условни оператори + +- Условен оператор `if`: приема булева стойност, ако е `true`, изпълнява кода в къдравите скоби, ако е `false` ги пропуска + + ```cpp + if (expression) { + dosomething + } + dootherthing + ``` + + `expression` се конвертира към типа `bool` + + Ако `dosomething` е само един израз (тоест е само един ред код, завършващ на ;) можем да пропуснем кдърваите скоби. + + ```cpp + if (expression) dosomething + dootherthing + ``` + +&&/slide + + + +&&clide &&font25 + +- Условен оператор `if-else`: работи като `if`, обаче след къдравите скоби добавяме `else { ... }`. + + ```cpp + if (expression) { + dothing1 + } + else { + dothing2 + } + dootherthing + ``` + + Ако `expression` е истина, `dothing1` се изпълнява и `dothing2` се пропуска изцяло. + Аналогично, ако `expression` е лъжа, `dothing1` се изпуска и `dothing2` се изпълнява. + + Както с `if`, ако `dothing2` е само един израз, можем да пропуснем къдравите скоби + + ```cpp + if (expression) { + dothing1 + } + else dothing2 + dootherthing + ``` + +&&/font &&/clide + + + +&&slide &&font25 + +- благодарение на изпускането на къдрави скоби, можем да пишем + + ```cpp + if (expression1) { + doSomething1; + } + else if (expression2) { + doSometing2; + } + ... + else { + doSomethingN; + } + ``` + + Това е еквивалентно на: + + ```cpp + if (expression1) doSomething1; + else { + if (expression2) doSomething2; + else { + ... + else doSomethingN; + } + } + ``` + +&&/font &&/slide + + + +&&slide + +- `expression` винаги се конвертира до тип `bool` (ако е нужно) + **Никога не правете такива неща:** + + ```cpp + bool a; + if (expression) a = true; + else a = false; + ``` + + ```cpp + bool a = false; + if (expression) a = true; + ``` + + Просто правите `bool a = expression;` + + ```cpp + bool a; + if (expression) a = false; + else a = true; + ``` + + Просто правите `bool a = ! expression;` + +&&/slide + + + +&&slide + +- Тернарен оператор: ако искате да имате такава условна конструкция като част от израз (който взема стойност) използвате + + ```cpp + (expression) ? valueA : valueB + ``` + + Ако `expression` е истинта, връща се `valueA`, иначе се връща `valueB` + + ```cpp + int grade; + std::cin >> grade; + double a = (grade < 300) ? 2.0 : grade / 100.0; + ``` + + Има много нисък приоритет, в повечето случаи ще ви се наложи да го оградите в скоби. + + ```cpp + int grade; + std::cin >> grade; + std::cout << ((grade < 300) ? 2.0 : grade / 100.0); + ``` + +&&/slide + + + +&&clide &&font27 + +- Оператор `switch`: приема стойност и изпълнява случая, при който стойността съвпада с определената + + ```cpp + switch (value) { + case valueA: doSomething1; break; + case valueB: doSomething2; break; + case valueC: doSomething3; break; + } + ``` + + Служи като улеснение на синтаксиса: + + ```cpp + if (value == valueA) doSomething1; + else if (value == valueB) doSomething2; + else if (value == valueC) doSomething3; + ``` + + `otherwise` е като `else`, това е случая когато не съвпада с никоя стойност. + Може да бъде изпуснат. + + Без `break` изпълнението продължава към следващия `case` + +&&/font &&/clide + + + + +&&clide + +```cpp +char characterInput; +std::cin >> characterInput; +switch(characterInput) { + case 'h': + case '?': std::cout << "This is a helpful message."; break; + case 'w': std::cout << "Hello World"; break; + otherwise: std::cout << "Error"; break; +} +``` + +&&/clide |