Unntakhåndtering i C ++

Unntakhåndtering i C ++
Det er tre typer programvarefeil som finnes. Dette er syntaksfeil, logiske feil og runtime -feil.

Syntaksfeil

Et feilaktig skrevet uttrykk, uttalelse eller konstruksjon er en syntaksfeil.

Tenk på følgende to utsagn:

int arr [] = 1, 2, 3; //riktig
int arr = 1, 2, 3; // Syntaksfeil, mangler []

De er definisjoner av samme matrise. Den første er riktig. Den andre mangler [], og det er en syntaksfeil. Et program med syntaksfeil lykkes ikke å kompilere. Samlingen mislykkes med en feilmelding som indikerer syntaksfeilen. Bra er at en syntaksfeil alltid kan fikses hvis programmereren vet hva han gjør.

Logikkfeil

En logikkfeil er en feil begått av programmereren når noe feil logisk koding gjøres. Det kan være et resultat av uvitenhet fra programmerer til programmeringsspråkfunksjonene eller en misforståelse av hva programmet skal gjøre.

I denne situasjonen er programmet samlet vellykket. Programmet fungerer bra, men det gir gale resultater. En slik feil kan være på grunn av å lage en sløyfe iterere 5 ganger når den gjøres for å iterere 10 ganger. Det kan også være at en sløyfe ubevisst er laget for å iterere uendelig. Den eneste måten å løse denne typen feil er å gjøre nøye programmering og teste programmet grundig før du overleverer det til kunden.

Runtime -feil

Feil eller eksepsjonelle innganger forårsaker runtime -feil. I dette tilfellet ble programmet samlet og fungerer bra i mange situasjoner. I visse situasjoner krasjer programmet (og stopper).

Se for deg at i et programkodesegment må 8 deles med en rekke nevner. Så hvis telleren 8 er delt av nevneren 4, ville svaret (kvotient) være 2. Imidlertid, hvis brukeren legger inn 0 som nevner, ville programmet krasje. Divisjon med 0 er ikke tillatt i matematikk, og det er heller ikke tillatt i databehandling. Divisjon for null bør forhindres i programmering. Unntakhåndtering håndterer runtime-feil, som divisjon-for-null. Følgende program viser hvordan du håndterer divisjon-for-null-problemet uten å bruke unntaksfunksjonen i C ++:

#inkludere
ved hjelp av navneområdet STD;
int main ()

int teller = 8;
int nevner = 2;
if (nevner != 0)

int resultat = teller/nevner;
cout << result << '\n';

ellers

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

retur 0;

Utgangen er 4. Hvis nevneren var 0, ville utgangen vært:

“Divisjon med null er ikke tillatt!”

Hovedkoden her er en if-ests-konstruksjon. Hvis nevneren ikke er 0, vil divisjonen finne sted; Hvis det er 0, vil divisjonen ikke finne sted. En feilmelding vil bli sendt til brukeren, og programmet fortsetter å kjøre uten å krasje. Runtime -feil håndteres vanligvis ved å unngå utførelse av et kodesegment og sende en feilmelding til brukeren.

Unntaksfunksjonen i C ++ bruker en prøveblokk for if-block og en fangstblokk for annetblokken for å håndtere feilen, akkurat som følger:

#inkludere
ved hjelp av navneområdet STD;
int main ()

int teller = 8;
int nevner = 2;
prøve

if (nevner != 0)

int resultat = teller/nevner;
cout << result << '\n';

ellers

kast 0;


fangst (int feil)

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

retur 0;

Merk at prøveoverskriften ikke har et argument. Legg også merke til at fangstblokken, som er som en funksjonsdefinisjon, har en parameter. Parametertypen må være den samme som operand (argument) for kastuttrykk. Kastuttrykket er i prøveblokken. Det kaster et argument for programmererens valg som er relatert til feilen, og fangstblokken fanger den. På den måten blir ikke koden i prøveblokken utført. Deretter viser fangstblokken feilmeldingen.

Denne artikkelen forklarer unntakshåndtering i C++. Grunnleggende kunnskap i C ++ er en forutsetning for leseren å forstå denne artikkelen.

Artikkelinnhold:

  • Funksjon kaster et unntak
  • Mer enn ett fangstblokker for en prøveblokk
  • Nestet prøve/fange blokker
  • NoExcept-Spesifikator
  • Den spesielle STD :: Termininate () -funksjonen
  • Konklusjon

Funksjon kaster et unntak:

En funksjon kan også kaste et unntak akkurat som det prøveblokken gjør. Kastet foregår innenfor definisjonen av funksjonen. Følgende program illustrerer dette:

#inkludere
ved hjelp av navneområdet STD;
void fn (const char* str)

if (islower (str [0]))
kast 'l';

int main ()

prøve

fn ("Smith");

fangst (char ch)

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

retur 0;

Legg merke til at prøveblokken denne gangen har nettopp funksjonssamtalen. Det er funksjonen som heter som har kastoperasjonen. Fangstblokken fanger unntaket, og utgangen er:

"Personens navn kan ikke begynne i små bokstaver!”

Denne gangen er typen kastet og fanget en røye.

Mer enn ett fangstblokker for en prøveblokk:

