ketvirtadienis, vasario 01, 2007

C/C++ tipų deklaracijos

Neperseniausiai perskaičiau C istorijos straipsnį. Buvo labai įdomu sužinoti, kodėl priimti vieni ar kiti sintaksės, arba pačios kalbos sprendimai. Vienas iš tokių -- tipų deklaravimas C/C++ kalbose.

Vardai (kintamieji, funkcijos) definuojami tokia pat išraiška, kaip kad tie patys vardai yra resolvinami į reikšmes, be abejo atsižvelgiant į operatorių prioritetus. Pamenu anksčiau buvo sušmėžavus tokia mintis, bet kažkaip daugiau apie tai nemasčiau, tad realiai šitą faktą suvokiau tik perskaitęs minėtą straipsnį. Taigi pavyzdžiui turint pointerį į int'ą pi, reikšmės, į kurią šis rodo, paėmimas, atrodo taip: *pi. Tai yra operatoriaus* įvykdymas po jo einančiai išraiškai. O tokio pointerio definicija atrodo šitaip int* pi. Tai paaiškinama taip - šis užrašas parodo, kad int'ą mes gausime, jei pritaikysime operatorių * pi reikšmei. Štai keletas pavyzdžių:

void (*pointer_to_fun)( int );

Pasako, kad pritaikę operatorių * vardui pointer_to_fun, mes gausime "funkciją" void (int), t.y. kažką, kam reikia taikyti operatorių () ir po to gauti void. Turėtų b9ti aišku, kodėl kodas:

void* not_so_pointer_to_fun( int );

pointerio nebeaprašo. Operatorius () turi prioritetą prieš operatorių * ir "funkcijos kvietimas" turės būti prieš pointerio resolvinimą. Taigi išraiška rodo, kad "iškvietus" vardą not_so_pointer_to_fun (kuris reikalauja argumento int), ir tik po to pritaikius operatorių *, mes gausime void. Toliau:

int arr[];

pritaikę operatorių [] vardui arr gausim int'ą.

int* (*arr1)[];

pritaikę op* vardui arr1, gausime masyvą, šiam pritaikę op[] gausime pointerį į int ir finale, po dar vieno operatoriaus*, gausime int. Taigi, tipas arr1 aprašo pointerį į masyvą iš pointerių į int'us.

Beje, atrodo, C++ reference deklaracija (&) į šią sistemą kažkaip netelpa.

Kaip rašė pats D. Ritchie - egzistuoja daug nusiskundimų, kad tipų aprašymas C kalboje yra labai sudėtingas, ypač kai tai liečia funkcijas ir/arba masyvus. Į ką jis atsako - taip, jis yra sudėtingas, bet tik tam ir dėl to, kad sudėtingos yra pačios išraiškos. Pilnai sutinku.

Jei dar neatsibodo - o kas yra čia?

void* (*(*a)[])(int*&);