C++

Afhandeling van uitzonderingen in C++

Afhandeling van uitzonderingen in C++
Er zijn drie soorten softwarefouten:. Dit zijn syntaxisfouten, logische fouten en runtime-fouten.

Syntaxisfouten

Een verkeerd getypte uitdrukking, instructie of constructie is een syntaxisfout.

Beschouw de volgende twee uitspraken:

int arr[] = 1, 2, 3; //correct
int arr = 1, 2, 3; //syntaxisfout, ontbreekt []

Het zijn definities van dezelfde array. De eerste klopt. De tweede ontbreekt [], en dat is een syntaxisfout. Een programma met een syntaxisfout slaagt er niet in om te compileren. De compilatie mislukt met een foutmelding die de syntaxisfout aangeeft. Het goede is dat een syntaxisfout altijd kan worden verholpen als de programmeur weet wat hij doet.

Logische fout

Een logische fout is een fout begaan door de programmeur wanneer een verkeerde logische codering is gemaakt. Het kan het gevolg zijn van onwetendheid van de programmeur over de programmeertaalfuncties of een verkeerd begrip van wat het programma zou moeten doen.

In deze situatie is het programma succesvol gecompileerd. Het programma werkt prima, maar het geeft verkeerde resultaten. Zo'n fout kan zijn doordat een lus 5 keer wordt herhaald wanneer deze 10 keer wordt herhaald. Het kan ook zijn dat er onbewust een lus gemaakt wordt om oneindig te itereren. De enige manier om dit soort fouten op te lossen, is door zorgvuldig te programmeren en het programma grondig te testen voordat u het aan de klant overhandigt.

Runtime-fouten

Verkeerde of uitzonderlijke invoer veroorzaakt runtime-fouten. In dit geval is het programma succesvol gecompileerd en werkt het in veel situaties goed. In bepaalde situaties crasht het programma (en stopt).

Stel je voor dat in een programmacodesegment 8 moet worden gedeeld door een aantal noemers. Dus als de teller 8 wordt gedeeld door de noemer 4, is het antwoord (quotiënt) 2. Als de gebruiker echter 0 invoert als de noemer, crasht het programma. Delen door 0 is niet toegestaan ​​in wiskunde, en het is ook niet toegestaan ​​in informatica. Delen door nul moet worden voorkomen bij het programmeren. Afhandeling van uitzonderingen verwerkt runtime-fouten, zoals delen door nul. Het volgende programma laat zien hoe u het deling-door-nul-probleem kunt oplossen zonder de uitzonderingsfunctie in C++ te gebruiken:

#include
namespace std; gebruiken;
int hoofd()

int teller = 8;
int noemer = 2;
als (noemer) != 0)

int resultaat = teller/noemer;
cout << result << '\n';

anders

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

retourneer 0;

De uitvoer is 4. Als de noemer 0 was, zou de uitvoer zijn geweest:

“Delen door nul is niet toegestaan!”

De hoofdcode hier is een if-else constructie. Als de noemer niet 0 is, vindt de deling plaats; als het 0 is, zal de deling niet plaatsvinden. Er wordt een foutmelding naar de gebruiker gestuurd en het programma blijft draaien zonder te crashen. Runtime-fouten worden meestal afgehandeld door de uitvoering van een codesegment te vermijden en een foutmelding naar de gebruiker te sturen.

De uitzonderingsfunctie in C++ gebruikt een try-block voor het if-block en een catch-block voor het else-block om de fout af te handelen, net als volgt:

#include
namespace std; gebruiken;
int hoofd()

int teller = 8;
int noemer = 2;
proberen

als (noemer) != 0)

int resultaat = teller/noemer;
cout << result << '\n';

anders

gooi 0;


vangen (int fout)

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

retourneer 0;

