Document, comentariu, eseu, bacalaureat, liceu si facultate
Top documenteAdmitereTesteUtileContact
      
    


 


Ultimele referate adaugate

Adauga referat - poti sa ne ajuti cu un referat?

Politica de confidentialitate



Ultimele referate descarcare de pe site
  CREDITUL IPOTECAR PENTRU INVESTITII IMOBILIARE (economie)
  Comertul cu amanuntul (economie)
  IDENTIFICAREA CRIMINALISTICA (drept)
  Mecanismul motor, Biela, organe mobile proiect (diverse)
  O scrisoare pierduta (romana)
  O scrisoare pierduta (romana)
  Ion DRUTA (romana)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  Starea civila (geografie)
 

Ultimele referate cautate in site
   domnisoara hus
   legume
    istoria unui galban
   metanol
   recapitulare
   profitul
   caract
   comentariu liric
   radiolocatia
   praslea cel voinic si merele da aur
 
despre:
 
Totul despre C++
Colt dreapta
Vizite: ? Nota: ? Ce reprezinta? Intrebari si raspunsuri
 
1 Introducere

Limbajul de programare C++ este limbajul C extins cu clase, functii inline, operator de supraincarcare, nume de functie supraincarcat, tipurile constant, referinta, operatorii de gesti- une a memoriei libere, verificarea argumentelor functiei si o sintaxa noua de definire a functiilor. Limbajul C este descris in "The C Programming Language" de Brian W. Kernighan si Dennis M. Richie, Prentice Hall, 1978. Acest manual a fost derivat din sistemul UNIX V "The C Programming Language - Reference Manual" cu permisiunea lui AT&T Ball Laboratories. Diferentele dintre C++ si C sint rezumate in &15. Manualul descrie limbajul C++ din iunie 1985. o8x16xh

2 Conventii lexicale

Exista sase clase de lexicuri: identificatori, cuvinte cheie, constante, siruri, operatori si alti separatori. Blancuri- le, tabulatori, rindul nou si comentariile (cu un singur cuvint "spatii albe") asa cum se descrie mai jos se ignora exceptind faptul ca ele servesc la a separa lexicuri. Anumite spatii albe se cer pentru a separa printre altele identificatori, cuvinte cheie si constante adiacente.
Daca sistemul de intrare a fost descompus in lexicuri pina la un caracter dat, lexicul urmator va include cel mai lung sir de caractere care este posibil sa constituie un lexic.

2.1 Comentarii

Caracterele /* incep un comentariu care se termina cu caracterele */. Comentariile nu se vor imbrica. Caracterele // incep un comentariu care se termina in linia in care a fost inceput.

2.2 Identificatori (Nume)

Un identificator este un sir de litere si cifre de lungime arbitrara; primul caracter trebuie sa fie o litera; caracterul subliniere _ conteaza ca litera. Literele mari sint diferite de cele mici.

2.3 Cuvinte cheie

Identificatorii urmatori sint rezervati pentru a fi utilizati ca si cuvinte cheie si nu pot fi utilizati in alte scopuri: asm auto break case char class const continue default delete do double else enum extern float for friend goto if inline int long new operator overload public register return short sizeof static struct switch this typedef union unsigned virtual void
while




2.4 Constante

Exista diferite tipuri de constante, asa cum se indica mai jos. Caracteristicile hardware care afecteaza dimensiunile sint rezumate in &2.6.

2.4.1 Constante intregi

O constanta intreaga care consta dintr-un sir de cifre se considera in octal daca ea incepe cu 0 (cifra zero) si zecimal in caz contrar. Cifrele 8 si 9 nu fac parte din sistemul de numeratie octal. Un sir de cifre precedate de 0x sau 0X se considera ca fiind un intreg hexazecimal. Cifrele hexazecimale contin si literele a..f respectiv A..F care reprezinta valorile 10..15. O constanta zecimala a carei valoare depaseste intregul cu semn cel mai mare se considera de tip long; o constanta octala sau hexazecimala care depaseste intregul fara semn cel mai mare se conside- ra de tip long; altfel constantele intregi se considera de tip int.

2.4.2 Constante long explicite

O constanta intreaga zecimala, octala sau hexazecimala urmata imediat de litera l sau L este o constanta de tip long.


2.4.3 Constante caracter

O constanta caracter este un caracter inclus intre caractere apostrof ('x'). Valoarea unei constante caracter este valoarea numerica a caracterului din setul de caractere al calculatorului. Constantele caracter se considera de tip int. Anumite caractere negrafice, apostroful si backslashul pot fi reprezentate potrivit tabelei urmatoare de secvente escape: new_line NL (LF) \n horizontal tab HT \t vertical tab VT \v backspace BS \b carriage return CR \r form feed FF \f backslash \ \\ simple quote ' \' bit pattern 0ddd \ddd bit pattern 0xddd \xddd

Secventa escape \ddd consta dintr-un backslash urmat de una, doua sau trei cifre octale care specifica valoarea caracterului dorit. Un caz special al acestei constructii este \0 (care nu este urmat de o cifra), care indica caracterul NULL. Secventa escape \xddd consta din backslash urmat de una, doua sau trei cifre hexazecimale care specifica valoarea caracterului dorit. Daca caracterul care urmeaza dupa backslash nu este unul din cei specificati mai sus, atunci caracterul backslash se ignora.

2.4.4 Constante flotante

O constanta flotanta consta dintr-o parte intreaga, un punct zecimal, o parte fractionara, un e sau un E si un exponent intreg cu un semn optional. Partile intregi si fractionare constau fiecare dintr-o secventa de cifre. Partea intreaga sau partea fractionara (dar nu simultan) pot lipsi; punctul zecimal sau e (E) si exponentul (dar nu simultan) pot lipsi. O constanta flotanta are tipul double.

2.4.5 Constante enumerative

Numele declarate ca enumeratori (vezi &8.10) sint constante de tip int.

2.4.6 Constante declarate

Un obiect (&5) de orice tip poate fi specificat sa aiba o valoare constanta in domeniul numelui lui (&4.1). Pentru pointeri declaratorul &const (&8.3) se utilizeaza pentru a atinge acest fapt; pentru obiecte nepointer se utilizeaza specificatorul const (&8.2).

2.5 Siruri

Un sir este o succesiune de caractere delimitate prin ghilimele (" ... "). Un sir are tipul "tablou de caractere" si clasa de memorie static (vezi &4 mai jos) si se initializeaza cu caracterele date. Toate sirurile, chiar daca sint scrise identic sint distincte. Compilatorul plaseaza un octet null (\0) la sfirsitul fiecarui sir asa ca programele care parcurg sirul pot gasi sfirsitul lui. Intr-un sir, ghilimelele " trebuie precedate de \; in plus secventele escape asa cum s-au descris pentru constantele caracter, se pot folosi intr-un sir. In sfirsit, new_line poate apare numai imediat dupa \.

2.6 Caracteristici hardware

Tabela de mai jos rezuma anumite proprietati care variaza de la masina la masina.

| DEC | Naturale | IBM 370 | AT&T3B |
| VAX | 6800 | EBCDIC | ASCII |
| ASCII | ASCII | | |
|---------------------------------------------------------------|
| char | 8 biti | 8 biti | 8 biti | 8 biti |
| int | 32 | 16 | 32 | 32 |
| short | 16 | 16 | 16 | 16 |
| long | 32 | 32 | 32 | 32 |
| float | 32 | 32 | 32 | 32 |
| double | 64 | 64 | 64 | 64 |
| pointer | 32 | 32 | 24 | 32 |
| | +-38 | +-38 | +-76 | +-38 |
| float range | +-10 | +-10 | +-10 | +-10 |
| | +-38 | +-38 | +-76 | +-308|
| double range | +-10 | +-10 | +-10 | +-10 |
| field type | signed | unsigned | unsigned | unsigned |
| field order | right_to_ | left_to_ | left_to_ | left_to_ |
| | left | right | right | right |
| char | signed | unsigned | unsigned | unsigned |

