C ++

Erandite käsitlemine C ++ keeles

Erandite käsitlemine C ++ keeles
Tarkvaravigu on kolme tüüpi. Need on süntaksivead, loogikavead ja käitamisvead.

Süntaksivead

Valesti sisestatud avaldis, lause või konstruktsioon on süntaksiviga.

Vaatleme kahte järgmist väidet:

int arr [] = 1, 2, 3; // õige
int arr = 1, 2, 3; // süntaksiviga, puudub []

Need on sama massiivi definitsioonid. Esimene on õige. Teisel puudub [] ja see on süntaksiviga. Süntaksiveaga programmi ei õnnestu kompileerida. Kompileerimine ebaõnnestub süntaksi tõrget näitava veateatega. Hea on see, et süntaksiviga saab alati parandada, kui programmeerija teab, mida ta teeb.

Loogikaviga

Loogikaviga on viga, mille programmeerija on teinud vale loogilise kodeerimise korral. Selle põhjuseks võib olla programmeerija teadmatus programmeerimiskeele omaduste vastu või arusaamatus selle kohta, mida programm peaks tegema.

Selles olukorras koostatakse programm edukalt. Programm töötab hästi, kuid see annab valesid tulemusi. Selline viga võib olla tingitud sellest, et tsükkel kordub 5 korda, kui see pannakse kordama 10 korda. Võib ka juhtuda, et teadmatult tehakse silmus lõpmatuks kordamiseks. Ainus viis sellise vea lahendamiseks on hoolikas programmeerimine ja programmi põhjalik testimine enne selle kliendile üleandmist.

Käitusaja vead

Vale või erandlik sisend põhjustab käitamisvigu. Sel juhul koostati programm edukalt ja töötab hästi paljudes olukordades. Teatud olukordades jookseb programm kokku (ja peatub).

Kujutage ette, et programmikoodisegmendis tuleb 8 jagada mitme nimetajaga. Nii et kui lugeja 8 jagatakse nimetajaga 4, oleks vastuseks (jagatis) 2. Kui aga kasutaja sisestab nimetajana 0, siis krahhib programm. 0-ga jagamine pole matemaatikas lubatud, samuti pole see lubatud arvutamisel. Programmeerimisel tuleks vältida nulliga jagamist. Erandikäsitlus käsitleb käitamisvigu, näiteks jagamine nulliga. Järgmine programm näitab, kuidas lahendada nulliga jagamise probleemi ilma C ++ erandfunktsiooni kasutamata:

# kaasata
nimeruumi kasutamine std;
int main ()

int lugeja = 8;
int nimetaja = 2;
kui (nimetaja != 0)

int tulemus = lugeja / nimetaja;
cout << result << '\n';

muud

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

tagastama 0;

Väljund on 4. Kui nimetaja oli 0, oleks väljund olnud:

“Nulliga jagamine pole lubatud!”

Peamine kood on siin if-else konstrukt. Kui nimetaja pole 0, toimub jagamine; kui see on 0, jagamist ei toimu. Kasutajale saadetakse veateade ja programm töötab edasi ilma krahhita. Käitusaja tõrkeid käsitletakse tavaliselt koodisegmendi käivitamist vältides ja kasutajale tõrketeate saatmisega.

C ++ erandfunktsioon kasutab vea käsitsemiseks if-ploki jaoks try-blocki ja muu-blocki jaoks catch-blocki järgmiselt:

# kaasata
nimeruumi kasutamine std;
int main ()

int lugeja = 8;
int nimetaja = 2;
proovige

kui (nimetaja != 0)

int tulemus = lugeja / nimetaja;
cout << result << '\n';

muud

visata 0;


saak (int viga)

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

tagastama 0;

Pange tähele, et proovipäisel pole argumenti. Pange tähele ka seda, et püüdmisblokil, mis on nagu funktsiooni määratlus, on parameeter. Parameetri tüüp peab olema sama mis viskeväljendi operand (argument). Vise-avaldis on try-block. See viskab argumendi programmeerija valikust, mis on seotud veaga, ja püüdmisplokk püüab selle kinni. Nii ei käivitata proovibloki koodi. Seejärel kuvab püüdeplokk tõrketeate.

