Muutujate deklareerimine ja algväärtustamine

Muutujate deklareerimine

C-keeles deklareerime alati muutuja määrates andmetüüp ja muutuja nimi, kasutades süntaksit data_type variable_name; .

Kui sama andmetüübiga muutujaid on rohkem, eraldatakse need komaga data_type variable_name_1, variable_name_2;.  Sellisel viisil saab deklareerida suvalise arvu muutujaid, aga mida rohkem on muutujaid, seda raskemini loetavaks kood muutub!

Muutujate algväärtustamine

Iga muutuja võib deklareerimise käigus algväärtustada, omistades sellele väärtuse vastavalt süntaksile data_type variable_name = initial_value; . Vastavalt koodimisstiilile tuleb iga muutuja, millele omistatakse algväärtus, deklareerida eraldi real. See on oluline eelkõige koodi loetavuse seisukohalt.

Andmetüübid

C keel jätab muutuja andmetüüpide deklareerimisel mõned asjad lahtiseks. Nimelt määrab C standard ainult muutuja minimaalse suuruse baitides ja andmetüüpide suuruste vahelise seose. Seda on oluline meeles pidada, kui andmetüübi suurus esitatakse fikseeritud numbrina – see ei ole alati korrektne!

Järgnevas tabelis on toodud põhilisemad andmetüübid ja formaadid. Põhjalikuma ülevaate saamiseks vaadake https://en.wikipedia.org/wiki/C_data_types või  https://www.tutorialspoint.com/cprogramming/c_data_types.htm

 
Andmetüüp Miinimum suurus (baitides) Kasutusjuht Formaat Kommentaarid
char 1 tähemärk %c ASCII kodeerimine
char [] ? sõne %s Null-terminaatoriga ASCII-märkidest massiiv
int 2 väiksemad täisarvud

 

%d %i Suurus sõltub platvormist
long 4 Pikemad täisarvud %ld %li Suurus sõltub platvormist. Soovitatav on selle asemel kasutada bit-width täisarve
float 4 reaalarvud, ujukomaarvud %f Madal täpsus, vältida nt rahaliste väärtuste puhul jne
double 8 reaalarvud, kahekordse täpsusega ujukoma arv %lf Parem täpsus, kuid siiski ebasobiv, kui nõutakse suurt täpsust

Märkus: minimaalne suurus ja seos on väga märgatav, kui programmeeritakse mikrokontrollereid. Nt tavalisel lauaarvutil, sülearvutil ja serveril on int  4 baiti, aga enamikel Arduino arendusplaatidel on int  2 baiti. Ühtlasi peab  long  andmetüüp olema 2x suurem kui int , seega lauaarvutil on see tõenäoliselt 8 baiti, kuid Arduinol 4 baiti. See on omakorda sõltuv sellest, millist mikroprotsessorit Arduino mikrokontroller kasutab.

Bit-width täisarvu andmetüüpide kasutamiseks tutvu teegiga inttypes.h . Seda käsitleme ka Programmeerimine 1 kursusel.

Massiivide deklareerimine

Massiive deklareeritakse sama süntaksi alusel nagu muutujaid, lisades deklaratsiooni soovitud massiivi pikkuse data_type array_name[array_size]; . Pikkuse määramine on kohustuslik staatiliste massiivide puhul.

