C ++

Обработка на изключения в C ++

Обработка на изключения в C ++
Съществуват три вида софтуерни грешки. Това са синтаксични грешки, логически грешки и грешки по време на изпълнение.

Синтаксични грешки

Грешно набран израз, израз или конструкция е синтаксична грешка.

Обмислете следните две твърдения:

int arr [] = 1, 2, 3; // правилно
int arr = 1, 2, 3; // синтаксична грешка, липсва []

Те са дефиниции на един и същ масив. Първият е правилен. Втората липсва [] и това е синтаксична грешка. Програма със синтаксична грешка не успява да се компилира. Компилацията се проваля със съобщение за грешка, указващо синтаксисната грешка. Хубавото е, че синтаксичната грешка винаги може да бъде коригирана, ако програмистът знае какво прави.

Логическа грешка

Логическата грешка е грешка, извършена от програмиста, когато е направено грешно логическо кодиране. Това може да е резултат от невежество от страна на програмиста към функциите на езика за програмиране или от неразбиране на това, което програмата трябва да направи.

В тази ситуация програмата се компилира успешно. Програмата работи добре, но дава грешни резултати. Такава грешка може да се дължи на повторение на цикъл 5 пъти, когато е направено да се повтори 10 пъти. Възможно е също така цикълът да е несъзнателно да се итерира безкрайно. Единственият начин за разрешаване на този вид грешка е внимателното програмиране и тестването на програмата старателно, преди да я предадете на клиента.

Грешки по време на изпълнение

Грешни или изключителни входове причиняват грешки при изпълнението. В този случай програмата е компилирана успешно и работи добре в много ситуации. В определени ситуации програмата се срива (и спира).

Представете си, че в сегмент на програмен код 8 трябва да бъде разделен на редица знаменатели. Така че, ако числителят 8 се дели на знаменател 4, отговорът (коефициентът) ще бъде 2. Ако обаче потребителят въведе 0 като знаменател, програмата ще се срине. Делението на 0 не е разрешено в математиката, както и в изчисленията. Делението на нула трябва да се предотврати при програмирането. Обработката на изключения се справя с грешки по време на изпълнение, като разделяне по нула. Следващата програма показва как да се справите с проблема с разделяне по нула, без да използвате функцията за изключение в C ++:

#include
използване на пространство от имена std;
int main ()

int числител = 8;
int знаменател = 2;
ако (знаменател != 0)

int резултат = числител / знаменател;
Cout << result << '\n';

друго

Cout << "Division by zero is not permitted!" << '\n';

връщане 0;

Изходът е 4. Ако знаменателят беше 0, изходът щеше да бъде:

„Деление на нула не е разрешено!”

Основният код тук е конструкция if-else. Ако знаменателят не е 0, ще се извърши разделянето; ако е 0, разделянето няма да се извърши. На потребителя ще бъде изпратено съобщение за грешка и програмата продължава да работи, без да се срива. Грешките по време на работа обикновено се обработват, като се избягва изпълнението на кодов сегмент и се изпраща съобщение за грешка до потребителя.

Функцията за изключение в C ++ използва try-block за if-block и catch-block за else-блока, за да се справи с грешката, точно както следва:

#include
използване на пространство от имена std;
int main ()

int числител = 8;
int знаменател = 2;
опитвам

ако (знаменател != 0)

int резултат = числител / знаменател;
Cout << result << '\n';

друго

хвърли 0;


улов (вътре грешка)

ако (грешка == 0)
Cout << "Division by zero is not permitted!" << '\n';

връщане 0;

Обърнете внимание, че заглавката try няма аргумент. Също така имайте предвид, че блокът catch, който е като дефиниция на функция, има параметър. Типът на параметъра трябва да бъде същият като операнда (аргумента) на хвърлящия израз. Изразът хвърляне е в блока try. Той хвърля аргумент по избор на програмиста, който е свързан с грешката, и блокът catch хваща. По този начин кодът в блока try не се изпълнява. След това блокът catch показва съобщението за грешка.

Тази статия обяснява обработката на изключения в C++. Базовите познания на C ++ са предпоставка за разбирането на читателя от тази статия.

Съдържание на статията:

  • Функция Изхвърляне на изключение
  • Повече от един блок за улавяне за един опит
  • Вложени блокове за опит / улов
  • noexcept-спецификатор
  • Специалната функция std :: terminate ()
  • Заключение

Функция, хвърляща изключение:

Функция също може да хвърли изключение точно като това, което прави try-block. Хвърлянето се извършва в рамките на дефиницията на функцията. Следващата програма илюстрира това:

#include
използване на пространство от имена std;
void fn (const char * str)

if (islower (str [0]))
хвърли 'l';

int main ()

опитвам

fn ("ковач");

улов (char ch)

ако (ch == 'l')
Cout << "Person's name cannot begin in lowercase!" << '\n';

връщане 0;

Забележете, че този път блокът try има само извикване на функция. Извиканата функция има операцията хвърляне. Блокът catch улавя изключението и изходът е:

„Името на човека не може да започва с малки букви!”

Този път типът хвърлен и уловен е овал.

Повече от един блок за улавяне за един опит:

Може да има повече от един блок за хващане за един блок за опит. Представете си ситуацията, при която входът може да бъде всеки от символите на клавиатурата, но не цифра и не азбука. В този случай трябва да има два блока за хващане: един за цяло число за проверка на цифрата и един за знак за проверка на азбуката. Следният код илюстрира това:

#include
използване на пространство от имена std;
char вход = '*';
int main ()

опитвам

if (isdigit (вход))
хвърляне 10;
ако (isalpha (вход))
хвърли 'z';