3 Notatia sintactica

In notatia sintactica utilizata in acest manual categoriile sintactice se indica prin italice, iar cuvintele literale si caracterele din constante in forma reala. Variantele se listeaza pe linii separate. Un simbol terminal optional sau neoptional se indica prin indicele "opt" asa ca:
Aexpresie optS indica o expresie optionala inclusa intre paranteze. Sintaxa este rezumata in &14.

4 Nume si Tipuri

Un nume denota un obiect, o functie, un tip, o valoare sau o eticheta. Un nume se introduce intr-un program printr-o declaratie (&8). Un nume poate fi utilizat numai intr-o regiune a textului programului numit domeniul lui. Un obiect este o regiune de memorie care determina existenta lui. Intelesul valorilor gasite intr-un obiect se determina prin tipul numelui utilizat pentru a-l accesa.

4.1 Domenii

Exista trei feluri de domenii: local, fisier si clasa. Local: In general, un nume declarat intr-un bloc(&9.2) este local la acel bloc si poate fi folosit in el numai dupa punctul de declaratie si in blocurile incluse in el. Cu toate acestea, etichetele (&9.12) pot fi utilizate oriunde in functia in care ele sint declarate. Numele argumentelor formale pentru o functie se trateaza ca si cind ar fi fost declarate in blocul cel mai extern al acelei functii. Fisier: Un nume declarat in afara oricarui bloc (&9.2) sau clasa (&8.5) poate fi utilizat in fisierul in care a fost declarat dupa punctul in care a fost declarat. Clasa: Numele unui membru al clasei este local la clasa lui si poate fi utilizat numai intr-o functie membru al acelei clase (&8.5.2), dupa un operator aplicat la un obiect din clasa lui (&7.1) sau dupa operatorul -> aplicat la un pointer spre un obiect din clasa lui (&7.1). Membri clasei statice (&8.5.1) si functiile membru pot fi referite de asemenea acolo unde numele clasei lor este in domeniu utilizind operatorul :: (&7.1). O clasa declarata intr-o clasa (&8.5.15) nu se considera un membru si numele ei l apartine la domeniul care o include.
Un nume poate fi ascuns printr-o declaratie explicita a aceluiasi nume intr-un bloc sau clasa. Un nume intr-un bloc sau clasa poate fi ascuns numai printr-un nume declarat intr-un bloc sau clasa inclusa. Un nume nelocal ascuns poate insa sa fie utilizat cind domeniul lui se specifica folosind operatorul :: (&7.1). Un nume de clasa ascuns printr-un nume non-tip poate fi insa utilizat daca este prefixat prin class, struct sau union (&8.2). Un nume enum ascuns printr-un nume non-tip poate insa sa fie utilizat daca este prefixat de enum (&8.2).

4.2 Definitii

O declaratie (&8) este o definitie daca nu este o declaratie de functie (&10) si ea contine specificatorul extern si nu are initializator sau corpul functiei sau este declaratia unui nume de clasa (&8.8).

4.3 Linkare

Un nume din domeniul fisierului care nu este declarat expli- cit ca static este comun fiecarui fisier intr-un program multifi- sier; asa este numele unei functii. Astfel de nume se spune ca sint externe. Fiecare declaratie a unui nume extern din program se refera la acelasi obiect (&5), functie (&10), tip (&8.7), clasa (&8.5), enumerare (&8.10) sau valoare de enumerare (&8.10).
Tipurile specificate in toate declaratiile unui nume extern trebuie sa fie identice. Pot exista mai multe definitii pentru un tip, o enumerare, o functie inline (&8.1) sau o constanta care nu este agregat cu conditia ca definitiile care apar in diferite fisiere sa fie identice, iar toti initializatorii sa fie expresii constante (&12). In toate celelalte cazuri, trebuie sa fie exact o definitie pentru un nume extern din program.
O implementare poate cere ca o constanta neagregat utiliza- ta unde nu este definita, sa trebuiasca sa fie declarata extern explicit si sa aiba exact o definitie in program. Aceeasi restrictie poate fi impusa si asupra functiilor inline.

4.4 Clase de memorie

Exista doua clase de memorie: clase automatice si clase statice. Obiectele automatice sint locale. Ele apar la fiecare apel al unui bloc si se elimina la iesirea din el.
Obiectele statice exista si isi mentin valorile pe timpul executiei intregului program.
Anumite obiecte nu sint asociate cu nume si viata lor se controleaza explicit utilizind operatorii new si delete; vezi &7.2 si &9.14.

4.5 Tipuri fundamentale

Obiectele declarate ca si caractere (char) sint destul de mari pentru a memora orice membru al setului de caractere implementat si daca un caracter real din acel set se memoreaza intr-o variabila caracter, valoarea ei este echivalenta cu codul intreg al acelui caracter.
Sint disponibile trei dimensiuni de tip intreg, declarate short int, int si long int. Intregii long furnizeaza memorie nu mai putina decit cei short, dar implementarea poate face ca sau intregii short sau cei long sau ambii sa fie intregi fara alte atribute (int). Intregii int au dimensiunea naturala pe masina gazda sugerata de arhitectura ei.
Fiecare enumerare (&8.10) este un set de constante denumite. Proprietatile lui enum sint identice cu cele ale lui int. Intregii fara semn asculta de legile aritmeticii modulo 2^n unde n este numarul de biti din reprezentare.
Numerele flotante in simpla precizie (float) si in dubla precizie (double) pot fi sinonime in anumite implementari.
Deoarece obiectele de tipurile anterioare pot fi interpretate in mod util ca numere, ele vor fi referite ca tipuri aritmetice. Tipurile char, int de toate dimensiunile si enum vor fi numite tip integral. Tipurile float si double vor fi numite tip floating.
Tipul void specifica o multime vida de valori. Valoarea (inexistenta) a unui obiect void nu poate fi utilizata si nu se pot aplica conversii explicite sau implicite. Deoarece o expresie void noteaza o valoare inexistenta, o astfel de expresie poate fi utilizata numai ca o expresie instructiune (&9.1) sau ca operandul sting al unei expresii cu virgula (&7.15). O expresie poate fi convertita explicit spre tipul void (&7.2).

4.6 Tipuri derivate

Exista un numar conceptual infinit de tipuri derivate construite din tipurile fundamentale: tablouri de obiecte de un tip dat; functii care au argumente de tipuri date si returneaza obiecte de un tip dat; pointeri spre obiecte de un tip dat; referinte la obiecte de un tip dat; constante care sint valori de un tip dat; clase ce contin o secventa de obiecte de tipuri diferite, un set de functii pentru manipularea acestor obiecte si un set de restrictii asupra accesului la aceste obiecte si functii; structuri care sint clase fara restrictii la acces; reuniuni care sint structuri capabile sa contina obiecte de tipuri diferite in momente diferite.
In general aceste metode de a construi obiecte pot fi aplicate recursiv.
Un obiect de tip void* (pointer spre void) poate fi utilizat pentru a pointa spre obiecte de tip necunoscut.

5 Obiecte si Lvalori

Un obiect este o regiune de memorie; o lvaloare este o expresie care se refera la un obiect. Un exemplu evident de expresie lvaloare este numele unui obiect. Exista operatori care produc lvalori: de exemplu, daca E este o expresie de tip poin- ter, atunci *E este o expresie lvaloare care se refera la obiectul spre care pointeaza E. Numele lvaloare vine de la expresia de atribuire E1 = E2 in care operatorul sting trebuie sa fie o lvaloare. Discutia de mai jos despre operatori indica despre fiecare daca el asteapta un operand lvaloare si daca el produce o lvaloare.

6 Conversii

Un numar de operatori pot, depinzind de operanzii lor, sa provoace conversia valorii unui operand de un tip la altul. Aceasta sectiune explica rezultatul asteptat de la o astfel de conversie. Paragraful &6.6 rezuma conversiile cerute de cei mai obisnuiti operatori; ea va fi suplimentata la nevoie printr-o discutie despre fiecare operator. Paragraful &8.5.6 descrie conversiile definite de utilizator.

