Zpracování chyb a výjimek
6. Přetečení
Datové typy mají své rozsahy hodnot. V kódu můžeme využít vlastnost MaxValue, která nám vrátí horní mez rozsahu u daného datového typu. Může se stát, že vykonáním aritmetické operace překročíme povolený rozsah. Dojde k tzv. přetečení (anglicky "Overflow").
Pokud se chceme v C# pojistit, aby nás kompilátor upozornil, že během početních operací prováděných na celých číslech došlo k přetečení, můžeme využít klíčové slovo checked. Toto slovo nám zajistí, že v případě přetečení budeme upozorněni kompilátorem na tuto nepříjemnou skutečnost. Může se to zdát divné, ale existuje i protipól – klíčové slovo unchecked. To slovo potlačuje hlášení o přetečení a je využíváno záměrně při některých matematických výpočtech.
Pokud je ale uzavřeno do složeného příkazu za
příkazem checked volání metody, kontrola přetečení se na tento kód uvnitř
volané metody nevztahuje.
Ilustrativní příklad Preteceni
Program Preteceni
- Popis: Přetečení datového typu integer
- Zadání: Vytvořte program pro konzolovou aplikaci, ve kterém v hlavní statické metodě Main deklarujete celočíselnou proměnnou horniMez a uložíte do ní největší možné maximální kladné číslo. Hodnotu této proměnné vypište. V následném kroku k této hodnotě přičtěte hodnotu 1 a nechte znovu vypsat hodnotu v proměnné
- Řešení: Bude postupně probráno v následujícím textu
Následující kód ukazuje, jak
využijeme vlastnosti určení maximální hodnoty určitého datového typu. Do proměnné horniMez
uložíme tuto hodnotu celočíselného datového typu int – viz Kód 1.
Abychom se dozvěděli aktuální hodnotu proměnné, vypíšeme aktuální hodnotu
uložené v proměnné pomocí příkazu Console.WriteLine.
Abychom dosáhli přetečení (tedy
překročení rozsahu daného datového typu), k aktuální hodnotě v proměnné
přičteme hodnotu 1. Tento výsledek necháme znovu vypsat.
static void Main(string[] args) { //Deklarace celočíselné proměnné int horniMez; //Přiřazení hodnoty horní meze int (hodnota 2147483647) do proměnné horniMez = int.MaxValue; //Výpis akutální hodnoty proměnné Console.WriteLine("Horní mez: {0}", horniMez); //Přičtení 1 k aktuální hodnotě v proměnné -> přetečení horniMez = horniMez + 1; //Výpis akutální hodnoty proměnné Console.WriteLine("Horní mez + 1: {0}", horniMez); //Čekání na stisk klávesy -> Ukončení programu Console.ReadKey(); }
Kód 1: Deklarace hlavní metody Main programu Preteceni - přetečení hodnoty
Na následujícím výpisu programu vidíme, že nejprve byl proveden výpis aktuální hodnoty (horní mez datového typu int, tj. 2147483647) uložené v proměnné horniMez – viz Výstup programu - Kód 1. Co se ale stane, pokud jsme k této hodnotě přičetli 1? Jak vidíte, hodnota se nezvýšila na hodnotu 2147483648, ale spadla na dolní mez datového typu int, tj. -2147483648.
Horní mez: 2147483647
Horní mez + 1: -2147483648
Výstup programu - Kód 1: Ukázka
výsledku při přetečení
Ilustrativní příklad KontrolaPreteceni
Program KontrolaPreteceni
- Popis: Kontrola přetečení datového typu integer
- Zadání: Modifikujte program Preteceni (viz Kód 1) pro konzolovou aplikaci tak, aby nás kompilátor upozornil na přetečení celočíselné proměnné horniMez
- Řešení: Bude postupně probráno v následujícím textu
V následujícím zdrojovém kódu jsme využili klíčového slova checked, abychom si pojistili proti neošetřené výjimce typu OverflowException - přetečení - viz Kód 2. Nebezpečný kód, který je kontrolován horniMez = horniMez + 1;, jsme uzavřeli do složených závorek.
static void Main(string[] args) { //Deklarace celočíselné proměnné int horniMez; //Přiřazení hodnoty horní meze int (hodnota 2147483647) do proměnné horniMez = int.MaxValue; //Výpis akutální hodnoty proměnné Console.WriteLine("Horní mez: {0}", horniMez); //Kontrola přetečení checked { //Přičtení 1 k aktuální hodnotě v proměnné -> přetečení horniMez = horniMez + 1; } //Výpis akutální hodnoty proměnné Console.WriteLine("Horní mez + 1: {0}", horniMez); //Čekání na stisk klávesy -> Ukončení programu Console.ReadKey(); }
Kód 1: Deklarace metody KontrolaPreteceni - Příklad
přetečení s použitím checked
Když jsme spustili program, po výpisu horní meze celého čísla jsme byli upozorněni kompilátorem na nepříjemnou skutečnost přetečení prostřednictvím okna s neošetřenou výjimkou - viz Obrázek 1.

Obrázek 1: Informace kompilátoru u přetečení
Příkaz checked nebo unchecked lze použít pouze u aritmetických operací prováděných s celými čísly. V naší aplikaci týkající se algoritmu Kalkulacka, bychom mohli využít checked pouze tehdy, pokud bychom používali pouze celočíselné proměnné. Použití u reálných čísel by nevyvolalo výjimku typu OverflowException, o čemž jsme se přesvědčili již v kapitole Ošetření více výjimek, kde jsme narazili na pojem Infinity (nekonečno se znakem ?).