C ++

Undantagshantering i C ++

Undantagshantering i C ++
Det finns tre typer av programvarufel. Dessa är syntaxfel, logiska fel och körtidsfel.

Syntaxfel

Ett felaktigt uttryckt uttryck, uttalande eller konstruktion är ett syntaxfel.

Tänk på följande två påståenden:

int arr [] = 1, 2, 3; //korrekt
int arr = 1, 2, 3; // syntaxfel, saknas []

De är definitioner av samma array. Den första är korrekt. Den andra saknas [], och det är ett syntaxfel. Ett program med ett syntaxfel lyckas inte kompilera. Kompileringen misslyckas med ett felmeddelande som anger syntaxfelet. Bra är att ett syntaxfel alltid kan åtgärdas om programmeraren vet vad han gör.

Logikfel

Ett logiskt fel är ett fel som programmeraren begår när någon fel logisk kodning görs. Det kan vara resultatet av okunnighet från programmeraren till programmeringsspråkets funktioner eller ett missförstånd om vad programmet ska göra.

I den här situationen sammanställs programmet framgångsrikt. Programmet fungerar bra, men det ger fel resultat. Ett sådant fel kan bero på att göra en slinga itera 5 gånger när den görs att itera 10 gånger. Det kan också vara så att en ögla omedvetet görs för att itera oändligt. Det enda sättet att lösa denna typ av fel är att göra noggrann programmering och testa programmet noggrant innan du överlämnar det till kunden.

Runtime-fel

Fel eller exceptionella ingångar orsakar runtime-fel. I det här fallet sammanställdes programmet framgångsrikt och fungerar bra i många situationer. I vissa situationer kraschar (och slutar) programmet.

Tänk dig att 8 i ett programkodsegment måste delas med ett antal nämnare. Så om täljaren 8 delas med nämnaren 4, skulle svaret (kvot) vara 2. Men om användaren matar in 0 som nämnaren skulle programmet krascha. Uppdelning med 0 är inte tillåten i matematik, och det är inte heller tillåten i datorer. Division-by-zero bör förhindras vid programmering. Undantagshantering hanterar runtime-fel, som division-by-zero. Följande program visar hur man hanterar problemet med division-by-zero utan att använda undantagsfunktionen i C ++:

#omfatta
använder namnrymd std;
int main ()

int-täljare = 8;
int nämnare = 2;
if (nämnare != 0)

int-resultat = täljare / nämnare;
cout << result << '\n';

annan

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

returnera 0;

Utgången är 4. Om nämnaren var 0 skulle utmatningen ha varit:

”Det är inte tillåtet att dela med noll!”

Huvudkoden här är en if-else-konstruktion. Om nämnaren inte är 0, kommer uppdelningen att äga rum. om det är 0 kommer uppdelningen inte att ske. Ett felmeddelande kommer att skickas till användaren och programmet fortsätter att köras utan att krascha. Runtime-fel hanteras vanligtvis genom att undvika körning av ett kodsegment och skicka ett felmeddelande till användaren.

Undantagsfunktionen i C ++ använder ett försöksblock för if-blocket och ett fångstblock för det andra blocket för att hantera felet, precis som följer:

#omfatta
använder namnrymd std;
int main ()

int-täljare = 8;
int nämnare = 2;
Prova

if (nämnare != 0)

int-resultat = täljare / nämnare;
cout << result << '\n';

annan

kasta 0;


fånga (felaktig)

if (err == 0)
cout << "Division by zero is not permitted!" << '\n';

returnera 0;

Observera att försökshuvudet inte har något argument. Observera också att fångsten, som är som en funktionsdefinition, har en parameter. Parametertypen måste vara densamma som kastanduttryckets operand (argument). Kastuttrycket finns i försöksblocket. Det kastar ett argument av programmerarens val som är relaterat till felet och fångsten blockerar det. På det sättet körs inte koden i försöksblocket. Sedan visar blocket felmeddelandet.

Denna artikel förklarar undantagshantering i C++. Grundläggande kunskaper i C ++ är en förutsättning för att läsaren ska förstå den här artikeln.

Artikelinnehåll:

  • Funktion som kastar ett undantag
  • Mer än en Catch-Blocks för ett Try-block
  • Kapslade försök / fånga block
  • noexcept-specifier
  • Funktionen Special std :: terminate ()
  • Slutsats

Funktion som kastar ett undantag:

En funktion kan också kasta ett undantag precis som vad försöksblocket gör. Kastningen sker inom definitionen av funktionen. Följande program illustrerar detta:

#omfatta
använder namnrymd std;
ogiltigt fn (const char * str)

om (islower (str [0]))
kasta 'l';

int main ()

Prova

fn ("smith");

fånga (char ch)

om (ch == 'l')
cout << "Person's name cannot begin in lowercase!" << '\n';

returnera 0;

Observera att den här gången har försöksblocket bara funktionssamtalet. Det är funktionen som kallas som har kastoperationen. Fångstblocket fångar undantaget och resultatet är:

”Personens namn kan inte börja med gemener!”

Den här gången är den typ som kastas och fångas en röding.

Mer än en Catch-Blocks för ett Try-block:

Det kan finnas mer än ett fångstblock för ett försöksblock. Föreställ dig situationen där en inmatning kan vara vilken som helst av tangentbordets tecken, men inte en siffra och inte ett alfabet. I det här fallet måste det finnas två fångstycken: ett för ett heltal för att kontrollera siffran och ett för ett tecken för att kontrollera alfabetet. Följande kod illustrerar detta:

#omfatta
använder namnrymd std;
char input = '*';
int main ()

Prova