Det kan være mer enn en fangstblokk for en prøveblokk. Se for deg situasjonen der en inngang kan være noen av tegnene på tastaturet, men ikke et siffer og ikke et alfabet. I dette tilfellet må det være to fangstblokker: en for et heltall for å sjekke sifferet og en for en røye for å sjekke alfabetet. Følgende kode illustrerer dette:

#inkludere
ved hjelp av navneområdet STD;
char input = '*';
int main ()

prøve

if (isDigit (input))
Kast 10;
if (isalpha (input))
kast 'z';

fangst (int)

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

fangst (røye)

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

retur 0;

Det er ingen produksjon. Hvis verdien av inngangen var et siffer, e.g., '1', ville utgangen vært:

"Sifferinngang er forbudt!""

Hvis verdien av inngangen var et alfabet, e.g., 'A', utdataene ville vært:

"Karakterinngang er forbudt!""

Merk at i parameterlisten over de to fangstblokkene er det ikke noe identifikatornavn. Legg også merke til at i definisjonen av de to fangstblokkene har de kastede argumentene ikke blitt bekreftet om verdiene deres er nøyaktige eller ikke.

Det som betyr noe for en fangst er typen; En fangst må samsvare med den typen operand som kastes. Den spesielle verdien av argumentet (operand) som kastes kan brukes til ytterligere verifisering om nødvendig.

Mer enn en behandler for samme type

Det er mulig å ha to håndterere av samme type. Når et unntak kastes, overføres kontrollen til nærmeste handler med en matchende type. Følgende program illustrerer dette:

#inkludere
ved hjelp av navneområdet STD;
char input = '1';
int main ()

prøve

if (isDigit (input))
Kast 10;

fangst (int)

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

fangst (int)

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

retur 0;

Utgangen er:

"Sifferinngang er forbudt!""

Nested Try/Catch Blocks:

prøve/fange blokker kan nestes. Ovennevnte program for inndata av ikke-alfanumeriske tegn fra tastaturet gjentas her, men med den alfabetiske feilkoden nestet:

#inkludere
ved hjelp av navneområdet STD;
char input = '*';
int main ()

prøve

if (isDigit (input))
Kast 10;
prøve

if (isalpha (input))
kast 'z';

fangst (røye)

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


fangst (int)

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

retur 0;

Feil alfabetisk forsøk/fangstblokk er nestet i prøveblokken til sifferkoden. Operasjonen av dette programmet og den forrige operasjonen det er kopiert fra er den samme.

NoExcept-Spesifikator

Tenk på følgende funksjon:

void fn (const char* str) noexcept

if (islower (str [0]))
kast 'l';

Legg merke til spesifikasjonen 'NoExcept' like etter riktig parentes i funksjonsparameterlisten. Dette betyr at funksjonen ikke skal kaste et unntak. Hvis funksjonen kaster et unntak, som i dette tilfellet, vil den sammenstille med en advarsel, men ikke vil kjøre. Et forsøk på å kjøre programmet vil kalle den spesielle funksjonen std :: avslutte (), som skal stoppe programmet grasiøst i stedet for bare å la det bokstavelig talt krasje.

NoExcept -spesifikasjonen er i forskjellige former. Disse er som følger:

type func () noexcept; : tillater ikke et kastuttrykk
type func () noexcept (true); : tillater et kastuttrykk
type func () kast (); : tillater ikke et kastuttrykk
type func () noexcept (falsk); : tillater et kastuttrykk, som er valgfritt
type func (); : tillater et kastuttrykk, som er valgfritt

Sann eller usant i parentesene kan erstattes av et uttrykk som resulterer i sant eller usant.

Den spesielle STD :: Termininate () -funksjonen:

Hvis et unntak ikke kan håndteres, bør det kastes på nytt. I dette tilfellet kan det kastede uttrykket kanskje ikke ha en operand. Spesialfunksjonen std :: avslutt () vil bli kalt ved runtime, som skal stoppe programmet grasiøst i stedet for bare å la det bokstavelig talt krasje.

Skriv, kompiler og kjør følgende program:

#inkludere
ved hjelp av navneområdet STD;
char input = '1';
int main ()

prøve

if (isDigit (input))
Kast 10;

fangst (int)

kaste;

retur 0;

Etter en vellykket samling, avsluttet programmet uten å kjøre, og feilmeldingen fra forfatterens datamaskin er:

“Avslutt ringt etter å ha kastet en forekomst av 'int'

Abortert (kjernedumped) ”

Konklusjon:

Unntaksfunksjonen i C ++ forhindrer et kodesegment i å utføre basert på en slags inngang. Programmet fortsetter å utføre etter behov. Unntaket (feilforebygging) konstruksjon består av en prøveblokk og en fangstblokk. Try-Block har kodesegmentet av interesse, som kan omgås, avhengig av noen inngangsbetingelser. Try-blokken har kastet uttrykk, som kaster en operand. Denne operanden kalles også unntaket. Hvis operandtypen og typen for parameteren til fangstblokken er den samme, blir unntaket fanget (håndtert). Hvis unntaket ikke blir fanget, vil programmet bli avsluttet, men likevel være trygt siden kodesegmentet som skulle utføres for å gi feil resultat ikke er utført. Typisk unntakshåndtering betyr å omgå kodesegmentet og sende en feilmelding til brukeren. Kodesegmentet utføres for normal inngang, men forbigått for gale innganger.