Selles artiklis selgitatakse erandite käsitlemist C-s++. Põhiteadmised C ++ keeles on lugejale selle artikli mõistmise eelduseks.

Artikli sisu:

  • Funktsioon Erandi viskamine
  • Rohkem kui üks püüdmisblokk ühe proovimise blokeerimise jaoks
  • Pesastatud proovige / püüdke plokke
  • noexcept-täpsustaja
  • Funktsioon Special std :: terminate ()
  • Järeldus

Funktsioon erandi viskamine:

Funktsioon võib visata ka erandi, nagu see, mida teeb try-block. Vise toimub funktsiooni definitsiooni piires. Järgmine programm illustreerib seda:

# kaasata
nimeruumi kasutamine std;
void fn (const char * str)

kui (islower (str [0]))
viska 'l';

int main ()

proovige

fn ("sepp");

saak (char ch)

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

tagastama 0;

Pange tähele, et seekord on prooviplokil ainult funktsioonikõne. Nimetatud funktsioonil on visketoiming. Püügiplokk püüab erandi ja väljund on:

"Isiku nimi ei saa alata väiketähtedega!”

Seekord on visatud ja tabatud tüüp söe.

Ühe proovibloki jaoks rohkem kui üks püüdmisplokk:

Ühe proovibloki jaoks võib olla rohkem kui üks püüdmisblokk. Kujutage ette olukorda, kus sisendiks võib olla mõni klaviatuuri tähemärk, kuid mitte number ega tähestik. Sel juhul peab olema kaks püüdeplokki: üks täisarvu numbri kontrollimiseks ja teine ​​tähestiku kontrollimiseks. Järgmine kood illustreerib seda:

# kaasata
nimeruumi kasutamine std;
char sisend = '*';
int main ()

proovige

kui (isdigit (sisend))
visata 10;
kui (isalpha (sisend))
viska 'z';

saak (int)

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

saak (söe)

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

tagastama 0;

Väljundit pole. Kui sisendi väärtus oleks number, e.g., '1', väljund oleks olnud:

"Numbrite sisestamine on keelatud!"

Kui sisendi väärtus oleks tähestik, e.g., "a", oleks väljund olnud:

"Märkide sisestamine on keelatud!"

Pange tähele, et kahe püüdmisploki parameetrite loendis pole identifikaatori nime. Pange tähele ka seda, et kahe püüdmisbloki määratluses pole konkreetseid visatud argumente kontrollitud, kas nende väärtused on täpsed või mitte.

Saagi jaoks on oluline tüüp; saak peab vastama visatud operandi tüübile. Viskatud argumendi (operandi) konkreetset väärtust saab vajadusel kasutada täiendavaks kontrollimiseks.

Sama tüübi jaoks rohkem kui üks käitleja

Võimalik on kaks sama tüüpi käitlejat. Erandi viskamisel antakse juhtimine üle lähimale vastava tüübiga käitlejale. Järgmine programm illustreerib seda:

# kaasata
nimeruumi kasutamine std;
char sisend = '1';
int main ()

proovige

kui (isdigit (sisend))
visata 10;

saak (int)

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

saak (int)

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

tagastama 0;

Väljund on:

"Numbrite sisestamine on keelatud!"

Pesastatud proovimise / püüdmise plokid:

try / catch plokid saab pesitseda. Siin korratakse ülaltoodud programmi mitte-tähtnumbriliste märkide sisestamiseks klaviatuurilt, kuid tähestikulise veakoodiga on pesa tehtud:

# kaasata
nimeruumi kasutamine std;
char sisend = '*';
int main ()

proovige

kui (isdigit (sisend))
visata 10;
proovige

kui (isalpha (sisend))
viska 'z';

saak (söe)

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


saak (int)

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

tagastama 0;