om (isdigit (input))
kasta 10;
om (isalpha (input))
kasta 'z';

fånga (int)

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

fånga (röding)

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

returnera 0;

Det finns ingen utdata. Om värdet på inmatningen var en siffra, t.ex.g., '1', utgången skulle ha varit:

"Inmatning av siffror är förbjudet!"

Om värdet på inmatningen var ett alfabet, t.ex.g., 'a', produktionen skulle ha varit:

"Teckeninmatning är förbjuden!"

Observera att det inte finns något identifieringsnamn i parameterlistan över de två fångstblocken. Observera också att i definitionen av de två fångstenen har de särskilda argumenten som kastats inte verifierats om deras värden är exakta eller inte.

Det som är viktigt för en fångst är typen; en fångst måste matcha den typ av operand som kastas. Det speciella värdet av argumentet (operand) som kastas kan användas för ytterligare verifiering om det behövs.

Mer än en hanterare för samma typ

Det är möjligt att ha två hanterare av samma typ. När ett undantag kastas överförs kontrollen till närmaste hanterare med en matchande typ. Följande program illustrerar detta:

#omfatta
använder namnrymd std;
char input = '1';
int main ()

Prova

om (isdigit (input))
kasta 10;

fånga (int)

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

fånga (int)

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

returnera 0;

Utgången är:

"Inmatning av siffror är förbjudet!"

Kapslade försök / fånga block:

försök / fånga block kan vara kapslade. Ovanstående program för inmatning av icke-alfanumeriska tecken från tangentbordet upprepas här, men med den alfabetiska felkoden kapslad:

#omfatta
använder namnrymd std;
char input = '*';
int main ()

Prova

om (isdigit (input))
kasta 10;
Prova

om (isalpha (input))
kasta 'z';

fånga (röding)

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


fånga (int)

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

returnera 0;

Felets alfabetiska försök / fångstblock är kapslat i försöksblocket för sifferkoden. Driften av detta program och den tidigare åtgärden från vilken det kopieras är desamma.

noexcept-specifier

Tänk på följande funktion:

void fn (const char * str) noexcept

om (islower (str [0]))
kasta 'l';

Lägg märke till specifikatorn 'noexcept' strax efter höger parentes i funktionsparameterlistan. Detta innebär att funktionen inte ska kasta ett undantag. Om funktionen ger ett undantag, som i det här fallet, kommer den att kompileras med ett varningsmeddelande men kommer inte att köras. Ett försök att köra programmet kommer att kalla specialfunktionen std :: terminate (), som skulle stoppa programmet graciöst istället för att bara låta det krascha bokstavligen.

Noexcept-specifikatorn finns i olika former. Dessa är som följer:

typ func () noexcept; : tillåter inte ett kastuttryck
skriv func () noexcept (true); : tillåter ett kastuttryck
skriv func () throw (); : tillåter inte ett kastuttryck
skriv func () noexcept (false); : tillåter ett kastuttryck, vilket är valfritt
skriv func (); : tillåter ett kastuttryck, vilket är valfritt

true eller false inom parentes kan ersättas med ett uttryck som resulterar i true eller false.

Specialstd :: avsluta () -funktionen:

Om ett undantag inte kan hanteras bör det kastas om. I det här fallet kan det kastade uttrycket ha eller inte ha en operand. Specialfunktionen std :: terminate () kommer att anropas vid körning, vilket skulle stoppa programmet graciöst istället för att bara låta det krascha bokstavligen.

Skriv, kompilera och kör följande program:

#omfatta
använder namnrymd std;
char input = '1';
int main ()

Prova

om (isdigit (input))
kasta 10;

fånga (int)

kasta;

returnera 0;

Efter en lyckad sammanställning avslutades programmet utan att köras och felmeddelandet från författarens dator är:

"Avsluta kallas efter att ha kastat en instans av" int "

Avbruten (kärndumpad) ”

Slutsats:

Undantagsfunktionen i C ++ förhindrar att ett kodsegment körs baserat på någon typ av inmatning. Programmet fortsätter att köra efter behov. Undantaget (felförebyggande) konstruktion består av ett försök-block och ett fång-block. Try-blocket har kodsegmentet av intresse, vilket kan förbikopplas, beroende på något ingångsförhållande. Try-blocket har kastuttrycket, som kastar en operand. Denna operand kallas också undantaget. Om operandtypen och typen för fångblocksparametern är desamma, fångas (hanteras) undantaget. Om undantaget inte fångas avslutas programmet, men ändå vara säkert eftersom kodsegmentet som skulle köras för att ge fel resultat inte har körts. Typisk undantagshantering innebär att man kringgår kodesegmentet och skickar ett felmeddelande till användaren. Kodsegmentet körs för normal ingång men förbigås för fel ingångar.

Mus AppyMouse styrplatta och muspekare för Windows-surfplattor
AppyMouse styrplatta och muspekare för Windows-surfplattor
Surfplattanvändare saknar ofta muspekaren, särskilt när de brukar använda bärbara datorer. Pekskärmen Smartphones och surfplattor har många fördelar o...
Mus Mellan musknappen fungerar inte i Windows 10
Mellan musknappen fungerar inte i Windows 10
De mittknappen hjälper dig att bläddra igenom långa webbsidor och skärmar med mycket data. Om det slutar, kommer du sluta använda tangentbordet för at...
Mus Hur man ändrar vänster och höger musknapp på Windows 10 PC
Hur man ändrar vänster och höger musknapp på Windows 10 PC
Det är en hel norm att alla datormusenheter är ergonomiskt utformade för högerhänta användare. Men det finns musenheter tillgängliga som är speciellt ...