6.1 Caractere si Intregi

Un caracter sau un intreg scurt poate fi utilizat oriunde se poate utiliza un intreg. Conversia unui intreg scurt spre unul mai lung implica totdeauna extensie de semn; intregii sint cantitati cu semn. Daca extensia de semn apare sau nu pentru caractere este dependent de masina; vezi &2.6. Tipul explicit unsigned char forteaza ca valorile sa fie de la zero la cea mai mare valoare permisa de masina.
Pe masinile care trateaza caracterele ca fiind cu semn, caracterele ASCII sint toate pozitive. Cu toate acestea, o constanta caracter specificata cu backslash sufera o extensie de semn si poate apare negativa; de exemplu, '\377' are valoarea -1.
Cind un intreg lung se converteste spre un intreg mai scurt sau spre char, se trunchiaza la stinga; bitii in plus sint pierduti.

6.2 Flotante in simpla si dubla precizie

Aritmetica in flotanta simpla precizie poate fi utilizata pentru expresii de tip float. Conversiile intre numere flotante in simpla precizie si dubla precizie sint din punct de vedere matematic corecte in masura in care permite hardware-ul.

6.3 Flotante si Intregi

Conversiile valorilor flotante spre tipul intreg tind sa fie dependente de masina; in particular directia trunchierii numere lor negative variaza de la masina la masina. Rezultatul este imprevizibil daca valoarea nu incape in spatiul prevazut.
Conversiile valorilor intregi spre flotante se rezolva bine. Se pot pierde cifre daca destinatia nu are suficienti biti.

6.4. Pointeri si Intregi

O expresie de tip intreg poate fi adunata sau scazuta dintr-un pointer; intr-un astfel de caz primul se converteste asa cum se specifica in discutia despre operatorul de adunare. Doi pointeri spre obiecte de acelasi tip pot fi scazuti; in acest caz rezultatul se converteste spre int sau long in functie de masina; vezi &7.4.

6.5 Intregi fara semn

Ori de cite ori se combina un intreg fara semn si un intreg de tip int, ultimul se converteste spre unsigned si rezultatul este unsigned. Valoarea este cel mai mic intreg fara semn congruent cu intregul cu semn (modulo 2^dimensiunea cuvintului). In reprezentarea prin complement fata de 2, aceasta conversie este conceptuala si in realitate nu exista o schimbare in structura bitilor.
Cind un intreg fara semn se converteste spre long, valoarea rezultatului este numeric aceeasi cu cea a intregului fara semn. Astfel conversia are ca rezultat completarea cu zerouri nesemnificative la stinga.

6.6 Conversii aritmetice

Un numar mare de operatori conduc la conversii si produc rezultate de un tip similar cu tipurile descrise mai sus. Aceste conversii vor fi numite "conversii aritmetice uzuale". orice operanzi de tip char, unsigned char sau short se convertesc spre int. daca unul din operanzi este double, atunci si celalalt se converteste spre double si acesta este tipul rezultatului. altfel daca unul din operanzi este unsigned long atunci si celalalt se converteste spre unsigned long si acesta este tipul rezultatului. altfel, daca unul dintre operanzi este long, celalalt este convertit spre long si acesta este tipul rezultatului. altfel, daca unul din operanzi este unsigned, celalalt se converteste spre unsigned si acesta este tipul rezultatu lui. altfel, ambii operanzi trebuie sa fie int si acesta este tipul rezultatului.


6.7 Conversii de pointeri

Conversiile urmatoare pot fi facute ori de cite ori se atribuie, se initializeaza sau se compara pointeri. constanta 0 poate fi convertita spre un pointer si se garanteaza ca aceasta valoare va produce un pointer dis tinct de orice pointer spre orice obiect. un pointer spre orice tip poate fi convertit spre un void*. un pointer spre o clasa poate fi convertit spre un pointer spre o clasa de baza publica a acelei clase; vezi &8.5.3. un nume al unui vector poate fi convertit spre un pointer spre primul lui element. un identificator care se declara ca "functie ce returneaza ..." cind se utilizeaza altundeva decit ca nume intr-un apel de functiei, se converteste in pointer spre "functia ce returneaza ...".

6.8 Conversii de referinte

Conversia urmatoare poate fi facuta ori de cite ori se initializeaza referintele. o referinta la o clasa poate fi convertita spre o referin ta spre o clasa de baza publica a acelei clase; vezi &8.6.3.

7 Expresii

Precedenta operatorilor unei expresii este aceeasi cu ordinea subsectiunilor majore ale acestei subsectiuni, intii fiind precedenta cea mai inalta. Astfel, de exemplu, expresiile care se refera la operanzii lui + (&7.4) sint acele expresii care sint definite in &7.1-&7.4. Operatorii din fiecare subsectiune au aceeasi precedenta. Asociativitatea stinga sau dreapta este specificata in fiecare subsectiune pentru operatorii discutati in ea. Precedenta si asociativitatea tuturor operatorilor unei expresii este rezumata in gramatica din &14.
Altfel ordinea evaluarii expresiilor este nedefinita. In particular compilatorul considera ca el este liber sa calculeze subexpresiile in ordinea in care el considera ca acest lucru este cel mai eficient, chiar daca subexpresiile implica efecte secundare. Ordinea in care au loc efectele secundare nu este specificata. Expresiile care implica un operator comutativ si unul asociativ (*, +, &, |, ^) pot fi rearanjate arbitrar, chiar si in prezenta parantezelor; pentru a forta o ordine particulara a evaluarii trebuie sa se utilizeze un temporar explicit.
Tratarea depasirilor si verificarea impartirii intr-o evaluare de expresie este dependenta de masina. Majoritatea imple mentarilor existente ale lui C++ ignora depasirile de intregi, tratarea impartirii la zero si toate exceptiile flotante difera de la masina la masina si de obicei se ajusteaza printr-o functie de biblioteca.
In plus fata de intelesul standard descris in &7.2-&7.15 operatorii pot fi supraincarcati, adica li se dau sensuri cind se aplica la tipuri definite de utilizator; vezi &7.16.

7.1 Expresii primare

Expresiile primare implica . -> :: indexare si apel de functie grupindu-se de la stinga la dreapta. expression_list: expression expression_list, expression id: identifier operator_function_name typedef_name :: identifier typedef_name :: operator_function_name primary_expression: id
:: identifier constant string this
(expression) primary_expressionaexpressioni primary_expression(expression_list opt) primary_expression.id primary_expression->id