хващане (int)

Cout << "Digit input is forbidden!" << '\n';

улов (char)

Cout << "Character input is forbidden!" << '\n';

връщане 0;

Няма изход. Ако стойността на входа е цифра, напр.ж., „1“, изходът би бил:

"Въвеждането на цифри е забранено!"

Ако стойността на въведеното е азбука, напр.ж., 'a', изходът би бил:

"Въвеждането на символи е забранено!"

Обърнете внимание, че в списъка с параметри на двата блока за хващане няма име на идентификатор. Също така имайте предвид, че в дефиницията на двата блока за хващане конкретните изхвърлени аргументи не са проверени дали техните стойности са точни или не.

От значение за улова е видът; уловът трябва да съответства на вида хвърлен операнд. Конкретната стойност на хвърления аргумент (операнд) може да се използва за допълнителна проверка, ако е необходимо.

Повече от един манипулатор за същия тип

Възможно е да имате два манипулатора от един и същи тип. Когато се хвърли изключение, контролът се прехвърля на най-близкия манипулатор със съответстващ тип. Следващата програма илюстрира това:

#include
използване на пространство от имена std;
char вход = '1';
int main ()

опитвам

if (isdigit (вход))
хвърляне 10;

хващане (int)

Cout << "Digit input is forbidden!" << '\n';

хващане (int)

Cout << "Not allowed at all: digit input!" << '\n';

връщане 0;

Резултатът е:

"Въвеждането на цифри е забранено!"

Вложени блокове за опит / улов:

try / catch блокове могат да бъдат вложени. Горната програма за въвеждане на небуквено-цифрови символи от клавиатурата се повтаря тук, но с вложен код на азбучна грешка:

#include
използване на пространство от имена std;
char вход = '*';
int main ()

опитвам

if (isdigit (вход))
хвърляне 10;
опитвам

ако (isalpha (вход))
хвърли 'z';

улов (char)

Cout << "Character input is forbidden!" << '\n';


хващане (int)

Cout << "Digit input is forbidden!" << '\n';

връщане 0;

Блокът за грешка азбучен опит / улавяне е вложен в блока за опит на цифровия код. Работата на тази програма и предишната операция, от която е копирана, са еднакви.

noexcept-спецификатор

Обмислете следната функция:

void fn (const char * str) noexcept

if (islower (str [0]))
хвърли 'l';

Забележете спецификатора 'noexcept' веднага след дясната скоба на списъка с параметри на функцията. Това означава, че функцията не трябва да създава изключение. Ако функцията хвърли изключение, както в този случай, тя ще се компилира с предупредително съобщение, но няма да се изпълни. Опитът за стартиране на програмата ще извика специалната функция std :: terminate (), която трябва да спре грациозно програмата, вместо просто да й позволи буквално да се срине.

Спецификаторът noexcept е в различни форми. Те са както следва:

въведете func () noexcept; : не позволява израз на хвърляне
въведете func () noexcept (true); : позволява израз на хвърляне
въведете func () throw (); : не позволява израз на хвърляне
въведете func () noexcept (false); : позволява израз на хвърляне, който не е задължителен
въведете func (); : позволява израз на хвърляне, който не е задължителен

true или false в скобите могат да бъдат заменени с израз, който води до true или false.

Специалната функция std :: terminate ():

Ако изключение не може да бъде обработено, то трябва да бъде изхвърлено отново. В този случай хвърленият израз може да има или не операнд. Специалната функция std :: terminate () ще бъде извикана по време на изпълнение, което трябва да спре програмата грациозно, вместо просто да й позволи буквално да се срине.

Въведете, компилирайте и стартирайте следната програма:

#include
използване на пространство от имена std;
char вход = '1';
int main ()

опитвам

if (isdigit (вход))
хвърляне 10;

хващане (int)

хвърляне;

връщане 0;

След успешна компилация програмата се прекратява без стартиране и съобщението за грешка от компютъра на автора е:

„Прекратяване, извикано след изхвърляне на екземпляр на„ int “

Прекъснато (изхвърлено ядро) “

Заключение:

Функцията за изключение в C ++ предотвратява изпълнението на кодов сегмент въз основа на някакъв вид вход. Програмата продължава да се изпълнява при необходимост. Конструкцията за изключение (предотвратяване на грешки) се състои от try-block и catch-block. Опитният блок има интересния кодов сегмент, който може да бъде заобиколен, в зависимост от някои условия на въвеждане. Блокът try има израза хвърляне, който хвърля операнд. Този операнд се нарича още изключение. Ако типът на операнда и типът за параметъра на блока catch са еднакви, тогава изключението е уловено (обработено). Ако изключението не бъде уловено, програмата ще бъде прекратена, но все пак бъдете в безопасност, тъй като не е изпълнен кодовият сегмент, който трябваше да бъде изпълнен, за да даде грешен резултат. Типичното обработване на изключения означава заобикаляне на кодовия сегмент и изпращане на съобщение за грешка до потребителя. Кодовият сегмент се изпълнява за нормални входове, но се заобикаля за грешни входове.

Урок за OpenTTD
OpenTTD е една от най-популярните бизнес симулационни игри там. В тази игра трябва да създадете прекрасен транспортен бизнес. Въпреки това, ще започне...
SuperTuxKart за Linux
SuperTuxKart е страхотно заглавие, създадено да ви предостави безплатно изживяването на Mario Kart във вашата Linux система. Играта е доста предизвика...
Урок за битка за Уеснот
Битката за Уеснот е една от най-популярните стратегически игри с отворен код, които можете да играете по това време. Тази игра не само се разработва о...