Преговор - УПП, Седмица 2, 13.10.2023
Конвертиране на данни, побитови оператори, условни оператори
Конвертиране на данни
#- Неявно (скрито, експлицитно): компилаторът сам се досеща да промени типа
int a = 5; double b = a; - Явно (изрично, експлицитно): казваме как типът да се конвертира
double a = 5.7, b = 3.42; int m = (int)a + (int)b;
- Със загуба на информация (от по-голям тип в по-малък)
double a = 5.8371; int b = a; - Без загуба на информация (от по-малък тип в по-голям)
int a = 1000; long b = a;
Побитови оператори
#Първо ще ги погледнем чисто теоретично.
Внимавайте, те са различни от логическите оператори!
Означавам побитовите числа с водеща буква "b"!
Тоест, числото b1001 е двоичното число 1001, което е десетичното число 9.
- Отрицание/негация,
~: обръща 0 в 1 и 1 в 0~ b0010 = b1101
- Побитово "и",
&: за два бита, ако и двете са 1, връща 1, иначе връща 03 & 5 = 1 b0011 & b0101 = b0001 - Побитово "или",
|: за два бита, ако и двете са 0, връща 0, иначе връща 13 | 5 = 7 b0011 | b0101 = b0111 - Изключващо "или",
^: ако само един от двата бита е 1, връща 1, иначе връща 03 ^ 5 = 6 b0011 ^ b0101 = b0110
- Побитово отместване на ляво,
<<: отмества всеки бит с n позиции на ляво
Винаги "запълва" с нули (няма разлика между логическо и аритметично ляво отместване)
(приемаме, че типа данни съхранява само 4 бита данни)b1010 << 1 = b0100 b0001 << 3 = b1000 - Побитово отместване на дясно,
>>: отмества всеки бит с n позиции на дясно
При аритметичното отместване, дупките се запълват с предходната стойност на старшия бит
При логическото отместване, винаги запълваме с 0
В C++ има един оператор, дали е аритметическо или логическо се определя от типаb1000 >> 1 = b0100 или пък b1100 b1010 >> 3 = b0001 или пък b1111
Примери с код:
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
Логически оператори
#Много приличат на побитовите, обаче побитовите работят върху битове, докато логическите работят върху bool.
!: обръщаtrueвъвfalseи обратно! true // false ! false // true
&&: "логическо и", ако и двете стойности саtrue, тогава и резултатът еtruetrue && true // true false && true // false false && false // false||: "логическо или", само ако и двете саfalse, тогава еfalsetrue || true // true false || true // true false || false // false
Условни конструкции
#if: приема булева стойност, ако еtrue, изпълнява кода в къдравите скоби, ако еfalseги пропускаif (expression) { dosomething; } dootherthing;expressionсе конвертира към типаbool
Ако в къдравите скоби имаме един израз (тоест е само един ред код, завършващ на;) можем да ги пропуснем.if (expression) dosomething; dootherthing;
if-else: работи катоif, обаче след къдравите скоби добавямеelse { ... }.if (expression) { dothing1; } else { dothing2; } dootherthing;Ако
expressionе истина,dothing1се изпълнява иdothing2се пропуска изцяло. Аналогично, акоexpressionе лъжа,dothing1се изпуска иdothing2се изпълнява.Както с
if, акоdothing2е само един израз, можем да пропуснем къдравите скобиif (expression) { dothing1; } else dothing2; dootherthing;
- благодарение на изпускането на къдрави скоби, можем да пишем
Това е еквивалентно на:if (expression1) { doSomething1; } else if (expression2) { doSometing2; } ... else { doSomethingN; }if (expression1) doSomething1; else { if (expression2) doSomething2; else { ... else doSomethingN; } }
expressionвинаги се конвертира до типbool(ако е нужно)
Никога не правете такива неща:bool a; if (expression) a = true; else a = false;
Просто правитеbool a = false; if (expression) a = true;bool a = expression;
Просто правитеbool a; if (expression) a = false; else a = true;bool a = ! expression;
- Тернарен оператор: ако искате да имате такава условна конструкция като част от израз (който взема стойност) използвате
Ако(expression) ? valueA : valueBexpressionе истина, връща сеvalueA, иначе се връщаvalueB
Има много нисък приоритет, в повечето случаи ще ви се наложи да го оградите в скоби.int grade; std::cin >> grade; double a = (grade < 300) ? 2.0 : grade / 100.0;int grade; std::cin >> grade; std::cout << ((grade < 300) ? 2.0 : grade / 100.0);
switch: приема стойност и изпълнява случая, при който стойността съвпада с определената
Служи като улеснение на синтаксиса:switch (value) { case valueA: doSomething1; break; case valueB: doSomething2; break; case valueC: doSomething3; break; }if (value == valueA) doSomething1; else if (value == valueB) doSomething2; else if (value == valueC) doSomething3;otherwiseе катоelse, това е случая когато не съвпада с никоя стойност. Може да бъде изпуснат.Без
breakизпълнението продължава към следващияcase
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;
}