Operátory v C
Předchozí [První program, datové typy a printf]
Již jsme si pověděli, že proměnné jsou místa v paměti, která uchovávají jistou hodnotu. S touto hodnotou je pak možné dále pracovat, přičemž nám k tomu C nabízí různé tzv. operátory, které pracují na jedné nebo více proměnných.
Aritmetické operátory
Aritmetické operátory v C zahrnují ze školy známé sčítání (+), odečítání (-), násobení (*) a dělení(/). Navíc tu máme modulo-operátor (%), inkrement (++) a dekrement (–). Modulo nám dá jako výsledek zbytek celočíselného dělení (např. 5 % 3 = 2), inkrement a dekrement pracují pouze s jednou proměnnou a zvětší/zmenší její hodnotu o 1.
Pozor, typ operandu určuje typ výsledku (operand je vstupní hodnota matematické operace, výše tedy 5 a 3)! Zkuste si zkopírovat následující řádky do nové main-funkce, program zkompilujte a spusťte. U celočíselného dělení se vše za desetinnou čárkou prostě zahodí. Je tedy třeba na toto myslet, protože kompilátor zde nenahlásí chybu, ale výsledek se může lišit od očekávaného.
int operand = 1;
float result = operand / 2;
printf("%f\n", result);
Řešení představuje použití desetinného čísla na místě alespoň jednoho operandu. Následující úprava kódu ze shora ještě jednou zobrazí nesprávný výsledek a následně již výsledek takový, jaký bychom při dělení očekávali:
int operand = 1;
float result = operand / 2;
printf("%f\n", result);
result = operand / 2.0;
printf("%f\n", result);
Rovněž se zahodí vše za desetinnou čárkou, pokud byste takové číslo chtěli uložit do proměnné s celočíselným typem.
int sum = 1 + 0.5;
printf("%d\n", sum);
sum = 1 - 0.5;
printf("%d\n", sum);
(Kód výše naleznete i na GitHubu pod tímto odkazem).
Závorky
Používejte závorky při programování a používání vícero operátorů najednou. Poslouží nejenom k tomu, že výsledek bude opravdu takový, jaký chcete, ale dopomůžou také k větší přehlednosti (myslete na již zmiňovanou čitelnost kódu). Závorky můžete i škatulkovat do sebe a pokud byste náhodou někde nějakou zapomněli, měla by vás na to upozornit buď IDE, nebo nejpozději compiler.
Příklad na použití závorek a počítání s desetinnou čárkou:
int a = 2;
int b = 3;
float average = a + b / 2.0;
printf("%f\n", average);
average = (a + b) / 2.0;
printf("%f\n", average);
average = (a + b) / 2;
printf("%f\n", average);
(Kód výše naleznete i na GitHubu pod tímto odkazem. Doporučuju ale si výsledek zkusit nejdřív představit, než si program pustíte.)
Inkrement a dekrement
Jak jsem již zmínila, C nabízí i tzv. unární operátory inkrementu a dekrementu. Tyto operátory nelze ovlivnit závorkami. Používají se jako prefix nebo postfix.
Jedná se vlastně o zkrácenou variantu přičítání +1:
counter++;
Je to samé jako:
counter = counter + 1;
Použití post- a prefixu ovlivňuje okamžik, kdy bude hodnota uložená v proměnné inkrementována, příp. dekrementována. Následující příklad má za úkol problematiku trochu přiblížit (zdá se mi jednodušší se na věc hned podívat takto, než to komplikovaně popisovat):
#include <stdio.h>
int result = 0;
int number = 2;
int main(void)
{
result = number++;
printf("Post increment: %d, %d \n", result, number);
result = ++number;
printf("Pre increment: %d, %d \n", result, number);
result = number--;
printf("Post decrement: %d, %d \n", result, number);
result = --number;
printf("Pre decrement: %d, %d \n", result, number);
return 0;
}
(Kód výše naleznete i na GitHubu pod tímto odkazem. Doporučuju si výsledek ale nejdříve představit, než si ho necháte vytisknout přes stdout.)
Další zkratky
Programátoři jsou občas líní tvorové a co můžou zkrátit, to zkrátí. C proto nabízí i další zkratky (vedle inkrementu a dekrementu):
- +=, -=, *=, /=
int number = 2;
number *= 3;
Je to samé jako:
int number = 2;
number = number * 3;
Celé se to samozřejmě dá i kombinovat, např.:
int a = 3;
int b = 4;
b *= --a;
(Kód výše naleznete i na GitHubu pod tímto odkazem. I tady doporučuju se nejdřív zamyslet nad výsledkem, než si program pustíte.)
Porovnávací a logické operátory
Operátory porovnání
Výsledkem použití logických operátorů je pravdivostní hodnota. V minulém díle jsme si již ukázali, že pravdivostní hodnota 0 představuje nepravdu, jakékoli jiné číslo pak pravdu. Srovnání, logické operace, dodají jako výsledek buď 0, nebo 1.
Ke srovnání dvou hodnot používáme následující operátory:
- ==
- !=
- >
- <
- >=
- <=
Častou chybou bývá záměna = (přiřazení) a == (rovnost)!
Logické operátory
Mezi logické operátory řadíme:
- ! (NOT, výsledkem je hodnota opačná té, která je uložena v proměnné, na kterou aplikujeme NOT)
- && (AND, výsledkem je pravda, pokud všechny proměnné jsou pravdivé, nepravda v opačném případě)
- || (OR, výsledkem je pravda, pokud alespoň jedna z proměnných je pravdivá)
Céčko provádí tzv. zkrácené vyhodnocování složených výrazů, tzv. “short circuit evaluation”. Tzn., že v případě AND (a zároveň) stačí, aby jediný výraz byl nepravda a program přestane vyhodnocovat cokoliv, co stojí dále v pravo za tímto výrazem, protože to již na výsledek nebude mít vliv (výsledek bude nepravda). Podobně je to u OR (nebo). Tam stačí, aby byl jediný výraz pravda a bude celý výsledek pravdivý, aniž by bylo potřeba vyhodnocovat ostatní části výrazu stojící dále vpravo od pravdivé proměnné.
Využití najdeme pro logické operátory například v situaci, kdy se chceme ujistit, že uživatel neobjedná víc než nějaký maximální počet položek a zároveň ani nezadá do objednávky negativní číslo. Výtažek z takového kódu by mohl vypadat následovně:
int max = 20;
amount_ok = !((order < 0) || (order > max));
amount_ok = !(order < 0) && !(order > max);
amount_ok = (order >= 0) && (order <= max);
(Zjednoduššenou verzi toho, jak by takový kód mohl vypadat, naleznete i na GitHubu pod tímto odkazem.)
V proměnné amount_ok bychom v takovémto případě uložili informaci, zda je objednané množství v pořádku (0 nebo 1, ano nebo ne). Objednané množství by mohlo být uložené za proměnnou order a max definováno v kódu. Výsledek v proměnné amount_ok je ve všech třech případech stejný.