Přednost a pořadí vyhodnocení
Priorita a asociativita operátorů jazyka C ovlivní seskupování a vyhodnocování operandů ve výrazech.Priorita operátoru má smysl pouze v případě, že jsou přítomny operátory s nižší nebo vyšší prioritou.Výrazy s operátory s vyšší prioritou jsou vyhodnoceny jako první.Prioritu lze popsat také slovem "vazba." O operátorech s vyšší prioritou se říká, že mají silnější vazbu.
Následující tabulka shrnuje prioritu a asociativitu (tedy pořadí, v němž jsou vyhodnoceny operandy) operátorů jazyka C v pořadí dle priority od nejvyšší k nejnižší.Vyskytne-li se několik operátorů pohromadě, mají stejnou prioritu a jsou vyhodnoceny dle své asociativity.Operátory uvedené v tabulce jsou popsány v oddílech začínajících oddílem Příponové operátory.Zbytek tohoto oddílu poskytuje obecné informace o prioritě a asociativitě.
Priorita a asociativita operátorů jazyka C
Symbol1 |
Typ operace |
Asociativita |
---|---|---|
[ ] ( ) . –> přípona ++ a přípona –– |
Výraz |
Zleva doprava |
předpona ++ a předpona –– sizeof & * + – ~ ! |
Unární |
Zprava doleva |
přetypování |
Unární |
Zprava doleva |
* / % |
Násobicí |
Zleva doprava |
+ – |
Aditivní |
Zleva doprava |
<< >> |
Bitový posun |
Zleva doprava |
< > <= >= |
Relační |
Zleva doprava |
== != |
Rovnost |
Zleva doprava |
& |
Bitový operátor AND |
Zleva doprava |
^ |
Bitový operátor XOR |
Zleva doprava |
| |
Bitový operátor OR |
Zleva doprava |
&& |
Logický operátor AND |
Zleva doprava |
|| |
Logický operátor OR |
Zleva doprava |
? : |
Podmíněný výraz |
Zprava doleva |
= *= /= %= += –= <<= >>=&= ^= |= |
Jednoduché a složené přiřazení |
Zprava doleva |
, |
Sekvenční vyhodnocení |
Zleva doprava |
1.Operátory jsou uvedeny v sestupném pořadí dle priority.Je-li několik operátorů uvedeno na stejném řádku nebo ve skupině, mají stejnou prioritu.
2.Všechny operátory jednoduchého a složeného přiřazení mají stejnou prioritu.
Výraz může obsahovat několik operátorů shodné priority.Vyskytne-li si na stejné úrovni ve výrazu několik takových operátorů, vyhodnocování pokračuje dle asociativity operátorů, tedy zleva doprava nebo zprava doleva.Směr vyhodnocení neovlivní výsledky výrazů, které obsahují více než jedno násobení (*), sčítání (+) nebo binární bitový (& | ^) operátor na stejné úrovni.Pořadí operací není v jazyce definováno.Dokáže-li kompilátor zaručit konzistentní výsledek, může takové výrazy vyhodnotit v libovolném pořadí.
Pouze sekvenční vyhodnocení (,), logický operátor AND (&&), logický operátor OR (||), podmíněný výraz (? :) a operátory volání funkce představují body sekvence a zaručují tak konkrétní pořadí vyhodnocení svých operandů.Operátorem volání funkce je sada závorek za identifikátorem funkce.Operátor sekvenčního vyhodnocení (,) zaručuje vyhodnocení operandů zleva doprava. (Povšimněte si, že operátor čárky ve volání funkce není totéž jako operátor sekvenčního vyhodnocení a žádnou takovou záruku tak neposkytuje.) Další informace naleznete v tématu Sekvenční body.
Logické operátory rovněž zaručují vyhodnocení svých operandů zleva doprava.Vyhodnocují však nejmenší počet operandů potřebných k určení výsledků výrazu.Tento postup se nazývá "zkrácené" vyhodnocení.Některé operandy výrazu tedy nemusí být vyhodnoceny.Například ve výrazu
x && y++
je druhý operand, y++, vyhodnocen pouze v případě, že operand x je vyhodnocen na hodnotu true (nenulovou).Operand y tedy nebude navýšen, bude-li operand x vyhodnocen na hodnotu false (0).
Příklady
Následující seznam ukazuje, jak kompilátor automaticky sváže několik ukázkových výrazů:
Výraz |
Automatické vázání |
---|---|
a & b || c |
(a & b) || c |
a = b || c |
a = (b || c) |
q && r || s-- |
(q && r) || s–– |
V prvním výrazu bitový operátor AND (&) má vyšší prioritu než logický operátor OR (||), proto výraz a & b tvoří první operand operace logického OR.
Ve druhém výrazu má logický operátor OR (||) vyšší prioritu než operátor jednoduchého přiřazení (=), proto je výraz b || c v přiřazení seskupen jako operand pravé strany.Povšimněte si, že hodnota přiřazená proměnné a je 0 nebo 1.
Třetí výraz ukazuje výraz správného tvaru, který může být vyhodnocen na neočekávaný výsledek.Logický operátor AND (&&) má vyšší prioritu než logický operátor OR (||), proto je výraz q && r seskupen jako operand.Jelikož logické operátory zaručují vyhodnocování operandů zleva doprava, je výraz q && r vyhodnocen před výrazem s––.Bude-li však výraz q && r vyhodnocen na nenulovou hodnotu, není výraz s–– vyhodnocena a proměnná s není snížena.Pokud by nesnížení proměnné s způsobilo potíže v programu, měl by výraz s–– být prvním operandem výrazu, nebo by proměnná s měla být snížena v samostatné operaci.
Následující výraz není platný a vyvolá při kompilaci diagnostickou zprávu:
Neplatný výraz |
Výchozí seskupení |
---|---|
p == 0 ? p += 1: p += 2 |
( p == 0 ? p += 1 : p ) += 2 |
V tomto výrazu má operátor rovnosti (==) nejvyšší prioritu, proto je výraz p == 0 seskupen jako operand.Operátor podmíněného výrazu (? :) má druhou nejvyšší prioritu.Jeho prvním operandem je výraz p == 0, jeho druhým operandem pak výraz p += 1.Za poslední operand v operátoru podmíněného výrazu je však považován výraz p namísto výrazu p += 2, protože tento výskyt proměnné p je více svázána s operátorem podmíněného výrazu než s operátorem složeného přiřazení.Výraz += 2 nemá operand na levé straně, dojde tedy k chybě syntaxe.Chcete-li zabránit chybám tohoto typu a vytvářet čitelnější kód, měly by být použity závorky.Závorky by měly být použity například jako v ukázce níže, která předchozí příklad opravuje a ujasňuje:
( p == 0 ) ? ( p += 1 ) : ( p += 2 )