Un identificator este o expresie primara, cu conditia ca el sa aiba o declaratie potrivita (&8). Un operator_function_name este un identificator cu un inteles special; vezi &7.16 si &8.5.11.
Operatorul :: urmat de un identificator din domeniul fisierului este acelasi lucru cu identificatorul. El permite unui obiect sa fie referentiat chiar daca identificatorul lui a fost ascuns (&4.1).
Un typedef_name (&8.8) urmat de :: si de un identificator este o expresie primara. Typedef_name trebuie sa noteze o clasa (&8.5) iar identificatorul trebuie sa noteze un membru al acelei clase. Tipul lui se specifica printr-o declaratie de identificator. Type_name poate fi ascuns printr-un nume non_type; in acest caz typedef_name poate fi inca gasit si utilizat.
O constanta este o expresie primara. Tipul ei poate fi int, long, float sau double in functie de forma ei.
Un sir este o expresie primara. Tipul lui este "tablou de caractere". El este de obicei convertit imediat spre un pointer spre primul lui caracter (&6.7).
Cuvintul cheie this este o variabila locala din corpul unei functii membru (vezi &8.5); este un pointer spre obiectul pentru care functia a fost apelata.
O expresie in paranteze este o expresie primara a carui tip si valoare sint identice cu a expresiei fara paranteze. Prezenta parantezelor nu afecteaza faptul ca expresia este o lvaloare. O expresie primara urmata de o expresie in paranteze patrate este o expresie primara. Sensul intuitiv este acela al unui indice. De obicei, expresia primara are tipul "pointer spre ...", expresia indice este int, iar tipul rezultatului este "...". Expresia E1aE2i este identica (prin definitie) cu *((E1) + (E2)). Toate cheile necesare intelegerii acestei notatii sint continute in aceasta sectiune impreuna cu discutiile din &7.1, &7.2 si &7.4 despre identificatori, * si respectiv +; &8.4.2 rezuma mai jos implicatiile. Apelul unei functii este o expresie primara urmata de paranteze care contin o lista de expresii separate prin virgula, care este posibil sa fie si vida, iar expresiile formeaza argumentele reale ale functiei. Expresia primara trebuie sa fie de tipul "functie care returneaza ... " sau "pointer spre o functie care returneaza ... " iar rezultatul apelului functiei este de tipul "...".
Fiecare argument formal se initializeaza cu argumentul actual al lui (&8.6). Se fac conversii standard (&6.6-&6.8) si conversii definite de utilizator (&8.5.6). O functie poate schimba valorile argumentelor ei formale, dar aceste schimbari nu pot afecta valorile argumentelor actuale exceptind cazul in care argumentele formale sint de tip referinta (&8.4). O functie poate fi declarata ca sa accepte mai putine sau mai multe argumente decit sint specificate in declaratia de functie (&8.4). Orice argument real de tip float pentru care nu exista un argument formal se converteste inaintea apelului spre double; cel de tip char sau short se converteste spre int si ca de obicei, numele de tablouri se convertesc spre pointeri. Ordinea de evaluare a argumentelor este nedefinita prin limbaj; sa luam nota de faptul ca compilatoarele difera intre ele.
Apelurile recursive sint permise la orice functie.
O expresie primara urmata de un punct si de un identificator (sau un identificator calificat printr-un typedef_name utilizind operatorul ::) este o expresie. Prima expresie trebuie sa fie un obiect al unei clase, iar identificatorul trebuie sa numeasca un membru al acelei clase. Valoarea este membrul numit al obiectului si el este o lvaloare daca prima expresie este o lvaloare. Sa observam ca "obiectele unei clase" pot fi structuri (&8.5.12) sau reuniuni (&8.5.13).
O expresie primara urmata de o sageata (->) si de un identificator (sau un identificator calificat printr-un typedef_name utilizind operatorul ::) este o expresie. Prima expresie trebuie sa fie un pointer la un obiect al unei clase iar identificatorul trebuie sa numeasca un membru al acelei clase. Rezultatul este o lvaloare care referentiaza membrul numit al clasei spre care pointeaza expresia pointer. Astfel expresia E1->MOS este acelasi lucru cu (*E1).MOS. Clasele se discuta in &8.5.
Daca o expresie are tipul "referinta la ..." (vezi &8.4 si &8.6.3) valoarea expresiei este obiectul notat prin referinta. O referinta poate fi gindita ca un nume al unui obiect (&8.6.3).

7.2 Operatori unari

Expresiile cu operatori unari se grupeaza de la dreapta la stinga. unary_expression: unary_operator expression expression++ expression- sizeof expression sizeof(type_name)
(type_name) expression simple_type_name (expression_list) new type_name initializer_opt new (type_name) delete expression delete aexpressioni expression

unary_operator: unul dintre

* & + - ! I ++ --

Operatorul unar * inseamna indirectare: expresia trebuie sa fie un pointer, iar rezultatul este o lvaloare care se refera la un obiect spre care pointeaza expresia. Daca tipul expresiei este "pointer spre ..." tipul rezultatului este "... ".
Rezultatul operatorului unar & este un pointer spre obiectul referit de operand. Operandul trebuie sa fie o lvaloare. Daca ti- pul expresiei este "...", atunci tipul rezultatului este "pointer spre ...".
Rezultatul operatorului unar + este valoarea operandului sau valoarea rezultata in urma conversiilor aritmetice obisnuite. Operandul trebuie sa fie de tip aritmetic.
Rezultatul operatorului unar - este negativarea operandului sau.
Operandul trebuie sa fie de tip aritmetic. Se fac conversii aritmetice obisnuite. Negativarea unei cantitati fara semn se calculeaza scazind valoarea ei din 2^n unde n este numarul de biti dintr-un int.
Rezultatul operatorului de negatie logica ! este 1 daca valoarea operandului sau este 0, si este 0 daca valoarea operandului sau este diferita de zero. Tipul operandului este int. Se aplica la orice tip aritmetic sau la pointeri.
Operatorul I produce complementul fata de 1 al operandului sau. Se fac conversii aritmetice uzuale. Tipul operandului trebuie sa fie intreg.

7.2.1 Incrementare si Decrementare
Operandul prefixului ++ este incrementat. Operandul trebuie sa fie o lvaloare. Expresia ++x este echivalenta cu x += 1. Vezi discutiile despre adunare (&7.4) si operatorii de asignare (&7.14) pentru informatii despre conversii.
Operandul prefixat prin -- se decrementeaza in mod analog ca si in cazul operatorului prefix ++.
Valoarea obtinuta prin aplicarea unui operator ++ postfix este valoarea operandului. Operandul trebuie sa fie o lvaloare. Dupa ce este luat in evidenta rezultatul; obiectul este incrementat in aceeasi maniera ca si operatorul prefix ++. Tipul rezultatului este acelasi ca si tipul operandului. Valoarea obtinuta prin aplicarea unui operator -- postfix este valoarea operandului. Operandul trebuie sa fie o lvaloare. Dupa ce rezultatul este luat in evidenta, obiectul este decremen- tat in aceeasi maniera ca si pentru operatorul prefix --. Tipul rezultatului este acelasi cu al operandului.

7.2.2 Sizeof

Operatorul sizeof produce dimensiunea in octeti a operandului sau. (Un octet este nedefinit prin limbaj cu exceptia terme- nilor valorii lui sizeof. Cu toate acestea, in toate implementarile existente un octet este spatiul cerut pentru a pastra un caracter.) Cind se aplica la un tablou, rezultatul este numarul total de octeti din tablou. Dimensiunea se determina din declaratiile obiectelor dintr-o expresie. Expresia este semantic o constanta fara semn si poate fi utilizata oriunde se cere o constanta.
Operatorul sizeof se poate aplica de asemenea la un nume de tip in paranteze. In acest caz el produce dimensiunea in octeti a unui obiect de tip indicat.

7.2.3 Conversia explicita de tip

Un simple_type_name inclus optional in paranteze (&8.2) urmat de o expresie in paranteze (sau o lista de expresii daca ti- pul este o clasa cu un constructor declarat in mod corespunzator &8.5.5) face ca valoarea expresiei sa fie convertita spre tipul denumit. Pentru a exprima conversia spre un tip care nu are un nume simplu, trebuie inclus in paranteze numele tipului (&8.7). Daca numele tipului este in paranteze, expresia nu este necesar sa fie in paranteze. Aceasta constructie se numeste cast.
Un pointer poate fi convertit explicit spre orice tip de intregi care sint destul de mari pentru a le pastra. Ori de cite ori se cere un int sau long, acest lucru este dependent de masina. Functia de transformare este de asemenea dependenta de masina, dar se intentioneaza ca aceasta sa nu fie o surpriza pentru cei care cunosc structura de adresare a masinii. Detalii despre anumite masini particulare se dau in &2.6.
Un obiect de tip intreg se poate converti in mod explicit spre un pointer. Transformarea totdeauna face ca un intreg convertit dintr-un pointer sa revina inapoi la acelasi pointer, dar printre altele ea este dependenta de masina.
Un pointer spre un tip poate fi convertit explicit spre un pointer spre un alt tip. Pointerul rezultat poate provoca ex ceptii de adresare la utilizare daca pointerul care se converteste nu se refera la un obiect aliniat in memorie in mod cores- punzator. Se garanteaza ca un pointer spre un obiect de o dimensiune data poate fi convertit spre un pointer spre un obiect cu o dimensiune mai mica si din nou inapoi fara a face schimbari. Diferite masini pot diferi in numarul de biti in pointeri si in cerintele de aliniere pentru obiecte. Agregatele se aliniaza la limita cea mai stricta ceruta de oricare din componentele lor.
Un obiect poate fi convertit spre o clasa de obiecte numai daca a fost declarat un constructor potrivit sau un operator de conversie (&8.5.6). Un obiect poate fi convertit explicit spre o referinta de tip X& daca un pointer spre acel obiect poate fi convertit explicit spre un X*.

