Kontrollfunktsioonid

Sageli võib programmistruktuurist lähtudes eeldada, et üks või teine muutuja omab antud hetkel mingit kindlat väärtust. Näiteks enne mälublokile näitava viida kasutamist võime oletada, et too viit ei oma väärtust NULL. Kui see aga nii oleks ja me ikkagi seda viita kasutaksime, siis oleks tulemuseks raske viga. Seega tuleks mainitud oletust enne viida kasutamist kontrollida ja kui ta ei kehti ning mingit muud võimalust programmi tööd jätkata ei ole, siis tuleks programmi töö ise lõpetada. Selliseks otstarbeks on loodud päisefail ASSERT.H, mis sisaldab vaid ühe makro - assert().

void assert(int test);

Makro assert() sisaldab tingimuslauset if, mis kontrollib, kas talle üle antud avaldis omab väärtust 0 (tõeväärtus VÄÄR). Kui see nii on, siis väljastab ta voole strerr teate:

	Assertation failed: <test> file <faili nimi> line <rea number>

ning kutsub seejärel välja funktsiooni abort() programmi lõpetamiseks.

void abort( void );

Funktsioon abort() on defineeritud päisefailis STDLIB.H ning ka päisefailis PROCESS.H. See funktsioon väljastab voole stderr teate:

	Abnormal programm termination

ja kasutab seejärel programmi töö lõpetamiseks funktsiooni _exit().

Makrot assert() kasutatakse enamasti programmi kontrolli käigus, kui veel ei olda kindel programmi korrektses töös. Hiljem võib valmis programmist need kontrollid eemaldada, et programmi töökiirust tõsta. Selleks tuleks sisestada programmi teksti enne eeltranslaatori käsku #include <ASSERT.H> käsk #define NDEBUG. Viimane käsk määrab, et programm tuleks transleerida valmis kujul ja sel juhul asendab eeltranslaator makro assert() tühikuga.

Päisefail CTYPE.H defineerib sümbolite klassifitseerimiseks hulga funktsioone. Sümboleid võib jagada tähtedeks (mis omakorda jagunevad väike- ja suurtähtedeks), numbriteks, kirjavahemärkideks (punkt, koma, semikoolon jne.) ja muudeks. Nimetatud funktsioonid vajavd kõik ühte parameetrit - uuritavat sümbolit, ja loovutavad positiivse väärtuse, kui nimetatud sümbol kuulus vastavasse sümbolite klassi ning vastasel juhul nulli. Järgnevas tabelis näete nende funktsioonide ülevaadet.


Funktsioon Sümbolite klass
int isalnum(int c); c on harilik täht või number: A - Z, a - z, 0 - 9
int isalpha(int c); c on harilik täht: A - Z, a - z
int isascii(int c); c esimene bait omab väärtust piirides 0 - 127
int iscntrl(int c); c vastab klahvile <DEL> või mingile laiendatud ASCII koodiga kontrollklahvile, mille esimene bait on null: 0x7F või 0x00 kuni 0x1F.
int isdigit(int c); c on number: 0 - 9
int isgraph(int c); c on ekraanile väljastatav sümbol, s.t. sama mis isprint(), ainult et seekord ei loeta tühikut (0x20) õigete sümbolite hulka.
int islower(int c); c on väiketäht: a - z
int isprint(int c); c on ekraanile trükitav täht: 0x20 - 0x7E. Väiksemad sümbolid kujutavad endast kontrollkoode, mille väljastamine ekraanile ei esita sinna mingit sümbolit, vaid hoopis täidab mingi operatsiooni, näiteks 0x07 väljastab hoiatava helisignaali.
int ispunct(int c); c on kirjavahemärk või kontrollkood: (isspace() || iscntrl())
int isspace(int c); c on tühik, horisontaalne või vertikaalne tabulaator, reavahetuse märk või uue rea märk: ' ', '\t', '\v', '\n', '\r'
int isupper(int c); c on suurtäht: A - Z
int isxdigit(int c); c on number kuueteistkümnendsüsteemis: 0 - 9, A - F, a - f

