Andmetüübid

Programmeerimiskeel C nõuab iga muutuja jaoks selle andmetüübi määramist. Tüüp määrab muutuja salvestamiseks vajaliku mälupesa suuruse ja sinna salvestatud andmete tähenduse. Programmeerimiskeel C tunneb kolme põhilist andmetüüpi - sümbolid, täisarvud ja murdarvud. Iga tüüp koosneb omakorda mitmetest alamtüüpidest. Lisaks sellele saab sama tüüpi muutujaid koguda massividesse (array), opereerida nende aadressidega (pointers and references) ja luua tuntud tüüpide alusel uusi tüüpe (typedefs). Erinevaid tüüpe saab samuti koguda andmestruktuuridesse (structures and unions) ja luua niimoodi uusi tüüpe. Programmeerimiskeel C++ lisab sellele kõigele veel klassid, mis tähendavad tegelikult andmete ja nende töötlemiseks sobivate funktsioonide kogumist ühte tüüpi.

Põhilised tüübid vajavad teatud kindla hulga mälu. Kõige väiksem andmeühik on bitt. Üks bitt võib omada vaid väärtusi 1 ja 0. Seega võib üks bitt sisaldada vastust mingile küsimusele stiilis "ja või ei". Programmeerimiskeel C võimaldab ka üksikute bittide väärtusi muuta, kuid bitt ei ole siiski põhitüüp. Väikseim adresseeritav mäluühik on bait, mis koosneb kaheksast bitist. Baidi sees omab iga bitt kindlat positsioon, mis määrab tema tähenduse. Esimene bitt omab järjekorranumbrit 0 ja viimane 7.

Meie tavaline arvude süsteem on kümnendsüsteem. Ka siin omab iga positsioon erinevat tähendust. Näiteks arv 235 on väljendatav kujul:

2 * 10 + 3 * 10 + 5 * 100

Iga koht on kümne aste ja seega on see arv kümnendsüsteemis. Arvuti aga kasutab kahendsüsteemi. Iga koht on kahe aste ja võib omada vaid väärtusi 1 ja 0. Nimelt siin tulebki mängu bitt. Bitt on arvuti arvudesüsteemi aluseks. Iga suurem andmetüüp koosneb järjestatud bittidest, mis määravad arvu 2 astmete väärtused. Näitena toodud arv 235 muundatakse arvuti sees kujule 11101011, mis tähendab:

1 * 27 + 1 * 26 + 1 * 25 + 0 * 24 + 1 * 23 + 0 * 22 + 1 * 21 + 1 * 20

Nimetatud arv on väljendatav ka ühe baidi abil, kuna 28 - 1 = 255, mis on suurim ühe baidi abil väljendatav arv. Suuremate arvude jaoks on vajalik rohkem baite. Ühe sümboli jaoks aga jätkub ühest baidist. Tähed ja muud sümbolid salvestatakse arvutis numbrite abil. Igale sümbolile seatakse vastavusse mingi kindel arv vahemikus 0 - 255. Näiteks tähele 'A' vastab arv 65. Erinevaid koode on palju, neist kõige tuntum on ASCII kood.

Lõputute nullide ja ühtede jadadega opereerimine on raske ja seepärast kasutatakse veel kaheksand- ja kuueteistkümnendsüsteemi. Nende süsteemide alused on arvu 2 astmed ja seega on ühest süsteemist teise konverteerimine üsna lihtne.

Nagu juba mainitud, on igat tüüpi muutuja jaoks vajalik kindel arv baite. See arv on iga tüübi jaoks ühel protsessoril konstantne väärtus, kuid ärge lootke, et see on nii iga protsessori tüübi puhul. Kui te soovite teada mingi tüübi suurust baitides (näiteks faili salvestamisel või sealt lugemisel), siis kasutage programmi porteeritavuse huvides operaatorit sizeof(). Lisaks sellele vahetavad Inteli protsessorid suuremat tüüpi muutuja salvestamisel järjestikused baidid omavahel (byte swapping). See teema aga kuulub rohkem masinkoodi piiresse.

Programmeerimiskeel C kontrollib küll muutujatele väärtuste omistamisel tüübi sobivust, kuid ei keela omistada ka ebasobivat tüüpi väärtust. Võimaluse korral konverteerib translaator selle väärtuse enne muutujale omistamist vajalikku tüüpi. Te võite aga ka ise väärtuste tüüpe konverteerida, kasutades vajaliku tüübi nime ümarsulgudes. Näiteks:

int	i;		/* täisarv */
float	f1, f2;	        /* kümnendmurrud */
...
f1 = 1.3;
f2 = 2.5;		/* summa on tegelikult 3.8 */
/* enne omistamist konverteerime summa täisarvuks ==> 3*/
/* murdosa lihtsalt eemaldatakse. Ümardamiseks peate */
/* defineerima vajaliku funktsiooni */
i = (int) (f1 + f2);

Seega on programmeerimiskeeles C võimalik ka näiteks liita tähtedele arve ja neist arve lahutada. PASCAL - keeles ei ole see nii lihtsalt võimalik. Selline tüüpide segamine on ohtlik ja võib tekitada palju vigu, kuid ettevaatlikul kasutamisel võib see tunduvalt tõsta programmi töökiirust.