7.2.4 Memoria libera

Operatorul new creaza un obiect de tipul type_name (vezi &8.7) la care se aplica el. Durata de viata a unui obiect creat prin new nu este restrinsa la domeniul in care se creaza. Operatorul new returneaza un pointer la obiectul pe care il creaza. Cind acel obiect este un tablou se returneaza un pointer la primul sau element. De exemplu, atit new int, cit si new inta10i returneaza un int*. Se poate furniza un initializator pentru anumite obiecte de clasa (&8.6.2). Pentru a obtine memorie operatorul new (&7.2) va apela functia: void* operator new(long);
Argumentul specifica numarul de octeti cerut. Memoria va fi neinitializata. Daca operatorul new() nu poate gasi cantitatea de memorie ceruta, atunci el va returna valoarea zero.

Operatorul delete va distruge un obiect creat prin operatorul new. Rezultatul este void. Operandul lui delete trebuie sa fie un pointer returnat de new. Efectul aplicarii lui delete la un pointer care nu este obtinut prin operatorul new este nedefinit. Cu toate acestea, stergind un pointer cu valoarea zero este inofensiv. Pentru a elibera memorie operatorul delete va apela functia: void operator delete(void*);
In forma: delete aexpressioni expression cea de a doua expresie pointeaza spre un vector iar prima expresie da numarul de elemente al acelui vector. Specificarea numarului de elemente este redondant exceptind cazul cind se sterg vectori de anumite clase (vezi &8.5.8).


7.3 Operatori multiplicatori

Operatorii multiplicatori *, / si % se grupeaza de la stinga la dreapta. Se fac conversii aritmetice obisnuite. multiplicative_expression expression * expression expression / expression expression % expression

Operatorul binar * indica inmultire. Operatorul * este asociativ si expresia cu diferite inmultiri la acelasi nivel poate fi rearanjata de compilator.
Operatorul / indica impartire. Cind intregii pozitivi se impart trunchierea este zero; dar forma trunchierii este depen- denta de masina daca operandul este negativ. Pe masinile indicate in acest manual, restul are acelasi semn cu deimpartitul. Este totdeauna adevarat ca (a / b) * b + a % b este egal cu a (daca b nu este zero).
Operatorul binar % produce restul impartirii primei expresii prin cea de a doua. Se fac conversii aritmetice uzuale. Operanzii trebuie sa nu fie flotanti.

7.4 Operatori aditivi

Operatorii aditivi + si - se grupeaza de la stinga la dreapta. Se fac conversii aritmetice obisnuite. Exista unele posibilitati de tip suplimentare pentru fiecare operator. aditive_expression: expression + expression expression - expression

Rezultatul operatorului + este suma operanzilor. Un pointer spre un obiect dintr-un tablou poate fi adunat cu o valoare de tip intreg. Ultimul este in toate cazurile convertit spre un deplasament inmultindu-l prin lungimea obiectului spre care pointeaza acel pointer. Rezultatul este un pointer de acelasi tip ca si pointerul original si care pointeaza spre un alt obiect din acelasi tablou, potrivit deplasamentului fata de obiectul original. Astfel daca P este un pointer spre un obiect dintr-un ta- blou, expresia P + 1 este un pointer spre obiectul urmator din tablou.
Nu sint admise alte combinatii de tip pentru pointeri.
Operatorul + este asociativ si expresiile cu diferite adunari la acelasi nivel pot fi rearanjate de compilator. Rezultatul operatorului -; este diferenta dintre operanzi. Se fac conversii aritmetice obisnuite. In plus, o valoare de tip intreg poate fi scazuta dintr-un pointer si apoi se aplica aceleasi conversii ca si pentru adunare.
Daca doi pointeri spre obiecte de acelasi tip se scad, rezultatul sete convertit (impartind la lungimea obiectului) la un intreg ce reprezinta numarul de obiecte care separa obiectele pointate. Depinzind de masina, intregul rezultat poate fi de tip int sau long (&2.6). Aceasta conversie va da in general un rezultat neasteptat daca pointerii nu pointeaza spre obiecte din acelasi tablou, intrucit pointerii, chiar spre obiecte de acelasi tip, nu difera in mod necesar printr-un multiplu de lungimea obiectului.

7.5 Operatori de deplasare

Operatorii de deplasare << si >> se grupeaza de la stinga la dreapta. Ambii realizeaza conversii aritmetice obisnuite asupra operanzilor lor, fiecare din ei trebuind sa fie de tip intreg. Apoi operandul drept se converteste spre int. Tipul rezultatului este cel al operandului sting.
Rezultatul este nedefinit daca operandul drept este negativ sau este mai mare sau egal decit lungimea obiectelor in biti. shift_expression: expression << expression expression >> expression

Valoarea lui E1 << E2 este E1 (interpretat ca o configuratie de biti) deplasat la stinga cu E2 biti; bitii liberi se completeaza cu zero. Deplasarea la dreapta este garantata a fi o deplasare logica (se completeaza cu 0) daca E1 este fara semn; altfel ea este aritmetica (se copiaza bitul de semn).

7.6 Operatori relationali

Operatorii de relatie se grupeaza de la stinga la dreapta, dar acest fapt nu este foarte util; a < b < c nu inseamna ceea ce s-ar parea. relational_expression: expression < expression expression > expression expression <= expression expression >= expression

Operatorii < (mai mic decit), > (mai mare decit), <= (mai mic sau egal cu) si >= (mai mare sau egal cu) produc zero daca relatia specificata este falsa si unu daca este adevarata. Tipul rezultatului este int. Se fac conversii aritmetice obisnuite. Doi pointeri pot fi comparati; rezultatul depinde de locatiile relative din spatiul de adrese al obiectelor pointate. Comparatia de pointeri este portabila numai cind pointerii pointeaza spre obiecte din acelasi tablou.

7.7 Operatori de egalitate

equality_expression: expression == expression expression != expression

Operatorii == (egal) si != (diferit) sint analogi cu operatorii de relatie exceptind precedenta mai mica a lor. (Astfel a<b == c<d este 1 daca a<b si c<d au aceeasi valoare de adevar). Un pointer poate fi comparat cu zero.

7.8 Operatorul SI pe biti and_expression: expression & expression
Operatorul & este asociativ si expresiile care implica & pot fi rearanjate. Se executa conversii aritmetice obisnuite; rezultatul este functia si pe biti a operanzilor. Operatorii se aplica numai la operanzi intregi.

7.9 Operatorul SAU EXCLUSIV pe biti

exclusive_or_expression: expression ^ expression
Operatorul ^ este asociativ si expresiile care implica ^ pot fi rearanjate. Se fac conversii aritmetice obisnuite; rezultatul este functia sau exclusiv pe biti al operanzilor. Operatorii se aplica numai la operanzi intregi.

7.10 Operatorul SAU INCLUSIV pe biti

inclusive_or_expression: expression | expression
Operatorul | este asociativ si expresiile care implica | pot fi rearanjate. Se fac conversii aritmetice obisnuite; rezultatul este functia sau inclusiv pe biti a operanzilor. Operatorii se aplica numai la operanzi intregi.

7.11 Operatorul logic SI

logical_and_expression: expression && expression
Operatorul && se grupeaza de la stinga la dreapta. El returneaza 1 daca ambii operanzi ai lui sint diferiti de zero, si zero in celelalte cazuri. Spre deosebire de &, && garanteaza evaluarea de la stinga la dreapta; mai mult decit atit, cel de al doilea operand nu se evalueaza daca primul operand este zero. Operanzii nu este necesar sa aiba acelasi tip, dar fiecare trebuie sa aiba unul din tipurile fundamentale sau sa fie un poin- ter. Rezultatul este totdeauna int.