Merk op dat de try-header geen argument heeft. Merk ook op dat het catch-blok, dat lijkt op een functiedefinitie, een parameter heeft. Het type parameter moet hetzelfde zijn als de operand (argument) van de throw-expressie. De worp-expressie bevindt zich in het try-blok. Het gooit een argument naar keuze van de programmeur dat gerelateerd is aan de fout, en het catch-blok vangt het op. Op die manier wordt de code in het try-blok niet uitgevoerd. Vervolgens geeft het catch-blok de foutmelding weer.

In dit artikel wordt de afhandeling van uitzonderingen in C . uitgelegd++. Basiskennis in C++ is een voorwaarde voor de lezer om dit artikel te begrijpen.

Artikel Inhoud:

  • Functie Een uitzondering maken
  • Meer dan één catch-block voor één try-block
  • Geneste try/catch-blokken
  • nobehalve-specificatie
  • De speciale std::terminate() functie
  • Conclusie

Functie die een uitzondering gooit:

Een functie kan ook een uitzondering genereren, net zoals het try-block doet. Het werpen vindt plaats binnen de definitie van de functie. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
void fn(const char* str)

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

int hoofd()

proberen

fn("smid");

vangen (char ch)

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

retourneer 0;

Merk op dat deze keer het try-blok alleen de functieaanroep heeft. Het is de aangeroepen functie die de worpbewerking heeft. Het catch-blok vangt de uitzondering en de uitvoer is:

“De naam van de persoon mag niet beginnen in kleine letters!”

Deze keer is het type dat wordt gegooid en gevangen een char.

Meer dan één catch-blocks voor één try-block:

Er kan meer dan één catch-block zijn voor één try-block. Stel je de situatie voor waarin een invoer een van de tekens van het toetsenbord kan zijn, maar geen cijfer en geen alfabet. In dit geval moeten er twee catch-blocks zijn: een voor een geheel getal om het cijfer te controleren en een voor een char om het alfabet te controleren. De volgende code illustreert dit:

#include
namespace std; gebruiken;
char invoer = '*';
int hoofd()

proberen

if (isdigit(invoer))
gooi 10;
if (isalpha(invoer))
gooi 'z';

vangen (int)

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

vangen (char)

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

retourneer 0;

Er is geen uitvoer. Als de invoerwaarde een cijfer was, e.g., '1', de output zou zijn geweest:

"Cijferinvoer is verboden!"

Als de invoerwaarde een alfabet was, e.g., 'a', de output zou zijn geweest:

"Tekeninvoer is verboden!"

Merk op dat er in de parameterlijst van de twee catch-blokken geen identifier-naam is. Merk ook op dat in de definitie van de twee catch-blokken de specifieke argumenten die worden gegooid niet zijn geverifieerd of hun waarden exact zijn of niet.

Wat voor een vangst belangrijk is, is het type; een vangst moet overeenkomen met het type operand dat wordt gegooid. De specifieke waarde van het argument (operand) dat wordt gegooid, kan indien nodig worden gebruikt voor verdere verificatie.

Meer dan één handler voor hetzelfde type

Het is mogelijk om twee handlers van hetzelfde type te hebben. Wanneer een uitzondering wordt gegenereerd, wordt de controle overgedragen aan de dichtstbijzijnde handler met een overeenkomend type. Het volgende programma illustreert dit:

#include
namespace std; gebruiken;
char-invoer = '1';
int hoofd()

proberen

if (isdigit(invoer))
gooi 10;

vangen (int)

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

vangen (int)

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

retourneer 0;

De uitvoer is:

"Cijferinvoer is verboden!"

Geneste try/catch-blokken:

try/catch-blokken kunnen worden genest. Het bovenstaande programma voor het invoeren van niet-alfanumerieke tekens vanaf het toetsenbord wordt hier herhaald, maar met de alfabetische foutcode genest:

#include
namespace std; gebruiken;
char invoer = '*';
int hoofd()

proberen

if (isdigit(invoer))
gooi 10;
proberen

if (isalpha(invoer))
gooi 'z';

vangen (char)

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


vangen (int)

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

retourneer 0;

