'def title Преговор - УПП, Седмица 2, 13.10.2023 'def desc Преговор на материала # {title} \n {presentation-controller} :title_slide # Конвертиране на данни, побитови оператори, условни оператори :slide ## Конвертиране на данни {br3} :unordered - Неявно (скрито, експлицитно): компилаторът сам се досеща да промени типа ```cpp int a = 5; double b = a; - Явно (изрично, експлицитно): казваме как типът да се конвертира ```cpp double a = 5.7, b = 3.42; int m = (int)a + (int)b; :slide {br5} :unordered - Със загуба на информация (от по-голям тип в по-малък) ```cpp double a = 5.8371; int b = a; - Без загуба на информация (от по-малък тип в по-голям) ```cpp int a = 1000; long b = a; :slide ## Побитови оператори .p Първо ще ги погледнем чисто теоретично. .p {b Внимавайте, те са различни от логическите оператори!} .p {b Означавам побитовите числа с водеща буква "b"!} Тоест, числото {` b1001} е двоичното число {` 1001}, което е десетичното число {` 9}. {br3} :unordered - Отрицание/негация, {` ~}: обръща 0 в 1 и 1 в 0 ``` ~ b0010 = b1101 :slide :unordered - Побитово "и", {` &}: за два бита, ако и двете са 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 :middle_slide27 :unordered - Побитово отместване на ляво, {` <<}: отмества всеки бит с n позиции на ляво\n Винаги "запълва" с нули (няма разлика между логическо и аритметично ляво отместване) ``` b1010 << 1 = b0100 b0001 << 3 = b1000 (приемаме, че типа данни съхранява само 4 бита данни) - Побитово отместване на дясно, {` >>}: отмества всеки бит с n позиции на дясно\n При аритметичното отместване, дупките се запълват с предходната стойност на старшия бит\n При логическото отместване, винаги запълваме с 0\n В C++ има един оператор, дали е аритметическо или логическо се определя от типа ``` b1000 >> 1 = b0100 или пък b1100 b1010 >> 3 = b0001 или пък b1111 :middle_slide Примери с код: ````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 :slide ## Логически оператори .p Много приличат на побитовите, обаче побитовите работят върху битове, докато логическите работят върху bool. {br4} :unordered - {` !}: обръща {` true} във {` false} и обратно ```cpp ! true // false ! false // true :middle_slide :unordered - {` &&}: "логическо и", ако и двете стойности са {` true}, тогава и резултатът е {` true} ```cpp true && true // true false && true // false false && false // false - {` ||}: "логическо или", само ако и двете са {` false}, тогава е {` false} ```cpp true || true // true false || true // true false || false // false :slide ## Условни конструкции :unordered - {` if}: приема булева стойност, ако е {` true}, изпълнява кода в къдравите скоби, ако е {` false} ги пропуска ```cpp if (expression) { dosomething; } dootherthing; {` expression} се конвертира към типа {` bool}\n Ако в къдравите скоби имаме един израз (тоест е само един ред код, завършващ на {` ;}) можем да ги пропуснем. ```cpp if (expression) dosomething; dootherthing; :middle_slide25 :unordered - {` if-else}: работи като {` if}, обаче след къдравите скоби добавяме {` else { ... }}. ```cpp if (expression) { dothing1; } else { dothing2; } dootherthing; .p Ако {` expression} е истина, {` dothing1} се изпълнява и {` dothing2} се пропуска изцяло. Аналогично, ако {` expression} е лъжа, {` dothing1} се изпуска и {` dothing2} се изпълнява. .p Както с {` if}, ако {` dothing2} е само един израз, можем да пропуснем къдравите скоби ```cpp if (expression) { dothing1; } else dothing2; dootherthing; :slide25 :unordered - благодарение на изпускането на къдрави скоби, можем да пишем ```cpp if (expression1) { doSomething1; } else if (expression2) { doSometing2; } \... else { doSomethingN; } Това е еквивалентно на: ```cpp if (expression1) doSomething1; else { if (expression2) doSomething2; else { \... else doSomethingN; } } :slide :unordered - {` expression} винаги се конвертира до тип {` bool} (ако е нужно)\n {b Никога не правете такива неща:} ```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 :unordered - Тернарен оператор: ако искате да имате такава условна конструкция като част от израз (който взема стойност) използвате ```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); :middle_slide27 :unordered - {` 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; .p {` otherwise} е като {` else}, това е случая когато не съвпада с никоя стойност. Може да бъде изпуснат. .p Без {` break} изпълнението продължава към следващия {` case} :middle_slide ```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; default: std::cout << "Error"; break; }