7.12 Operatorul logic SAU

logical_or_expression: expression || expression
Operatorul || se grupeaza de la stinga la dreapta. El retur- neaza 1 daca oricare din operanzi este diferit de zero, si zero altfel. Spre deosebire de |, || garanteaza o evaluare de la stinga la dreapta; mai mult decit atit, operandul al doilea nu este evaluat daca valoarea primului operand este diferita de 0.
Nu este necesar ca operanzii sa aiba acelasi tip, dar fiecare trebuie sa aiba unul din tipurile fundamentale sau sa fie un pointer. Rezultatul este intotdeauna int.

7.13 Operator conditional

conditional_expression: expression ? expression : expression
Expresiile conditionale se grupeaza de la dreapta la stinga. Prima expresie se evalueaza si daca nu este zero, rezultatul este valoarea celei de a doua expresii, altfel este a celei de a treia expresii. Daca este posibil, se fac conversii aritmetice pentru a aduce expresiile a doua si a treia la un tip comun. Daca este posibil se fac conversii de pointeri pentru a aduce expresiile a doua si a treia la un tip comun. Rezultatul are tipul comun: numai una din expresiile doi sau trei se evalueaza.

7.14 Operatori de asignare

Exista mai multi operatori de asignare si toti se grupeaza de la dreapta la stinga. Toti cer o lvaloare ca operand sting si tipul unei expresii de asignare este acela al operandului sting; aceasta lvaloare trebuie sa nu se refere la o constanta (nume de tablou, nume de functie sau const). Valoarea este valoarea memorata in operandul sting dupa ce asignarea a avut loc. assigment_expresion; expression assigment_operator expression assigment_operator: unul dintre

= += -= *= /= %= >>= <<= &= ^= |=

In atribuire simpla cu =, valoarea expresiei o inlocuieste pe cea a obiectului referit prin operandul din partea stinga. Daca ambii operanzi au tipul aritmetic, operandul drept se converteste spre tipul operandului sting preparat pentru asignare. Daca argumentul sting are tipul pointer operandul drept trebuie sa fie de acelasi tip sau de un tip care poate fi convertit spre el (vezi &6.7). Ambii operanzi pot fi obiecte de aceeasi clasa. Obiectele de anumite clase nu pot fi atribuite (vezi &8.5.3).
Asignarea la un obiect de tip "referinta la ..." atribuie la obiectul notat prin referinta.
Comportamentul unei expresii de forma E1 op= E2 poate fi dedus luind echivalentul ei de forma E1 = E1 op (E2); totusi E1 se evalueaza numai o data. In += si -=, operatorul sting poate fi un pointer, caz in care operandul drept (de tip intreg) se converteste asa cum s-a explicat in &7.4; toti operanzii drepti si toti operanzii stingi non_pointer trebuie sa aiba tipul aritmetic.

7.15 Operatorul virgula comma_expression: expression, expression
O pereche de expresii separate printr-o virgula se evalueaza de la stinga la dreapta si valoarea expresiei din stinga este eliminata. Tipul si valoarea rezultatului este tipul si valoarea operandului din dreapta. Acest operator se grupeaza de la stinga la dreapta. In contextele in care virgulei i se da un inteles special, de exemplu in listele parametrilor reali ale functiilor (&7.1) si in listele de initializatori (&8.6), operatorul virgula asa cum a fost descris in aceasta sectiune poate sa apara numai in paranteze; de exemplu: f(a, (t=3, t+2), c) are trei argumente, cel de al doilea are valoarea 5.

7.16 Operatori de supraincarcare

Majoritatea operatorilor pot fi supraincarcati, adica declarati sa accepte obiectele unei clase ca operanzi (vezi &8.5.11). Nu este posibil sa se schimbe precedenta operatorilor si nici sa se schimbe sensul operatorilor aplicati la obiecte non_clasa. In telesul predefinit al operatorilor = si & (unar) aplicati la obiectele unei clase se poate schimba.
Identitatile dintre operatori aplicate la tipurile de baza (de exemplu a++ <=> a += 1) nu este necesar sa se indeplineasca pentru operatorii aplicati la tipurile clasa. Unii operatori, de exemplu cel de asignare, cere ca un operand sa fie o lvaloare cind se aplica la tipuri de baza; aceasta nu se cere cind operatorii sint declarati pentru tipuri clasa.

7.16.1 Operatori unari

Un operator unar, daca este prefix sau postfix, poate fi definit printr-o functie membru (vezi &8.5.4) fara apartenente sau o functie prieten (vezi &8.5.10) care are un argument dar nu ambele. Astfel, pentru operatorul unar @, atit x@, cit si @x pot fi interpretati fie ca x.operator@(), fie ca operator@(x). Cind operatorii ++ si -- sint supraincarcati, nu este posibil sa se faca distinctie intre aplicatia prefix si cea postfix.

7.16.2 Operatori binari

Un operator binar poate fi definit sau printr-o functie membru care are un argument sau printr-o functie prieten care are doi parametri, dar nu ambele. Astfel, pentru un operator binar @, x@y poate fi interpretat sau x.operator@(y) sau operator@(x, y).

7.16.3 Operatori speciali

Apelul de functie primary_expression (expression_list_opt) si indexarea primary_expressionaexpressioni se considera operatori binari. Numele functiilor care se definesc sint operator() si operatorai. Astfel, un apel x(arg) este interpretat ca x.operator()(arg) pentru un obiect de clasa x. O expresie de forma xayi se interpreteaza ca x.operatorai(y).

8 Declaratii

Declaratiile se utilizeaza pentru a specifica interpretarea data fiecarui identificator; ele nu neaparat rezerva memorie asociata cu identificatorul. Declaratiile au forma: declaration: decl_specifiers_opt declarator_list_opt; name_declaration asm_declaration
Declaratorii din lista declaratiilor contin identificatorii de declarat. Numai in definitiile functiilor externe (&10) sau declaratiile de functii externe se pot omite decl_specifier. Numai cind, declarind o clasa (&8.5) sau o enumerare (&8.10), adica, atunci cind decl_specifier este un specificator de clasa (class_specifier), sau de enumerare (enum_specifier) se poate ca declarator_list sa fie vida. Name_declarations se descriu in &8.8; declaratiile asm se descriu in &8.11. decl_specifier: sc_specifier type_specifier fct_specifier friend typedef decl_specifiers: decl_specifier decl_specifiers_opt
Lista trebuie sa fie autoconsistenta in modul descris mai jos.

8.1 Specificatori de clasa de memorie

Specificatorii de clasa de memorie sint: sc_specifier: auto static extern register

Declaratiile care utilizeaza specificatorii auto, static si register servesc de asemenea ca definitii prin faptul ca ele implica rezervarea unei cantitati de memorie de o marime potrivita. Daca o declaratie extern nu este o definitie (&4.2) trebuie sa existe undeva o definitie pentru identificatorii dati. O declaratie register este cel mai bine sa fie gindita ca o declaratie auto impreuna cu sugestia ca, compilatorul stie faptul ca variabilele respective vor fi utilizate din greu. Aceasta informatie poate fi ignorata.
Operatorul de adresa & nu poate fi aplicat la ele. Specificatorii auto sau register pot fi utilizati numai pentru nume de obiecte declarate intr-un bloc si pentru argumente formale. Se poate sa nu existe functii statice intr-un bloc si nici argumente statice formale. Cel putin un sc_specifier poate fi dat intr-o declaratie. Daca sc_specifier este absent dintr-o declaratie, clasa de memorie se considera automatic intr-o functie si static in afara.
Exceptie: functiile nu sint niciodata automatice. Specificatorii static si extern pot fi folositi numai pentru nume de obiecte sau functii.
Anumiti specificatori pot fi folositi numai in declaratii de functii: fct_specifiers: overload inline virtual