De alfabetische fout try/catch-block is genest in het try-block van de cijfercode. De werking van dit programma en de vorige bewerking waarvan het gekopieerd is, zijn hetzelfde.

nobehalve-specificatie

Denk aan de volgende functie:

void fn(const char* str) neebehalve

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

Let op de specificatie 'nobehalve' net na het rechter haakje van de functieparameterlijst. Dit betekent dat de functie geen uitzondering mag genereren. Als de functie een uitzondering genereert, zoals in dit geval, wordt deze gecompileerd met een waarschuwingsbericht maar niet uitgevoerd. Een poging om het programma uit te voeren zal de speciale functie std::terminate() aanroepen, die het programma netjes zou moeten stoppen in plaats van het letterlijk te laten crashen.

De nobehalve-specificatie heeft verschillende vormen. Deze zijn als volgt:

typ func() nobehalve; : staat geen worp-expressie toe
typ func() nobehalve(true); : staat een worp-expressie toe
typ func() throw(); : staat geen worp-expressie toe
typ func() nobehalve(false); : staat een worp-expressie toe, wat optioneel is
typ func(); : staat een worp-expressie toe, wat optioneel is

waar of onwaar tussen haakjes kan worden vervangen door een uitdrukking die resulteert in waar of onwaar.

De speciale std::terminate() Functie:

Als een uitzondering niet kan worden afgehandeld, moet deze opnieuw worden gegooid. In dit geval kan de gegooide uitdrukking al dan niet een operand hebben. De speciale functie std::terminate() wordt tijdens runtime aangeroepen, wat het programma netjes zou moeten stoppen in plaats van het letterlijk te laten crashen.

Typ, compileer en voer het volgende programma uit:

#include
namespace std; gebruiken;
char-invoer = '1';
int hoofd()

proberen

if (isdigit(invoer))
gooi 10;

vangen (int)

werpen;

retourneer 0;

Na een succesvolle compilatie is het programma gestopt zonder te starten en de foutmelding van de computer van de auteur is:

"beëindigen aangeroepen na het gooien van een instantie van 'int'

Afgebroken (kern gedumpt)”

Conclusie:

De uitzonderingsfunctie in C++ voorkomt dat een codesegment wordt uitgevoerd op basis van een soort invoer. Het programma wordt verder uitgevoerd als dat nodig is. Het exception-construct (foutpreventie) bestaat uit een try-block en een catch-block. Het try-blok heeft het codesegment van belang, dat kan worden omzeild, afhankelijk van een invoervoorwaarde. Het try-blok heeft de throw-expressie, die een operand . gooit. Deze operand wordt ook wel de exception genoemd. Als het operandtype en het type voor de parameter van het catch-blok hetzelfde zijn, wordt de uitzondering opgevangen (behandeld). Als de uitzondering niet wordt opgevangen, wordt het programma beëindigd, maar toch, wees veilig, aangezien het codesegment dat moest worden uitgevoerd om het verkeerde resultaat te geven, niet is uitgevoerd. Typische afhandeling van uitzonderingen betekent het omzeilen van het codesegment en het verzenden van een foutmelding naar de gebruiker. Het codesegment wordt uitgevoerd voor normale invoer, maar overbrugd voor verkeerde invoer.

Top 5 ergonomische computermuisproducten voor Linux
Veroorzaakt langdurig computergebruik pijn in uw pols of vingers?? Heb je last van stijve gewrichten en moet je constant de hand schudden?? Voelt u ee...
Hoe de muis- en touchpad-instellingen te wijzigen met Xinput in Linux
De meeste Linux-distributies worden standaard geleverd met de bibliotheek "libinput" om invoergebeurtenissen op een systeem af te handelen. Het kan in...
Wijs uw muisknoppen anders toe voor verschillende software met X-Mouse Button Control
Misschien heeft u een tool nodig waarmee u de bediening van uw muis kunt veranderen bij elke applicatie die u gebruikt. Als dit het geval is, kunt u e...