Maagiliste numbrite vältimiseks kasutatakse sageli makrot ( #define ) või const  piiranguga muutujat

Massiivide algväärtustamine

Massiive saab algväärtustada deklaratsiooni käigus, määrates loogeliste sulgude { }  vahel kas kõik väärtused või alamhulga väärtustest, nt data_type array_name[array_size] = {val_1, val_2, ..., val_n-1}; .

Massiivi algväärtustamisel võib massiivi suuruse  array_size määramata jätta. Sellisel juhul leiab kompilaator massiivi pikkuse vastavalt algväärtustatud liikmete arvule.

Massiivi algväärtustamine nullideks

Massiivid võivad olla null-väärtustatud kasutades süntaksit data_type array_name[array_size] = {0};.  Sellisel juhul arvesta, et kui massiivi pikkus ei ole määratud, siis saab massiivi pikkuseks 1.

Mitme-dimensiooniliste massiivide deklareerimine ja initsialiseerimine

Kõik massiivi dimensioonid tuleb deklaratsiooni käigus spetsifitseerida. 2-dimensioonilise massiivi deklareerimiseks kasutame tavaliselt süntaksit data_type array_name[row_cnt][col_cnt];. Ridade ja veergude kasutamine on illustreeriv (mõtle nt Exceli tabelile), kuid ka väga levinud praktika.

2-D massiivi initsialiseerimisel kasutame pesastatud sulge ridade eristamiseks. Väärtuste joondamine ei ole kohustuslik, kuid on abiks hooldatavuse seisukohalt.

Pane tähele, et mitmemõõtmelises massiivis võib esimese mõõtme (st ridade arvu) ära jätta, kuid selle peab hiljem välja arvutama, et massiivi itereerida.

Sõnede deklareerimine

C-keeles käsitletakse sõne null-lõpuga massiividena. Iga massiivi element on ASCII-koodis esindatud märk, mille suurus on 1 bait. Sõnel peab alati olema varuks üks lisamärk null-lõpu jaoks.

Märkus: Sellist sõne lugemise viisi ei soovitata C-keeles kasutada, aga see on jäetud illustratsiooniks, et hoida see lihtsa ja lühikesena. Õigeid sõne lugemise viise tutvustatakse vastavas loengus.

Sõnede initsialiseerimine

Sõned initsialiseeritakse tihti sõne literaalidena, jättes massiivi pikkuse määramata – nii saab kompilaator tuvastada massiivi pikkuse. Sõned on alati ümbritsetud jutumärkidega, kuid üksikud tähemärgid on ümbritsetud ülakomadega.

Järgmises näites koosneb sõne 13 märgist, samas massiiv on deklareeritud 14 baidi pikkuseks, et oleks ruumi lõpu märgile NUL. Väljend null-lõpp (zero-terminated) tuleb sellest, et ASCII sümbol NUL omab täisarvulist väärtust 0 (null)

Enamik ajast kasutatakse tühjade kantsulgude asemel muutuja nime ees tärni. Sellel on täpselt sama mõju.

Tühja sõne initsialiseerimine

Tühja sõne initsialiseerimisel peame olema kindlad, et sõne oleks piisava pikkusega vastavalt planeeritavale kasutusjuhule.

ÄRA KASUTA char *string = "";  ega char string[] = "";. Kompilaator arvutab massiivi pikkuse initsialiseerimise baasil- need on tühjad sõned, mis sisaldavad ainult sõne lõputähist, mille tulemuseks on 1-baidine pikkus ja seetõttu ei mahu sinna ühtegi muud märki.

Sõnedest koosneva massiivi deklareerimine

Sõnede massiive käsitletakse sarnaselt kahemõõtmeliste massiividega, kuid sõltuvalt deklareerimise viisist võib esineda mõningaid erandeid.

Deklaratsioon char strings[num_of_strings][string_length]; võimaldab luua kindla arvu sõnesid, mille määrab esimene pikkus (st   num_of_string ), kus iga sõne saab olla kuni string_length - 1  märgi pikkune. Kõik sõned kasutavad sama palju mälu olenemata tegelikust pikkusest.

Sellist tüüpi deklaratsioon on ebatavaline ja suuresti ebapraktiline. Rohkem levinud näide on toodud järgmises peatükis.

Sõnedest koosneva massiivi initsialiseerimine

Sõnede massiiv deklareeritakse tavaliselt massiivina, mille elemendid on viidad sõnedele. Selleks kasutatakse järgmist süntaksit:

char *strings[] = {"string1", "string2", ..., "string_n-1"};

Selle eeliseks on see, et kompilaator määrab automaatselt nii massiivi kui ka iga initsialiseeritud sõne suuruse. See on ka käsureaargumentide struktuur.