Specificatorul overload permite ca un nume sa fie utilizat pentru a nota diferite functii: vezi &8.9. Specificatorul inline este numai o informatie pentru compi- lator; el nu afecteaza intelesul programului si poate fi ignorat. Se indica faptul ca substitutia inline a corpului functiei este de preferat implementarii obisnuite al apelului de functie. O functie (vezi &8.5.2 si &8.5.10) definita intr-o declaratie a unei clase este implicit o functie inline. Specificatorul virtual poate fi utilizat numai in decla- ratiile membrilor unei clase; vezi &8.5.4.

Specificatorul friend poate fi folosit sa se suprapuna peste numele care ascund regulile pentru membri unei clase si poate fi utilizat numai intr-o declaratie de clasa; vezi &8.5.10.
Specificatorul typedef se foloseste pentru a introduce un nume pentru un tip; vezi &8.8.

8.2 Specificatori de tip

Specificatorii de tip sint: type_specifier: simple_type_name class_specifier enum_specifier elaborated_type_specifier const

Cuvintul const poate fi adaugat la orice specificator de tip legal. Altfel, intr-o declaratie se poate da cel mult un specifi- cator de tip. Un obiect de tip const nu este o lvaloare. Daca specificatorul de tip lipseste dintr-o declaratie, el se ia int. simple_type_name: typedef_name char short int long unsigned float double void
Cuvintele long, short si unsigned pot fi gindite ca adjective. Ele pot fi aplicate la int; unsigned de asemenea se poate aplica la char, short si long.
Specificatorii de clasa si enumerare se discuta in &8.5 si respectiv &8.10. elaborate_type_specifier: key type_def_name key identifier key: class struct union enum

Un specificator de tip elaborat poate fi utilizat pentru a face referire la numele unei clase sau la numele unei enumerari unde numele poate fi ascuns printr-un nume local. De exemplu: class x A /*...*/ S; void f(int)
A class x a;
// ...
S

Daca numele de clasa sau de enumerare nu a fost in prealabil declarat, specificatorul de tip elaborat actioneaza ca o decla- ratie de nume; vezi &8.8.

8.3 Declaratori

declarator_list: init_declarator init_declarator, declarator_list init_declarator: declarator initializer_opt
Initializatorii se discuta in &8.6. Specificatorii din declaratie indica tipul si clasa de memorie al obiectelor la care se refera declaratorii. Declaratorii au sintaxa: declarator: dname
(declarator)
*const_opt declarator
&const_opt declarator declarator(argument_declaration_list) declaratoraconstant_expression_opti dname: simple_dname typedef_name :: simple_dname simple_dname: identifier typedef_name
Itypedef_name operator_function_name conversion_function_name
Gruparea este aceeasi ca in expresii.

8.4 Intelesul (sensul) declaratorilor

Fiecare declarator se considera a fi o asertiune care, cind apare intr-o expresie o constructie asemanatoare cu declaratorul, produce un obiect de tipul si clasa de memorie indicata. Fiecare declarator contine exact un dname; el specifica identificatorul care este declarat. Exceptind declaratiile unor functii speciale (vezi &8.5.2), un dname va fi un identificator simplu. Daca apare ca un declarator un identificator "neimpodobit", atunci el are tipul indicat de specificatorul care se afla in capul declaratiei. Un declarator in paranteze este identic cu un declarator "neimpodobit", dar legaturile declaratorilor complecsi pot fi alterate prin paranteze; vezi exemplele de mai jos.
Sa ne imaginam o declaratie:
T D1 unde T este un specificator de tip (int, etc.) si D1 este un declarator. Sa presupunem ca aceasta declaratie face ca identifi- catorul sa aiba tipul " ... T", unde "..." este vid daca D1 este chiar un identificator (cum ar fi tipul lui x in "int x" exact int).
Daca D1 are forma:
*D tipul identificatorului pe care il contine este "... pointer la T". Daca D1 are forma:
*const D tipul identificatorului pe care il contine este "... pointer constant la T" adica, acelasi tip ca si *D, dar identificatorul continut nu este o lvaloare. Daca D1 are forma:
&D sau
&const D tipul identificatorului pe care il contine este "... referinta la T". Intrucit o referinta nu poate fi prin definitie o lvaloare, utilizarea lui lvalue este redondanta. Nu este posibil sa avem o referinta spre void (void&). Daca D1 are forma:
D(argument_declaration_list) atunci identificatorul pe care il contine are tipul "... functie care are argumente de tip argument_declaration_list si returneaza T". argument_declaration_list: arg_declaration_list_opt ... _opt argument_declaration_list: arg_declaration_list, argument_declaration argument_declaration argument_declaration: decl_specifiers declarator decl_specifiers declarator = expression decl_specifiers abstract_declarator decl_specifiers abstract_declarator = expression
Daca argument_declaration_list se termina cu trei puncte, atunci numarul argumentelor se stie numai ca este egal sau mai mare decit numarul de argumente specificat; daca este vid, fun- ctia nu are argumente.Toate declaratiile pentru o functie trebuie sa corespunda exact atit in privinta tipului valorii returnate, cit si in numarul si tipul argumentelor. Argumentul argument_declaration_list se utilizeaza pentru a verifica si converti argumentele actuale in apeluri si pentru a verifica asignarile pointerilor spre functii. Daca este specificata o expresie intr-o declaratie de argument, atunci aceasta expresie se utilizeaza ca argument implicit. Argumentele implicite vor fi utilizate in apeluri acolo unde ultimele argumente sint omise. Un argument implicit nu poate fi redefinit printr-o declaratie ulterioara. Cu toate acestea, o declaratie poate adauga argumente implicite care nu s-au dat in declaratiile precedente.
Un identificator poate fi furnizat optional ca un argument nume; daca este prezent intr-o declaratie de functie, el nu poate fi utilizat intrucit el iese imediat afara din domeniul sau; daca este prezent intr-o definitie de functie (&10) el numeste un argument formal. Daca D1 are forma:
Daconstant_expressioni sau
Dai atunci identificatorul pe care il contine are tipul "... tablou de T". In primul caz expresia constanta este o expresie a carei valoare se determina la compilare si a carei tip este int (expresiile constante se definesc in &12). Cind diferite specificari de tablouri sint adiacente, se creaza un tablou multidimensional; expresiile constante care specifica limitele tablourilor se pot omite numai pentru primul membru al secventei. Aceasta omisiune este utila cind tabloul este extern si definitia reala, care aloca memorie, se da in alta parte. Prima expresie constanta poate fi omisa de asemenea cind declaratorul este urmat de initializare. In acest caz dimensiunea se calculeaza din numarul elementelor initiale furnizate.
Un tablou poate fi construit din unul din tipurile de baza, dintr-un pointer, dintr-o structura sau reuniune sau dintr-un alt tablou (pentru a genera un tablou multi_dimensional).
Nu toate posibilitatile admise prin sintaxa de mai sus sint permise. Restrictiile sint: functiile nu pot returna tablouri sau functii, desi ele pot returna pointeri spre astfel de lucruri; nu exista tablouri de functii, desi pot fi tablouri de pointeri spre functii.

8.4.1 Exemple

Declaratia: int i, *pi, f(), *fpi(), (*pif)(); declara un intreg i, un pointer pi spre un intreg, o functie f care returneaza un intreg, o functie fpi care returneaza un pointer spre un intreg si un pointer pif spre o functie care returneaza un intreg. Este util mai ales sa se compare ultimii doi. Sensul lui *fpi() este *(fpi()) si aceeasi constructie intr-o expresie cere apelul functiei fpi si apoi utilizind indirectarea prin pointer rezulta producerea unui intreg. La declaratorul (*pif)(), parantezele sint necesare pentru a indica faptul ca indirectarea printr-un pointer la o functie produce o functie, care apoi este apelata. Functiile f si fpi se declara fara argumente, iar pif pointeaza spre o functie care nu are argumente.
Declaratiile: const a=10, *pc=&a, *const cpc=pc; int b, *const cp=&b; declara: a - o constanta intreaga; pc - un pointer spre o constanta intreaga; cpc - un pointer constant spre o constanta intreaga; b - un intreg; cp - pointer constant spre un intreg. Valoarea lui pc poate fi schimbata si la fel si obiectul spre care pointeaza cp. Exemple de operatii ilegale sint: a=1; a++;
*pc=2; cp=&a; cpc++;