Tabel 21: Sümbolite klassifitseerimisfunktsioonid

Päisefail CTYPE.H sisaldab ka funktsioone sümbolite konverteerimiseks soovitud sümbolite klassi.

int tolower(int ch);
int _tolower(int ch);
int toupper(int ch);
int _toupper(int ch);

Funktsioon tolower() konverteerib talle üleantud suurtähe vastavaks väiketäheks. Kui antud täht juba on väiketäht või ei ole üldsegi täht, siis seda ei muudeta. Makro _tolower() täidab sama ülesande, kuid ta ei kontrolli enne tähe tegelikku väärtust ja seega tuleks teda kasutada vaid siis, kui antud täht kindlasti on suurtäht. Ta töötab on aga kiiremini kui funktsioon tolower(). Sarnaselt konverteerib funktsioon toupper() iga väiketähe vastavaks suurtäheks ja makro _touper() teeb sama ilma eelneva kontrollita.

Kindlustamaks, et mingi sümbol on ASCII täht, tuleks kasutada makrot toascii().

int toascii(int ch);

Makro toascii() kindlustab, et arvu ch kõik bitid, väljaarvatud esimesed 7, on nullid. Seega on tulemus mingi väärtus piires 0 - 127, mis vastab tähtede ASCII koodidele.

Arvutis kasutatavad muutujad omavad kõik kindlat pikkust ja seega on arvuti muutujate väärtused piiratud. Nende piiride ületamine võib tekitada üsna üllatavaid tulemusi. Näiteks täisarv (int) kasutab kahte baiti ja võib seega salvestada väärtusi piirides - 32.768 kuni 32.767. Kui te sellisele muutujale omistate algul väärtuse 32.767 ja seejärel liidate veel ühe, siis ei ole tulemuseks mitte 32.768 vaid hoopiski - 32.768. See on tingitud täisarvude salvestamise viisist. Pikkade täisarvude (long) puhul tuleb see piir hiljem, kuid ka neil arvudel on suurim võimalik väärtus. Need piirid on defineeritud sümboolsete konstantidena päisefailis LIMITS.H

Järgmises tabelis näete nimetatud konstante ja neile vastavaid andmetüüpe.


Andmetüüp Konstant Väärtus
char CHAR_BIT bittide arv (8)

CHAR_MAX maksimaalne väärtus (127)

CHAR_MIN minimaalne väärtus (-128)
unsigned char UCHAR_MAX maksimaalne väärtus (255)
signed char SCHAR_MAX maksimaalne väärtus (127)

SCHAR_MIN minimaalne väärtus (-128)
int INT_MAX maksimaalne väärtus (32.767)

INT_MIN minimaalne väärtus (-32.768)
unsigned int UINT_MAX maksimaalne väärtus (65.535)
short SHRT_MAX maksimaalne väärtus (32.767)

SHRT_MIN minimaalne väärtus (-32.768)
unsigned short USHRT_MAX maksimaalne väärtus (65.535)
long LONG_MAX maksimaalne väärtus (2.147.483.647)

LONG_MIN minimaalne väärtus (-2.147.483.648)
unsigned long ULONG_MAX maksimaalne väärtus (4.294.967.295)

Tabel 23: Andmetüüpide minimaalsed ja maksimaalsed väärtused


Tabelis toodud väärtused kehtivad aga ainult 8086 ja 80286 tüüpi protsessoriga arvutil. 80386 protsessori puhul on näiteks andmetüübi int piirid võrdsed tüübi long omadega. Seda muidugi ainult juhul, kui ka translaator on selle protsessori jaoks loodud. Nende erinevuste tõttu ongi soovitavam kasutada otseste väärtuste asemel siintoodud sümboolseid konstante. Teistsuguse protsessori puhul on piirid teistsugused, kuid ka vastavate sümboolsete konstantide väärtused on sellele vastavalt muudetud.

Murdarvude puhul kasutatakse veel konstanti HUGE_VAL, mis sümboliseerib murdarvu suurimat (ja -HUGE_VAL tema vähimat) väärtust. See konstant on defineeritud päsefailis MATH.H