Vea tähestikuline try / catch-block on sisestatud numbrikoodi try-blocki. Selle programmi töö ja eelmine toiming, millest see kopeeritakse, on samad.

noexcept-täpsustaja

Mõelge järgmisele funktsioonile:

void fn (const char * str) noexcept

kui (madalam (str [0]))
viska 'l';

Pange tähele täpsustajat „noexcept” kohe pärast funktsiooni parameetrite loendi parempoolset sulgu. See tähendab, et funktsioon ei tohiks olla erand. Kui funktsioon loob erandi, nagu käesoleval juhul, siis kompileeritakse see hoiatussõnumiga, kuid ei käivitu. Programmi käivitamise katse kutsub erifunktsiooni std :: terminate (), mis peaks programmi graatsiliselt peatama, selle asemel, et lihtsalt sõna otseses mõttes kokku kukkuda.

Noexcept täpsustaja on erinevates vormides. Need on järgmised:

tüüp func () noexcept; : ei luba viset väljendada
tüüp func () noexcept (true); : võimaldab viskeväljendit
tüüp func () viska (); : ei luba viset väljendada
tüüp func () noexcept (false); : võimaldab viskeväljendit, mis on valikuline
tüüp func (); : võimaldab viskeväljendit, mis on valikuline

tõelise või vale sulgudes saab asendada avaldisega, mille tulemuseks on tõene või väär.

Funktsioon Special std :: terminate ():

Kui erandiga ei saa hakkama, tuleks see uuesti visata. Sellisel juhul võib visatud väljendil olla operand või mitte. Erifunktsioon std :: terminate () kutsutakse käitamise ajal, mis peaks programmi graatsiliselt peatama, selle asemel, et lasta sellel sõna otseses mõttes kokku kukkuda.

Sisestage, kompileerige ja käivitage järgmine programm:

# kaasata
nimeruumi kasutamine std;
char sisend = '1';
int main ()

proovige

kui (isdigit (sisend))
visata 10;

saak (int)

visata;

tagastama 0;

Pärast edukat kompileerimist lõpetati programm ilma käivitamiseta ja autori arvutist kuvatakse tõrketeade:

"Lõpetada kutsutakse pärast viskavad" int "eksemplari

Katkestatud (tuum visatud) ”

Järeldus:

C ++ erandfunktsioon takistab koodisegmendi käivitamist mingisuguse sisendi põhjal. Programmi jätkatakse vastavalt vajadusele. Erandkonstruktsioon (vigade ennetamine) koosneb prooviblokist ja püüdeplokist. Prooviblokil on huvi pakkuv koodisegment, millest võidakse mööda minna, sõltuvalt mõnest sisendtingimusest. Try-blockil on viskeväljend, mis viskab operandi. Seda operandi nimetatakse ka erandiks. Kui operandi tüüp ja püüdmisploki parameetri tüüp on ühesugused, siis püütakse erand kinni (käsitletakse). Kui erandit ei tabata, lõpetatakse programm, kuid see on siiski ohutu, kuna vale tulemuse saamiseks käivitatavat koodisegmenti pole täidetud. Tüüpiline erandite käsitlemine tähendab koodisegmendi ümbersõitu ja veateate saatmist kasutajale. Koodisegment täidetakse tavalise sisendi jaoks, kuid valede sisendite korral mööda.

Lahing Wesnothi õpetuse eest
Battle for Wesnoth on üks populaarsemaid avatud lähtekoodiga strateegiamänge, mida saate praegu mängida. See mäng pole mitte ainult olnud väga pikka a...
0 A.D. Õpetus
Paljudest strateegiamängudest on 0 A.D. suudab silma paista põhjaliku tiitli ja väga sügava taktikalise mänguna, hoolimata sellest, et see on avatud l...
Unity3D õpetus
Sissejuhatus Unity 3D-sse Unity 3D on võimas mängude arendamise mootor. See on platvormidevaheline, mis võimaldab teil luua mänge mobiilseadmetele, ve...