Exemple de operatii legale: b=a;
*cp=a; pc++; pc=cpc;

Declaratia: fseek(FILE*, long, int); declara o functie care poate fi apelata cu zero, unu sau doi parametri de tip int. Ea poate fi apelata in oricare din modurile: point(1, 2); point(1); point();

Declaratia: printf(char* ...); declara o functie care poate fi apelata cu un numar variabil de argumente si tipuri. De exemplu: printf("hello world"); printf("a=%d b=%d", a, b);

Cu toate acestea, trebuie ca totdeauna char* sa fie primul sau parametru. Declaratia: float faa17i, *afpa17i; declara un tablou de numere flotante si un tablou de pointeri spre numere flotante.
In final: static int x3da3ia5ia7i; declara un tablou de intregi tridimensional de ordinul 3x5x7. x3d este un tablou de 3 elemente; fiecare element este un tablou de 5 elemente; fiecare din acestea fiind la rindul lui un tablou de sapte intregi. Oricare din expresiile x3d, x3daii, x3daiiaji, x3daiiajiaki pot apare intr-o expresie.

8.4.2 Tablouri, Pointeri si Indici

Ori de cite ori intr-o expresie apare un identificator de tip tablou, el este convertit intr-un pointer spre primul element al tabloului. Din cauza acestei conversii, tablourile nu sint lvalori. Exceptind cazul in care operatorul de indexare ai a fost declarat pentru o clasa (&7.16.3), el se interpreteaza in asa fel incit E1aE2i este identic cu *((E1)+(E2)). Din cauza regulilor de conversie care se aplica la + daca E1 este un tablou si E2 un intreg, E1aE2i se refera la al E2-lea membru al lui E1. De aceea, in ciuda aparentei asimetrice, indexarea este o operatie comutativa. O regula consistenta se aplica in cazul tablourilor multidi- mensionale. Daca E este un tablou ndimensional de ordinul ixjx...xk, atunci E care apare intr-o expresie este convertit spre un pointer spre un tablou (n-1)dimensional de ordinul jx...xk. Daca operatorul * se aplica explicit sau implicit ca rezultat al indexarii, rezultatul este tabloul (n-1)dimensional, care este convertit imediat intr-un pointer.
De exemplu, consideram: int xa3ia5i;
Aici x este un tablou de 3x5 intregi. Cind x apare intr-o ex- presie, el se converteste spre un pointer spre (primul din cele trei) elementul care este un tablou de ordinul 5. In expresia xaii, care este echivalenta cu *(x+i), x este convertit intii spre un pointer asa cum s-a descris mai sus; apoi x+i este convertit spre tipul lui x, care implica multiplicarea lui i prin lungimea obiectului spre care pointeaza pointerul, si anume obiecte de 5 intregi. Rezultatele se aduna si se aplica indirectarea pentru a produce un tablou de cinci intregi care la rindul lui este convertit spre un pointer spre primul dintre intregi. Daca exista un alt indice se aplica din nou aceeasi regula; de data aceasta rezulta un intreg. Din toate acestea rezulta ca tablourile din C++ sint pastrate pe linie (ultimul indice variaza mai repede) si ca primul indice din declaratie ajuta sa se determine cantitatea de memorie consumata de un tablou dar el nu joaca alt rol in calculele de indici.

8.5 Declaratii de clasa

O clasa este un tip. Numele ei devine un typedef_name (vezi &8.8) care poate fi utilizat chiar in specificarea clasei. Obiectele unei clase constau dintr-o secventa de membri. class_specifier: class_headAmember_list_optS class_headAmember_list_opt public: member_list_optS class_head: aqqr identifier_opt aqqr identifier: public_opt typedef_name aqqr: class struct union

Obiectele de clasa pot fi asignate, pasate ca argumente la functii si returnate de functii (exceptind obiectele unor clase derivate; vezi &8.5.3).
Alti operatori plauzibili, cum ar fi egalitatea, pot fi definiti de utilizator; vezi &8.5.11.
O structura este o clasa cu toti membri publici; vezi &8.5.9. O reuniune este o structura care contine numai un membru la un moment dat; vezi &8.5.13. O lista de membri (member_list) poate declara ca membri date, functii, clase, enumerari, cimpuri (&8.5.14) si prieteni (&8.5.10). O lista de membri poate de asemenea contine declaratii pentru a specifica vizibilitatea numelor membrilor; vezi &8.5.9. member_list: member_declaration member_list_opt member_declaration: decl_specifiers_opt member_declarator;; function_definition; _opt member_declarator: declarator identifier_opt: constant_expresion
Membri care sint obiecte de clasa trebuie sa fie obiecte ale claselor declarate in prealabil. In particular, o clasa cl poate sa nu contina un obiect de clasa cl, dar ea poate contine un pointer spre un obiect de clasa cl.
Un exemplu simplu de declaratie a unei structuri este: struct tnodA char tworda20i; int count; tnode* left; tnode* right;
S; care contine un tablou de 20 de caractere, un intreg si doi pointeri spre structuri similare. Odata ce aceasta declaratie a fost data, declaratia: tnode s, *sp; declara pe s ca fiind un tnode si sp un pointer spre un tnode. Cu aceste declaratii: sp->count se refera la cimpul count al structurii spre care pointeaza sp; s.left se refera la pointerul spre subarborele sting al lui s; iar s.right->tworda0i se refera la primul caracter al membrului tnod al subarborelui drept al lui s.

8.5.1 Membri statici

Un membru care este data a unei clase poate fi static; functiile care sint membri nu pot fi. Membri pot sa nu fie auto, register sau extern. Exista numai o singura copie a unui membru static comuna pentru toate obiectele unei clase dintr-un program. Un membru static mem al unei clase cl poate fi referit prin cl::mem, adica fara a se face referire la un obiect. El exista chiar daca nu s-a creat nici un obiect al clasei cl. Nu se poate specifica nici un initializator pentru un membru static si nu poate fi o clasa cu un constructor.


8.5.2 Functii membru

O functie declarata ca membru (fara specificatorul friend (&8.5.10)) se numeste functie membru si se apeleaza utilizind sintaxa membrului unei clase (&7.1). De exemplu: struct tnodA char tworda20i; int count; tnode* left; tnode* right; void set(char*, tnode* l, tnode* r);
S; tnode n1, n2; n1.set("asdf", &n2, 0); n2.set("ghjk",0, 0);

Definitia unei functii membru se considera ca este in dome- niul clasei sale. Aceasta inseamna ca poate utiliza direct numele clasei sale. Daca definitia unei functii membru este lexic in afara declaratiei de clasa, numele functiei membru trebuie sa fie calificat prin numele clasei folosind operatorul ::. Definitiile functiilor se discuta in &10. De exemplu: void tnode::set(char* w, tnode* l, tnode* r)
A count = strlen(w); if(sizeof(tword) <= count) error("tnode string too long"); strcpy(tword, w); left = l; right = r;
S

Notatia tnode::set() specifica faptul ca set(


Colt dreapta
Creeaza cont
Comentarii:

Nu ai gasit ce cautai? Crezi ca ceva ne lipseste? Lasa-ti comentariul si incercam sa te ajutam.
Esti satisfacut de calitarea acestui document, eseu, cometariu? Apreciem aprecierile voastre.

Nume (obligatoriu):

Email (obligatoriu, nu va fi publicat):

Site URL (optional):


Comentariile tale: (NO HTML)


Noteaza documentul:
In prezent fisierul este notat cu: ? (media unui numar de ? de note primite).

2345678910

 
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite
Colt dreapta