Documente noi - cercetari, esee, comentariu, compunere, document
Documente categorii

Manual de referinta C

Manual de referinta C

1. Introducere

AcestmanualdescrielimbajulCimplementat pe PDP-11, Honeywele6000,IBM System370siInterdata832. In blocurileundeexista diferente (intre implemntari)else

referalaPDP-11, dar se incearca punctareadetaliilor dependente deimplementare. Cu micidiferente,aceste dependente sint legate direct de proprietatile hardware (ale masinilor); diverselel compilatoare sint in general compatibile.

2. Conventii lexicale

Exista sase clase de simboluri: identificatori, cuvinte-cheie, constante, (in mod colectiv numite 'spatii albe')asa cum vor fi descrise in continuare. sint ignorate cu exceptia cazurilor cind servesc la repararea simbolurilor. Unele spatii albe sint necesare pentrua separa identificatori adiacenti,cuvint-cheiesi constante.




Dacasirulde intrare (pentru compilator) a fost analizat (si transformat) in simboluri pina la un caracter dat, urmatorul simbol va include cel mai lung sir de caractere care poate constitui un simbol.


2. 1. Comentarii

Caracterele/*incep un comentariu,care se terminacu caracterele*/. Comentariile nu pot fi imbricate.


2. 2 Identificatori (nume)

Unidentificator este o secventa de litere si cifre; primul caracter trebuie sa fie litera.Sublinierea (underscor) este considerata litera literele mari si mici sintdiferite. Doar primele 8 caractere sint semnificative, desi pot fi folosite mai multe. Identificatorii externi care sint utilizati de o serie de asamblare sau incarcatoare, sint mai restrictivi:


PDP-II

7 caractere

2cazuri casete (cases)

Homywele 6000

6caractere

1case

IBM 360/370

7caractere

1case

Interdata 8/32

8caractere

2 cases


2. 3. Cuvinte cheie


Urmatoriiidenntificatori sint rezervati pentru a fi folositi ca si cuvinte cheie, si nu pot fi folositi altfel:


int

extern

else

char

register

for

float

typedef

do

double

static

while

struct

goto

switch

union

return

case

long

sizeof

default

short

break

entry

unsigned

continue

auto

if


Cuvintulcheie'entry'nueste implementat de niciun compilator, dar este rezervat pentru o utilizare ulterioara. Unele implementari rezerva si cuvintele 'fortran' si 'asm'


2. 4. Constante

Exista o serie decontantedecriseincontinuare. Caracteristicilehardwarecare afecteaza dimensiunilesint rezumate in $2. 6.


2. 4. 1. Constante intregi

O constanta intreaga constind dintr-o serie de cifre va fi considerata in octal daca incepe cu 0 (cifra zero), astfel va fi considerata in zecimal. O secvanta de cifre precedata deox sauOX(cifra zero) este considearata intreg hexazecimal. Daca valoarea unei constante zecimale depaseste posibilitatile hardwarede inmagazinare a intregilor ea va fi considerata de tip 'long'. Acelsi lucru se intimpla si pentru constantele octale sau hexazecimale.


2. 4. 2. Constante lungi explicite

O constanta intreaga de tip octal, zecimal sau hexazecimal urmata de caracterul 'l'sau'L' este considerata consatnta lunga. Dupa cum va fi discutat la unele masini intregii si valorile 'long' pot

fi considerate identice.


2. 4. 3. Constante tip caracter

O constanta tip carcter este un caracter intre ghilimele simple cum ar fi de exemplu '*'.Valoareauneiconstantetip caracter este valorea numerica a caracterului corepunzator setuluidecaractere al masinii. Unele caractere negrafice, cumsint ghilimeaua si backspace pot fi reprezentate dupa cum urmeaza, conform unei tabele de secvente 'escape'.


newline

NL(LP)

n

horisontaltab

HT

t

backspace

BS

b

carriagereturn

CR

r

formfeed

FF

f

backslash



ghilimea



modelbinar

ddd

ddd 'bit pattern'


Secventa ddd consta din caracterul backslash uramt de 1, 1 sau 3 cifre octale care vor specifica valorea unui caracter dorit. Un caz special de constructie este 0 (neurmat de nici o cifra) care indica un caracter NULL. Daca caracterul care urmeaza dupa nu este de tipul specificat, se ignora .


2. 4. 4. Constante in virgula mobila

Oconstanta in virgula mobila consta dintr-o parte intreaga, punct zecimal parte fractionara un 'e' sau 'E' si optional s un intreg cu semn pe post de exponent. Intregul si partea fractionara pot fi o secvente de cifre. Atit intregul cit si partea fractionara (dar nu simultan ) pot lipsi; si punctul zecimal sau 'e' si exponentul (nusimultan)pot lipsi. Constantele sint in dubla precizie reprezentate.


2. 5. Siruri

Unsir este o secventa de caractere intre ghilimele duble, de exemplu '' Un sir este de tipul 'tabloul de caractere ' si in clase de memorare 'static' (vezi &4) si se initializeaza cu caracterele date. Toate sirurile, chiar daca sint scrise identic, sint distincte. Compi latorul plaseaza caracterul 0 (byte nul) la sfirsitul fiecarui sir astfel ca programele care pot detecta sfirsitul sirului. Intr-un sir, car acterul ' trebuie precedat de ; in plus, secventele deschise pentru constante tip caracter pot

fi folosite. In sfirsit , un si un NL care urmeaza imediat sint ignorate.


2. 6. Caracteristici hardware

Tabelul care urmeaza rezuma unele proprietati de hardware care variazadelamasina la masina. Acesteaafecteaza portabilitatea programeleor; in practica aceasta este o problema care trebuie privita aprioric.


DEC PDP11 Honeywell 6000 IBM/370 Interdata 8/32

ASCII ASCII EBCDIC ASCII


char 8 biti 9 biti 8 biti 8 biti

int 16 36 32 32

short 16 36 16 16

long 32 36 32 32

float 32 36 32 32

double                            64 72 64 64

gama reprez. I10-38    I10-38 I10-76 I10-76

+ + + +



Pentru aceste patru tipuri de masina, numerele in VF au exponentul de 8 biti.


3. Notatii sintactice

In manual notatiile sintactice sint scrise cu tipul italic de caracter cuvintele literale sint caracteretipul drept. Categoriile alternative sint listate peliniiseparate.Un simbol optional terminal sau nonterminal este indicatprin subscrierea 'opt',astfel: indica o expresie optionala intre acolade. Sintaxa este rezumata in $18.

4. Ce este un nume ?

C-ulisi bazeaza interpretarea unui identificator dedoua atribute ale identificatorului: 'clasa de memorare ' si 'tipul'. Clasa de memorare determina locatiasidurata de viata a unei celule de memorare asociate unui identificator;tipul determinasemnificatia valorii depuse in celula de memorare a identificatorululilL.


Existapatruclasedememoraredeclarabile:automatic, staticexterna si tip registru. Variabilele automatice sint locale fiecarei apelari a unui bloc (vezi $9.2) si sint declasate la iesirea din blocul respectiv. Variabilele statice sint locale unui bloc, dar retin valoarea pina la revenirea in blocul respecitv chiar daca controlul a parasit blocul; variabilele exxterne exista si pastreaza valoarealorin decursulexecutieiintregului program si pot sa fie folosite pentru comunicare intre functii chiar funcctii compilate separat. Variabilele de tipregistru sintnumerotate(daca este posibil) in registrii rapizi ai masinii,casi variabilele automate sint locale blocului si dispar la iesirea din bloc.


C suporta citeva tipuri fundamentale de obiecte:


Obiectele declarate ca si caractere (char) sint sufiecient de mari pentru a sufoca orice membru a setuluidecaractere ale implementarii, si daca un caracter pur din acest set de caractere este sufocat intr-o variabila de tip caracter, valoarea sa este echivalenta cu codul intreg pentru acel caracter (cu valoarea intregului care reprezinta caracterul in reprezentarea interna (NI)) Si alte cantitati pot fi sufocate in variabile tip caracter, dar implementarea este dependenta de masina.


Sint disponibile 3 dimensiuni de intregi declarati short int, int si long int. Intregii lungi permit starii mai mari decit cei scurti, dar implementarea poate face ca intregii scurti,sau cei lungi, sau ambii sa devina echivalenti cu intregii de baza. Acestia au dimensiunea naturala decurgind dinarhitectura masinii, celelalte tipuri sint prevazute pentru cerinte speciale.


Intregii farasemn,declarati unsigned se supun legilor aritmeticiimodulo2n undenestenumaruldebitdin reprezentare. (La PDP11 cantitatile lungi fara semn nu sint suportate)


Cantitatiin VF simpla (float) sau dubla (double) pot sa fie sinonime in unele implementari.


Pentruca cantitatile descrise pot fi interpretate ca numere ce sint referite ca fiind de tip 'aritmetic'. Tipurile char si int de toate dimensiunile vor fi in mod colectiv numite de tip 'intreg'. (float si double vor fi denumite de tip 'flotant'.


In afara tipurilor aritmetice de baza exista, conceptual, o clasa infinitade tipuri derivate din tipurile de baza in modul urmator:


-tablouri de obiecte de multe tipuri

-functii care dau obiecte de un tip dat

-pointeri la obiecte de un tip dat

-structuri constituind o secvnta de obiecte de tipuri variate

-marimi capabile sa contina oricare unitate de obiecte de tipuri varaibie


In general aceste metode de constructie a obiectelor pot fi aplicate recursiv.

5. Obiecte si lvalori

Unobiect este o regiune manipulabila de memorare; o LVALOARE este o expresie referitoare la un obiect.Un ex simplu de expresieLVALOARE esteun identificator.Existaoperatori

care creaza (produc) lvalori: de ex, daca E este o expresie de tipul pointer, atunci*Eesteoexpresie lvaloare referitoare laobiectulsprecare pointeaza E.Numele 'lvaloare' vine de la expresia de asignare E1=E2 in care operandul sting E1 trebuie sa fie o expresie 'lvaloare'.Discutarea,mai jos,a fiecarui operator indica cind se asteapta operanzi 'lvaloare ' si cind operatorul produce o 'lvaloare'.

6. Conversii

Unnumar de operatori depinzind de operanzii lor sa cauzeze conversia unei valori a operandului dintr-un tip in altul. Aceasta sectiune explica rezultatul care se asteaptainurma unei astfel de conversii;&6.6 rezuma conversiile cerutede majoritateaoperatiilor curente (ordinare N.T) tabloul va fi imbogatit dupa (prin) discutarea fiecarui operator.


6. 1. Caractere si intregi

Uncaracter sau un intreg scurt pot fi folosite oriunde un intreg se poate folosi.Intoatecazurile valoarea este convertita intr-un intreg. Conversia unui intreg scurt intr-unul lung implica o extensie de semn;intregii sint cantitaticu semn.Extensia de semn pt caractere depinde de masina, dar se garanteaza ca un membru al unui set de caractere standard este nenegativ.Dintre masinile discutate aici dar la PDP-11 se extinde semnul. La PDP-11 valoarea variabilelor tip caracter este in gama-128la+127; caracterelealfabetului ASCII sint toate pozitive. O constanta tip caracter specificata octal sufera o extensie de semn si poate apare negativa de exemplu '377' are valoarea -1.

Cind un intreg mai lung este convertit intr-unul mai scurt sau char el este trunchiat la stinga; bitii in exces sint deplasati (pierduti).


6. 2. Float si double

Toataaritmetica in C este realizata in dubla precizie; cind apare un float intr-o expresie el este 'lungit' (extins) in double prin introducere de zeroruri in partea sa fractionara. Cind un double este convertit in float, de exempluprintr-o asignare, double-ul este rotunjit inaintea de trunchiere pe lungimea unui float.


6. 3. Flotante si intregi

Conversiaunei valori flotante in tip intreg devine dependenta de masina in particular directia de trunchiere a numerelor negative variaza de la masina la masina. Rezultatul este nedefibnit daca valoarea nu incape in spatiul prevazut (N. T. pt un intreg). Conversiile din intreg in flotant sint realizate bine. Poate apare o pierdere a preciziei daca detinatia nu are un numar suficient de biti.


6. 4. Pointeri si intreg

Unintreg sau un intreg lung poate fi adunat sau scazut dintr-un pointer; in acestcaz primul este convertit asa cum se specifica la operatia de adunare. Doi pointeri la obiecte de acelasi tip pot fi scazuti; in acest caz rezultatul este convertit intr-un intreg asa cum se va discuta la operatia de scadere.


6. 5. Fara semn

Orideciteoriun intreg fara semn si un intreg normal (de baza tipic) sint combinati, intregul tip este convertit in intreg fara semn si rezultatul va fi fara semn.Valoarea este cel mai mic intreg fara semn congruent intregului cu semn (modulo2 si lungimea caracterului). In reprezentarea in complement fata de 2, conversia esteconceptualasinuse modificatabloul (distributia) bitilor.Cind unintregfara semneste convertit in long , valoarea rezultatuluieste aceasi numeric, ca si a intregului fara semn. Deci conversia este introducere de zerouri spre stinga.


6. 6. Conversii aritmetice

Multioperatori cauzeaza conversii si produc rezultate de un tip oarecare, intr-un mod similar.Acest model va fi numit 'conversii aritmetice uzuale'. Intii, oricare operand de tipul char sau short va fi convertit in int, iar oricare operand de tipul float este convertit in tipul double.


Apoi, daca un operand este de tip double, atunci si celalalt este convertit in double si acesta va fi tipul rezultatului. Astfel daca un operand este long, celalalt este convertit in long si acesta va fi tipul rezultatului. Astfel, daca un operand este unsigned, celalalt este convertit in unsigned si acesta va fi tipul rezultatului. Astfel, daca ambii operanzi sint int, acesta va fi tipul rezultatului.

7. Expresii

Precedenta(prioritatea)operatorilordin expresii este aceasicuordinea subsectiunilordinaceasta sectiune, priritatea maxima fiind prima daca de exemplu expresiile referite ca operatori pentru +(&74) sint expresiile defiite in &&7.1-7. 3.Infiecaresubsectiune operatorii au aceeasi precedeta. Asociativitatea la stinga sau la dreapta este specificata in fiecare din operatorii din operatorii discutatiincadrul subsectiunii. Precedenta si asociativitatea tuturor operatorilor din expresii este rezumata in gramatica din &18.


Astfelordinea de evaluare a expresiilor estenedefinita. Inparticular compilatorul se considera liber de acalcula subexpresiile de maniera pe care el oconsideraceamai eficienta,chiardaca subexpresiile pot conduce la efecte secundare.Ordinea de aparatie a efectelor secundareeste nespecificata. Expresiilecare contin un comutator comutaiv si asociativ (*, +, &, |, ^) pot fi rearanjate arbitrar, chiar in prezentaparantezelor, pentru a se forta ordine particulara de evaluare o explicitare temporara devine necesara.


Prelucrarea depasirilor superioare si verficarea impartirilor la evaluarea expresiilor este dependenta demasina.Toate implementarileC-ului ignora depasirile superioareintregi; prelucrarea impartirii cu 0, si toate exceptiile VF variaza intre masini si sint uzual ajustabile printr-o functie de biblioteca.


7. 1 Expresii primare

Expresiile primare care contin.,->, subscrieri, si apeluri de functii se grupeaza de la stinga la dreapta.


primary-expresion:


identifier

constant

string

(expresion)

primary-expresion[expresion]

primary-expresion(expresion-list opt)

primary-lvalue. identifier

primary-expresion->identifier


expresion-list:

expresion

expresion-list, expresion


Un idetificator este o expresie primara, cu garantia ca a fost declaratasa cum se va discuta. Tipul sau este specificatla declarare.Daca tipul idetificatorului este 'tablouri de'atunci valoarea expresiei identificatoruluisauesteun pointer la primul obiect din tablou, iar tipul expresiei este 'pointer la'. Mai mult, un idetificator de tablou (masiv) nu este o lvaloare. La fel un idetificator care e declarat 'function returning' (functie carereturneaza ), cind este folosit (cu exceptia cazului cind apare canumele functiei la un apel) esteconvertitin 'pointer la functia ce returneaza'.


Oconstanta este o expresie primara. Tipul ei poate fi int, long sau double, depinzind de formasa.Constanteletip caracter au tipul int; constantele flotante sint double.


Un sir este o expresie primara. Tipul sau original (la origine) este 'tablou de char';urmind insaaceeasireguladata pentru identificatori, acesta este modificat in 'pointeri catre char' si rezultatul este un pointer catre primul caracter al sirului (exista o exceptie pt unele initializari a se vedea &8.6.).


O exprsie in paranteze este expresie primara a carui tip si valoare sint identicecualeexpresieifaraparanteze. Prezenta parantezelor nu are implicari daca expresia este o lvaloare. Oexpresieprimara urmata de o expresie in paranteze drepte este o expresie primara. Sensul intuitiv este acelaalunui indice. Obisnuit expresia primara are tipul 'pointer catre', expresiaindicelui este int, iar tipul rezultatului este '' (!!! N. T. ). Expresia E1[E2] este identica (prin definitie) cu *((E1)+(E2)).Toatereguluile necesare intielegeriiacesteinotatiisintcontinute in aceastasectiune impreuna cu discutiile din &&7. 1, 7. 2 si 7.

4. asupra identificatorilor, *, si respectiv +; &14. 3 rezuma implicatiile.


Un apeldefunctieesteexpresieprimaraurmata de paranteze continid un posibil vid, o lista de expresii separate prin virgule constituind argumentele actualealefunctiei. EXpresiaprimaratrebuie sa fie de tipul'functiecare returneaza',si rezultatul apelului functiei este de tipul ''. Cum se va indica,un identificator nevazut urmat de o paranteza stinga este contextual declarat careprezentindo functiecarereturneazaun intreg;deciin majoritatea cazurilor functiile car dau ca rezultat o valore intreaga nu trebuie declarate.




Oriceargument actual de tipul float este convertit in double inainte de apel; oricare argument de tipul char saushort esteconvertit in int; si, ca deobiecei numele de tablouri sint convertit in pointere. Daca este necesara o conversie se va folosi (N. T. cast) vezi &7. 2, 8. 7.

La pregatirea unui apella o functie se face o copie a fiecarui parametru actual adicatoate trecerile de argumente in C se fac prin valoare. O functie poate modifica valorea parametrilor sai formali, dar aceste modificari nu acteaza valoarea parametrilor actuali Mai mult se poate trece un pointer cu subintelesulfunctiapoate modificavaloarea obiectului spre care pointerul indica.Un nume de tablou este o expresie pointer. Ordinea de evaluare a argumentelor este nedefinita de catre limbaj;a se nota ca difera de la compiler la compiler. Sint permise apeluri recursive la orice functie.O expresie primara urmata deun punct urmatdeun identificator este o expresie. Prima expresie trebuie sa fie o lvaloare un signed a structurii sau o reuniune iar identificatorul trebuie sa fie un membru astructurii sau reuniunii.Rezultatul este o lvaloare referind membrul numit al structurii sau reuniunii.


O expresie primara urmata de o sageata (care se construieste din -si >) urmata de un identificator este oexpresie. Prima expresie trebuie sa fie un pointer la o structura sau la o reuniune si identificatorultrebuie sa numeasca un membrual acelei structuri saureuniuni. Rezultatuleste lvaloarecare refereaza membrulnumit al structurii sau reuniunii catre care pointerul expresiei puncteaza.


Astfel <expresia E1->MOS este identica cu (*E1). MOS. Structurile si reuniunile se discuta in &8. 5. Regulile date aici pentru utilizarea structurilor si reuniunilor nu nu sint stricte, de maniera care permite sa se scape de mecanismul tipurilor. Vezi &14.1.


7. 2. Operatori unari

Expresiile cu operatori unari se grupeaza de la dreapta la stinga.


unary-expression:


*expression

&lvalue

-expression

!expression

-expression

++lvalue

--lvalue

lvalue++

lvalue--

(type-name)expression

sizeof expression

sizeof(type-name)


Operatorul * inseamna indirect: expresia trebuie sa fie un pointer si rezultatul este o lvaloare care se refera la obiectul spre care pointeaza expresia. Daca tipul unei expresii este 'pointer catre' tipul rezultatului este ''.


Rezultatuloperatiei & este un pointer catre obiectul referit prin lvaloare. Daca tipul lvalorii este ' ' tipul rezultatului este 'pointer catre'.


Rezultatulunei operatii este negarea operandului. Se realizeaza conversiile aritmeticeobisnuite.Negativulunei cantitati este calculat prin scaderea valorii sale din 2 la n , unde 'n' este nr de biti pe care se reprezinta un int. Nu exista operatorul unar +.


Rezultatuloperatiei de negare logica ! este 1 daca valorea operandului a fost 0, si 0 daca operandul este non-zero. Tipul rezultatului este int. Operatia este aplicabila oricarui tip de opernand aritmetic sau pointerilor.


Obiectul referit prin operandul lvaloare precedat de ++ este incrementat. Valoareaeste noua valoare a operandului dar nu este o lvaloare. Expresia ++x este echivalenta cu x+=1. A se vedea adunarea (&7. 4) si operatorii de asignare (&7. 14) pentru informatii asupra conversiilor.


Operandul lvalorii cu prefixul -- este decrementat analog cu ++.


Cindpostfixul ++ este aplicat unei lvalori rezultatul este valoreaobiectului referitprinlvaloarea. Dupace rezultatulestenotatobiectul este incrementatin aceeasi maniera capentruoperatorulprefix++.Tipul rezultatului este acelasi cu tipul expresiei lvaloare.


Cind postfixul -- este aplicat unei lvalori rezultatul este valoareaobiectului referitprinlvaloare.Dupanotarea rezultatului obiectul este decrementat in maniera prefixului --. Tipul rezultatului este acelasi cu tipul expresiei lvaloare.


Oexpresie precedata de un nume de tip de data in paranteze cauzeaza conversia valorii expresiei in tipul de data numit constructia este denumita un cast (rol distributie, ). Numele de tipuri de date sint descrise in &8. 7.


Operatorul sizeof produce marimea in bytes a opeandului sau. (Un byte nu este definit de limbaj decit in termenul de valore a lui sizeof). Dar in toate implementarile un byte este spatiul necesar pastrarii unui char. Aplicat unui tablou rezultatul este numarul total de bytes din tablou. Marimea se determina din declaratiileobiectelor in expresii. Expresia este semnatic o constanta intreaga si poate fi folosita oriunde este necesara o constanta.Sefoloseste la comunicarile cu subprograme ca alocatori de memorie si sisteme de //0.


Operatorul sizeof poate fi aplicat unui nume de tip de data in paranteze. In acest caz va da marimea in bytes, a unui obiect de tipul indicat.


Constructiasizeof (type) este 1 deci expresia sizeof(type) -2 este aceeasi cu (sizeof(type)) -2.


7. 3. Operatori de inmultire

Operatorii de inmultire *, /, % grupeaza de la stinga la dreapta. Se realizeaza conversiile aritmetice uzuale.


multiplicative-expression:


expression*expression

expression/expression

expression%expression


Operatorul binar* indica inmultire. Operatorul * este asociativ si expresiile cu mai multe inmultiri de acelasi nivel pot fi rearanjate de compilator.


Operatorul/indicaimpartire. Cindseimpart intregi pozitivise face o trunchiere spre 0,dar forma trunchierii este dependenta de masina daca unul din operanzi este negativ.Pe toate masinile discutate in acest manual restul aresemnul impartitorului. Todeauna este adevarat ca (a/b) *b+a%b este egal cu a (daca b e diferit de zero).


Operatorul % produce restul impartirii primei expresii la a doua. Se realizeaza conversiile aritmetice uzuale. Operanzii trebuie sa

nu fie float.


7. 4. Operatori aditivi


Operatoriiaditivi + si- grupeaza de la stinga la dreapta. Se realizeaza conversiile aritmeticeuzuale.Exista citeva posibilitati de tip aditionale pentru fiecare operator.


aditive-expression:


expression+expression

expression-expression


Rezultatuloperatiei + este suma operanzilor.Unpointer catre un obiect dintr-un tablou si o valare de orice tip intreg pot fi adunate. Ultima este in toate cazurile convertita intr-un deplasament de adresa (N. T. address offset) prin inmultirea cu lungimea obiectului spre care indica pointerul. Rezultatul este un pointer de acelasi tip cu pointerul original si care indica un alt obiect din acelasi tablou, corespunzator deplasat fata de obiectul original. Deci daca P este un pointer catre un pointer dintr-un tablou (N. T. array) expresia P+1 este un pointer catre urmatorul element (obiect) din tablou.


Nu este permisa o alta forma de combinatie de tipuri pentru pointeri.


Operatorul + este asociativ si expresiile cu adunari multiple la acelasinivel pot fi rearanjate decompiler. Rezultatul operatorului - este difernta dintre operanzi.Se realizeaza conversi aritmetice uzuale.In plus o valore de orice tip de intreg poate fi scazuta dintr-un pointer cu aceeasi conversie ca la adunare.


Dacadoi pointeri catre obicte de acelasi tablou sint scazuti rezultatulesteconvertit(prinimpartire culungimea obiectlui) intr-un int care reprezinta numarul de obicte care separaobictele indicate (pointed-to).Conversia poateda rezultateneasteptate, dacapointerii nu indicaobiectele aceluiasi tablou intrucit pointerii chiar spreobiectede acelasi tip nu difera printr-un multiplu al lungimii obiectelor.


7. 5. Operatori de deplasare

Operatoriidedeplasare<<si >>grupeazastingala dreapta. Ambii fac conversiile uzuale asupra operanzilor fiecare trebuind sa fie un intreg. Apoi operanduldin dreapta se cponverteste in int; tipul rezultatului este aceea al operandului din stinga. Rezultatul este nedefinit daca operandul din dreapta este negativ sau > sau = cu lungimea obiectului in biti.


shift-expression:


expression<<expression

expression>>expression


Valoarealui E1<<E2 este E1 (interpretat ca forma de biti) deplasat la stinga; biti eliminati sint umpluticuzero. Valoarea lui E1>>E2 este E1 deplasat dreaptacuE2 pozitii binare. Deplasarea la dreapta este garantat a fi logica (cu umplere de zerouri) daca E1 nu are semn; altfel poate fi (si este la PDP11) aritmetica (cu umplerea bitului semn).


7. 6. Operatori relationali

Operatorii relationali grupeaza stinga la dreapta dar acest fapt nu este foarte folositor; a<b<c nu inseamna ceea ce pare.


relational-expression:


expression<expression

expression>expression

expression<=expression

expression>=expression


Operatorii <, >, <=, >= dau 0 daca relatia este falsa si 1 daca esteadevarata.Tipulrezultatuluiesteint. Sefac conversiile uzuale. Doi pointeri se pot compararezultatul depindedelocatiilerelativeinspatiulde adrese a obiectelorpoinate. Comparatia pointerilor este portabila numai cind pointerii indica spre obiecte din acelasi tablou.


7. 7. Operatori de egalitate


equality-expression:


expression==expression

expression!=expression


Semnul == (egal cu) si !=(inegal cu ) sint analogi operatorilor relationali dar nu au prioritate mai mica. (adica a<b==c<d este 1 daca a<b si c<d au valoare adevarat).


Un pointer poate fi comparat cu un intreg dar rezultatul va fi dependent de masina. Cu exceptia cazului cind intregul este constanta 0. Un pointer caruia i s-a asigurat valorea 0 se garanteaza ca nu va pointa spre nici un obiect si va apare a fi egal cu 0;in utilizarea conventionala un astfel de pointer este considerat nul.

7. 8. Operatorii si pe biti:


and expression:


expression&expresion


operatorul & este asociativ si expresiile continind & pot fi rearanjate Se realizeaza conversiile aritmetice uzuale; rezultatul este functia SI pe biti, a celor doi operanzi. Operatorul se aplica numai operanzilor intregi.


7. 9. Operatorul sau exclusiv pe biti


exclusive-or-expression:


expression^expression


Operatorul^ este asociativ si expresiile care contin ^ pot fi rearanjate.Serealizeazaconversiilearitmeticeuzuale; rezultatul este SAU exclusiv al celor doi operanzi la nivel de bit. Operatorul se aplica doar operanzilor intregi.


7. 10 Operatorul sau inclusiv


inclusiv-or-expression:


expression|expression


Operatorul| este asociativ expresiile care-l contin pot fi rearanjate. Se realizeaza conversii aritmetice uzuale; rezultatul estefunctie SAU inclusiv a operanzilor la nivel de bit. Operatorul se aplica doar operanzilor intregi.


7. 11. Operatorul si logic


logical-and-expression:


expression&&expression


Operatorul && grupeaza de la stinga la dreapta. El da 1 daca ambii operanzi sintdiferiti de 0 altfel da 0. Nu ca &, && garanteaza o evaluare de la stinga la dreapta; al doilea operand nu este evaluat daca primul este egal cu 0.


Operanzii pot fi de tipuri diferite dar fiecare trebuie sa fie unul din tipurile fundamentale sau un pointer. Rezultatul este intodeauna int.


7. 12 Operatorul sau logic


logical-or-expression:


expression||expression


Operatorul || opereaza de la stinga la dreapta. El da 1 daca unul din operanzi este diferit de 0 si altfel da 0. Nu ca |, || face evaluare la stinga -> dreapta, al doilea operand nu mai este evaluat daca primul este diferit de 0.


Operanziipot fi de tipuri diferite dar de tipurile de baza (fundamentale) sau pointeri. Rezultatul este totdeauna int.


7. 13 Operator conditional


conditional-expression:


expression?expression:expression


opereaza de la dreaptspre stinga. Prima expresie este evaluata si daca este non zero rezultatul este valoarea celei de a doua expresii. Altfel este al celei dea treia expresii.Daca este posibil conversiile artimetice uzuale se fac pentru a aduce a doua si a treia expresie la un tip comun; se poate ca unul sa fie pointer sicelalatzero, sirezultatul are tipul pointerului. Numai expresiile a doua si a treia sint evaluate.


7. 14. Operatori de atribuire

Operatoriideatribuire opereaza de la dreapta spre stinga. Toate solicita o lvaloare ca opernd stinga, iar tipul unei expesii de asigurare este acela al operanduluidin stinga. Valoarea este valoarea stocata in operandul din stinga dupace asigurareas-a facut. Cele doua parti ale unui operator de asigurare compus sint elemente sintactice (atomi)separati.

assignement-expression:


lvalue=expression

lvalue+=expression

lvalue-=expression

lvalue*=expression

lvalue/=expression

lvalue%=expression

lvalue>>=expression

lvalue<<=expression

lvalue&=expression

lvalue^=expression

lvalue|=expression


La asigurarea simpla cu = valoarea expresiei inlocuieste pe cea a obiectului referit prin lvaloare. Daca ambii operanzi sint de tip aritmetic operandul drept se converteste in tipul celui sting inainte de asigurare.


Comportarea unei expresii dforma E1op=E2 poate fi inferred luind ca echivalent al ei E1=E1op(E2); oricum E1 este evaluata doar odata. La += si -= operandul sting poate fi un poninterin careopernaduldin dreapta (intreg) este convertit dupacum se explica in &7. 4; toti opernazii din dreapta si toti opernazii stingi non pointeri trebuie sa fie de tip aritmetic.


Compilatoarele permit ca un pointer sa fie asignat unui intreg, un intreg sa fie asignat unui pointer si un pointer sa fie asignat unui pointer de alt tip. Asignarea este operatia de copiere pura fara conversii. Aceasta utilizare este neportabilasipoate produce pointeri care pot cauza exceptii de adresare la utilizare. Este garantata asignarea constantei zero la un pointer aceasta producind un pointer nul distinct de orice pointer spre orice

obiect.


7. 15 Operatorul virgula


comunn-expression:


expression, expression


O pereche de expresii separate prin virgula este evaluata de la stinga la dreapta si valorea expresiei din stingaeste declasata.Tipul si valoarea rezultatuluisinttipulsi valoreaoperandului din dreapta. Operatorul lucreaza de la stinga la dreapta. In contextul unde virgulei i se da un inteles special, de exemplu intr-o lista de argumente pt o fc. (&7. 1) sau liste de initializare(&8. 6), operatorul - virgula descrisa aici poate apare doar in paranteze, de exemplu:


f(a, (t=3, t+2), c)


are trei argumente, al doilea avind valoarea 5.

8. Declaratii

Declaratiile sint folosite pt a specifica interpretarea pe care C o da fiecarui identificator; nufacin mod necesar si rezervarea de memorie pt respectivul identificator. Declaratiile au forma:


declaration:


decl-specifiers declarator-list opt;


Declaratorii din lista de declaratori contin identificatorii de declarat. Specificatorii de declaratii constituie o secventa de specificatori de tip si clase de memorare:


decl-specifiers:


type-specifier decl-specifiers opt

sc-specifier decl-specifiers opt


listatrebuiesa fie unica (self consistent) in exemplul descris mai jos. (N.T. -sc=storage class)


8. 1. Specificatori de clase de memorare


Acestia sint:


sc-specifier:


auto

static

extern

register

typedef


specificatorul'typedef'nu rezerva memorie si este numit 'specificator'declasadememorie' doar dinmotive sintactice; se diacuta la &8. 8 sensurile diverselor claselor de memorare s-au discutat in &4.


Declaratiile auto,static si register servesc ca definitii pt ca cauzeaza o rezervare de memorie. La extern trebuie sa existe o definire externa (vezi &10) pt identificatori dati undeva in afara functiei unde ei au fost declarati.


Declaratia register este mai des vazuta ca o declaratie auto impreuna cu o alertare a compilatorului ca aceste varaibile vor fi utilizate des. Doar citeva declaratii deacesttipsint

efective. Mai mult doar varaibilele de anumite tipuri vor fi stocate in registre; la PDP11 acestea sint int, char si pointeri. Oaltarestrictiesereferalavariabileleregistru. Operatorul & (care lucreaza cu adrese) nu li se poate aplica programele create pot deveni mai mici mai rapide dintr-o utilizare de declaratii register folosite corespunzator, dar inbunatatiri viitoare lae generarii de cod pot sa le faca necesare.


Celputin un specificator de tip memorare poate fi dat intr-o declarare. Daca lipseste el este considerat auto in interiorul functiei, si extern in afara ei. Exceptie: functiile nu sint niciodata automatic.


8. 2. Specificatori de tip


type-specifier:


char

short

int

long

unsigned

float

double

struct-or-union-specifier

typedef-name.


Cuvintelelong, short si unsigned pot fi privite ca si adjective; urmatoarele combinatii sint aceptabile.


short int

long int

unsigned int

long float


Sensulultimei constructii este acelasi cu double.Altfel cel mult un specificator de tip poate fi dat intr-o declaratie. Daca specificatorul de tip lipseste el este considerat int.

Specificatorii de structuri si reuniuni vor fi discutati in &8. 5, declaratiile cu typedef sint discutate in &8. 8.


8. 3. Declaratori

Lista de declaratori care apare intr-o declaratie este o secventa separata prin virgula de declaratori, fiecare trebuind sa aiba o initializare.


declarator-list:


init-declarator

init-declarator, declarator-list


int-declarator:


declarator initialiser opt.

Initializatorii sint discutati in &8. 6. Specificatorii dintr-o declarattie indica tipuri si clasedememorarea obiectelorlacare se refera declaratorii. Declaratorii au sintaxa:


declarator:


identifier

(declarator)

*declarator

declarator()

declarator[constant-expression opt]


Gruparea este ca la expresii.


8. 4. Sensul declarartorilor

Fiecaredeclarator este o afirmatie de genul ca atunci cind o constructie de aceeasi forma ca si declaratorul apare intr-o expresie, va produce un obiect de tipul si clasa indicata. Fiecare declarator contine doar un identificator;acest identificator se declara.


Daca doar un identificator apare ca declarator, atunci el va avea tipul indicat de specificatorul de la inceputul declaratiei.




Undeclarator in paranteze este identic cu un declarator fara atribute, dar amestecarea declaratorilor complecsi poatefi alterat prin paranteze. Vezi exemplele de declaratie.


Acum sa ne imaginam o declaratie


T D1


undeT este un specificator de tip (ca int) si D1 este un declarator.Sapresupunem ca aceasta declaratiefaceca identificatorul (N. T. din declarator) sa aibe tipul ''unde ' ' este gol daca D1 este doar un identificator pur si sipmplu (asa ca tipul lui X din 'int X' este doar int ). Daca D1 are forma:


*D


tipul identificatorului continut este 'pointer la T'.


Daca D1 are forma


D()


atunci identificatorul continut are tipul 'functiece returneaza T. '


DacaD1 are forma D[constant-expression] sau D[], atunci identificatorul continut are tipul 'tablou de T'. In primul caz expresia constantei este o expresie a carei valoare estedeterminabila in momentul compilarii si care are tipulint (expresiileconstanta sint definite precis in &15). Cind mai multe specificatiidetsblou sint adiacente se creaza un tablou multidimensional; expresiileconstanta care specifica limitele tablourilor pot sa lipseasca doar pentru primul membru al secventei. Aceasta forama este folositoare daca tabloul e extern sidefinitia actuala,care aloca spatiu, este totusi data. Prima expresiecontantapoatefi omisa daca declaratorul

esteurmatdeo initializare.In acest caz marimea se calculeaza din nr elemente precizate.


Un tablou poate fi constituit din unul din tipurile de baza prin pointeri dintr-o structura sau reuniune,sau din alt tablou (pt a genera tablouri cu dimensiuni multiple).


Nutoateposibilitatiledate desintaxasintpermise. Restrictiile sint urmatoarele: functiile nu pot returna tablouri, structuri sau reuniuni dar pot returna pointeri spre asa ce va; nu exista tablouri de functii dar pot exista tablouri de pointeri spre functii. O structura sau o reuniune nu poate contine o functie, dar poate contine un pointer la o functie. Exemple:


int i; *ip, f(), *fip(), (*pfi)();


decalara

un intreg i

un pointer ip la un intreg

o functie f care returneza un intreg

o functie fip care returneaza un pointer la un intreg

un pointer pfi la o functie care reurneaza un intreg

Secomparaultimele. *fip()este*(fip()) declaratia sugereaza si aceiasi constructie intr-o expresie necesita apelul functiei fip si apoi indirectarea sprerezultat(pointer) se produce un intreg.(*pfi)() in declaratie parantezelesint necesare ca si intr-o expresie ca sa indice ca indirectarea prin pointeri la o functie produce o functie care este apoi chemata; va returna un intreg.


Alt exemplu:


float fa[17], *afp[17]


declara un tablou de flotante si un tablou de pointere spre numere flotante.


In final:


static int x3d[3][5][7];


declara un tablou de intregi, static, cu dimensiunile 3x5x7. In detaliu X3d este un tablou de 3 articole; fiecare articol este un tablou de 5 tablouri; si fiecare din ultimul este un tablou de 7 intregi. Oricare din expresiile x3d, x3d[i],x3d[i][j], x3d[i][j][k] poate apare intr-o expresie. Primele trei sint de tip 'tablou', ultima are tipul int.


8. 5. Declaratorii de structuri si reuniuni

Ostructuraeste un obiect constind dintr-osecventa de memorii cu nume. Fiecare membru poate aveaoricetip. O reuniune este un obiect care, la un moment dat, poate contine pe oricare din mai multi membri.


Specificatorii de structuri si reuniuni au aceeasi forma:


struct-or-union-specifier:


struct-or-union

struct-or-union identifier

union identifier


declaraidentificatorul ca eticheta (marcaj)destructura (sau uniune) a structturii specificate de lista. O declaratie de a treia forma


struct identifier

union identifier


Etichetelede structura permit definirea de structuri autoreferibile ele permit ca partea lunga a unei structuri sa fie data odata si folosita de mai multe ori.Este ilegal a declara o structura sau uniune care face apel la ea insasi,dar o structura sau uniune poate contine un pointer la un apel spre ea insasi.

Numele membrilor si etichetele sint la fel ca pentru variabilele ordinare dar sa fie distincte mutual.


Doua structuri pot folosi in comun o secventa initiala de membri; adica acelasi membru apare in doua structuri diferite daca au acelasi tip in ambele si daca membrii anteriori sintacesasi in ambele(In momentul de fata, compilatorul verfica numai daca inunuldindoua structuri diferite are acelasi tip si deplasament in ambele, dar daca membrii precedenti difera, constructtia este neportabila ).


Exemplu simplu de declarare de structura:


struct tnode;

contine

-un tablou de 20 caractere

-un intreg

-2 pointeri catre structuri similare


Odata aceasta declaratie facuta, declaratia


struct tnode s, *sp;


declara S ca fiind o structura de tipul dat si sp un pointer la o structura de tipul dat.


Cu aceste declaratii expresia:


sp->count


Se refera la cimpul count spre care pointeaza sp;


s. left


Se refera la pointerul subarborelui stinga


s. right->tword[0]


Se refera la primul caracter al subarborelui tword din arborelui drept al lui S.


8. 6. Initializare

Un declaratorpoatespecifica ovaloareinitialapt identificatorul declarat. Initializatorul este precedat de = si consta dintr-o expresie sau o lista de valori in acolade.


initializer:


=expression

=

=


initializer-list:


expression

initializer-list, initializer-list



Toate expresiile pentru initializarea unei variabile statice sau externe trebuie sa fie expresii de constanta, descrise in &15, sau expresii care se reduc la adresa variabilei declarate anterior, cuposibilitateade a fi deplasate printr-o constanta. Variabila automatic si registerpot fi

initializate cuexpresiiarbitrarecare pot contine constante, variabile declarate anterior si functii.


Variabilelestatice si externe neinitializate la start primesc valoarea zero. Cele automatic si register au continut nespecificat (probabil 'gunoi').


Cindintr-un initializator se aplica unui scalar (pointer sau un obiect de tip aritmetic) el consta dinexpresiesingulara posibil in paranteze. Valoarea initiala a obiectului se obtine din expresie; aceleasi conversii ca pentru atribuire se folosesc.


Cindo variabila declarata este un agregat ( structura sau tablou)atunciinitializatorulconstadintr-olistade initailizatori separati prin virgule in parantze (acolade)scrise siinordinea in care cresc indicii sau in orinea membrilor. Dacanumarul de initializatori este mai mic decit al membrilor se impune restul cu 0. Nu se initializeaza uniuni sau agregate de tip automatic.


Acoladele se pot elimina. Daca un initilizator incepe cu acolade stingaatuncivaurmaolistade initializare cu initializatori despartiti stinga prin virgule pentru membrii agregatului;este eronat sa existe mai multi initializatori decitmembri. Daca initializatorul nu incepe cu acolada stinga atunciseiau din lista numarul necesar de elemente pentru agregatul curent, restul lasati la dispozitia agrgatului urmator.


De exemplu:


int x[]=;


xeste declarat si initializat cu un tablou cu o dimensiune care are trei membri.


float y[4][3]={

, initializeaza prima linie adica y(0)

, care este y[0][0], y[0][1] si y[0, 2]

, apoi se initializeaza liniile y[1] si y[2]

}; y[3] se inittializeaza cu 0.

Acelasi efect se obtine cu:


float y[4][3]=;


Initializarea pentru y incepe cu acolada stinga, dar pentru y[0] nu, de ci se folosesc trei elemente din lista. Urmatorele trei sint luate pentru y[1] si y[2]. Deci:


float y[4][3]=, , ,

};


initializeazaprimacoloana a lui y (privit ca un tablou cu doua dimensiuni) si lasa restul pe zero.


Si:

char msg[]='syntax error on line %s/n';


arata un tablou de caractere a carui membri sint initializati cu un sir.


8. 7. Nume de tipuri

In doua contexte (pt a se specifica explicit o expresie cu ajutorul unei distributii (N.T. cast) si ca si argument pt size of) este de dorit a se specifica numele unui tip de data. Aceasta se realizeaza folosind 'nume de tip' careestein esenta o declaratie pt un obiect de tipul respectiv care omite

numele obiectului.


type-name:


type-specifier abstract-declarator.


abstract-declarator:


empty

(abstract-declarator)

*abstract-declarator

abstract-declarator()

abstract-declarator[constant-expression opt]


Pentru a se evita ambiguitatea in constructia


(abstract-declarator),


abstract-declaratorulnutrebuiesafie vid. Cu aceasta restrictiese poate identifica unic locatia dinabstract-declarator unde va apare declaratorul daca constructia a fost un declarator intr-o declaratie. Tipul de nume este acelasi cu tipul unui identificator ipotetic de exemplu:


int tip->intreg

int* pointer la (catre) intreg

int*[3] tablou de 3 pointeri la intregi

int(*)[3] pointer la un tablou format din 3 intregi

int*() functie care returneaza un pointer la un intreg

int(*)() pointer la o functie care returneaza un intreg


8. 8. Typedef

Declaratiile a caror 'clasa de memorare' este typedef nu definesc o memorie ci definesc identificatori care vor fi utilizati ulterior ca si cum ar fi cuvinte cheie de tip denumind tipuri fundamentale sau derivate.


typedef-name:


identifier


Roruluneideclaratiicontinind typedefestecaorice identificator care apare ca parte a oricarui declarator din interiorul (declaratiei) devine sintactic echivalenta cu cuvintele cheie de tip numind cuvintele de tip asociat identificatorului in modul desis in &8..De exemplu, dupa:


typedef int MILES, *KLICKSP;

typedef structcomplex;


Constructiile


MILES distance;

extern KLICKSP metricp;

complex 2, *zp;


sint declaratii legale; tipul lui distance este int, al lui metricp este 'pointer la un int', si al lui z este structura specificata; zp este pointer la respectiva structura.


typedef nu introduce tipuri noi, numai sinonime pt tipuri care se pot specifica si altfel.In exemplul distance este considerat a avea exact acelasi tip ca orice alt obiect int.

9. Enunturi

Cu exceptiile ce vor fi indicate, enunturile se executa in secventa.


9. 1. Enunt expresie

Multe enunturi sint enunturi expresie, care au forma:


expression;


In general enunturile expresie sint asignari sau apeluri de functie.


9. 2. Enuntul compus sau block

Se prevede enuntul compus intrucit se pot folosi mai multe enunturi acolo unde este asteptat doar unul:


compound-statement;


declaration-list:


declaration

declaration, declaration-list


statement-list


statement

statement statement-list


Daca unul din identificatorii din lista de declaratii a fost declarat anterior, declaratiaexterna este decazutapentru durata unui bloc, dupa care isi epuizeaza forta.


Orice initializare de variabile auto sau register se realizeaza de fiecare data cind se intra in bloc la virful sau. Este posibil( dar este o practica rea ) de a face transferul in bloc; in acest caz nu se face initializarea.


Initializareavariabilelorstaticse face doar odata, la inceputul executiei programului.In bloc, declaratiile extern nu rezerva memorie astfel ca initializarea nu este permisa.


9. 3. Enunturi conditionale

Sint 2 forme de enunturi conditionale:


if(expresie) statement

if(expresie) statement else statement


Inambele cazuri se evalueaza expresia si daca nu sint zero se executa primul enunt. In al2-lea caz seexecuta a 2-a instructie daca prima este egala cu zero.Ambiguitatealui 'else'este rezolvata prin conectarea unui 'else' cu ultimul 'else-less if' intilnit.


9. 4. Instructii while

Forma: while(expression)statement


Instructiadinwhile este executat repetat atita timp cit valoarea expreie ramine diferita de zero. Testul se face inainte de executia instructiei.


9. 5. Instructia do

Are forma


do statement while(expression);


Instructia este executata repetat pina cind valorea expresiei devine zero. Testul se face dupa fiecare executie a instructiei.


9. 6. Instructia for

Are forma:


for(expression-1opt;expression-2opt;expression-3opt)statement


Este echivalenta cu:


expression-1;

while(expression-2)



Deciprimaexpresie specifica initializarea buclei; a doua specifica un test, facut inaintea fiecarei iteratii, astfel ca din bucla se iese cind expresia devine zero;a 3-a expresie specificao incrementare care este realizata dupafiecare iteratie.


Oricaresau toate expresiile pot lipsi. Daca lipseste a doua instructie while implicata devine echivalentacuwhile(1); celelalte expresii vor lipsi din constructia data.


9. 7. Instructia switch

Instructia switch face ca controlul sa fie transferat la una din mai multe instructii functie de valoarea expresiei. Are forma:


switch(expression)statement


Seexecuta conversiile necesare, dar rezultatul trebuie sa fie int. Instructia este compusa.Orice instructie din bloc pate fi etichetata cu un prefix tip case


case constant-expression


unde expresia de constanta va fi un intreg(int). Este interzisa aparitia a doua constantepentru case in aceasiinstructie switchcu aceeasi valoare. Constantele se definesc precis in &4. 5.


Poate exista un prefix de instructie de forma


default:


Cind se executa instructia switch,expresia se evalueaza si se compara cu constantele case. Daca una este egala cu valorea expresiei, controlul se va da la instructia urmind prefixul gasit.


Dacanuexista instructii cucase-ul cautat, dar exista prefixul defaault, controlul se da la instructia prefixata. Inlipsa prefixului default nu se executa niciunadin instructiuni.


casesidefault, in sine, nu altereaza mersul programului. Iesirea din switch se face cu break (vezi &9.8) In general instructiaal carui subiect este switchesteun bloc.Declaratii pot apare la inceputulinstructiei,dar initializarea variabilelor automaticsiregister sint inefective.


9. 8. Instructia break

Are forma:break;si face sa se termine ciclul cel mai intern while, do, for sau switch. Controlul trece la instructia care urmeaza dupa instrucctia de terminare.


9. 9 Instructia continue

Are forma:


continue;


si face sa se treaca la continuarea in bucla a celui mai intern while, do sau for; adica se sare la sfirsitul buclei. Mai precis, in fiecare din instructiile


while() do }while(); }


O instrcutie continue este echivalenta cu goto contin(Dupa contin: o instructie goala)


9. 10. Instructia return

O functie revine la apelant cu instructia return care are formele:


return;

return expression;


In primul caz valoarea returnata nu e definita. In al doilea caz valoarea expresiei este returnata apelantului. Daca se cere, expresia este cnvertita, ca la asignare, in timpul functiei in care apare. Ocolirea finalului unei functii este echivalenta cu nereturnarea de valoare la apelant.


9. 11. Instructia goto

Controlul se poate transfera neconditionat cu ajutorul instructiei:


goto identifier;


Identificatorul trebuie sa fie o eticheta (vezi 9. 12) din functia curenta.


9. 12 Instructii etichetate

Oricare instructie poate fi precedata de un prefix eticheta de forma


identifier:


careservestepentrudeclararea identificatoruluicasi eticheta.Unica utilizare a etichetei este de tinta a unui goto. Bataia unei etichete este functia curenta, excluzind sub blocurile in care acelasi identificator poate fi redeclarat. Vezi &11.


9. 13 Instructia nula

Are forma


;


Este folosita pentru ca poate purta o eticheta chiar inainte de }(N.T. acolada finala) a unei instructii compuse sau servind ca si corp de instructii nul unei instructii de buclare gen while.

10. Definitii externe

Unprogram C consta dintr-o secventa de definitii externe. O definitie externa declara un identificator ca avind clasa de memorareextern(inlipsa specificatorului sau static, si un tip specificatn tip specificat. Specificatorul de tip (vezi 8. 2) poate fi vid, in care caz tipul va fi luat ca si int. Intinderea unei definitii externe persista pina la sfirsitul fisierului incare a fost declarata asa cum efectul unei declaratii persista pina la sfirsitulunuibloc. Sintaxa defintiilor extern este aceeasi ca a tuturor declaratorilor, cu exceptia ca numai la acest nivel poate fi dat codul pentru functii.


10. 1. Definitii de functie externe

Definitiile de functii au forma:


function-definition:


decl-specifiersopt function-declarator function-body


Singuriispecificatori de clasa de memorare permisa in cadrul specificatorilor de declaratii sint extern sau static;a se vedea &11. 2 pentru distinctia dintre ele.Un declarator de functieeste similar cu un declarator pentru 'functiecare returneaza' cu exceptia ca el listeaza parametrii formali ai functiei de definit.


function-declarator:

declarator(parameter-listopt)


parameter-list:

identifier

identifier, parameter-list


Corpul functiei are forma:




function-body:


declaration-list compound-statement


Identificatoriidin lista de parametrii,si numaiacesti identificatori, pot fi declarati in lista de declaratii. Orice identificator al carui tip nu este dat se considera a fi de tip int. Singurul tip de clasa de memorare care poate fi specificata este register; daca aceasta e specificata, parametrul actual corespunzatorva fi copiat,dacaesteposibil, intr- un registru in codul codului functiei. Un exemplu simplu de definitie completa de functie este:


int max(a, b, c)

int a, b, c;



Aici int este specificator de tip;max(a, b, c) este declaratorul de functie int a,b, c; este lista de declaratii pentru parametrii formali; este blocul care da codul pentru instructie.


'C'converteste parametrii actuali de tip float in double, astfel ca parametrii formali declarati float isi vor avea declaratiile ajustate pentru a se citi double. Astfel,daca o referinta la un tablou in orice context (in particular cuunparametru actual)estecnsiderata a avea sensul unui pointer la primul element al unui tablou,declaratiileparametrilor formali de genul 'tablou de' sint ajustate in 'pointeri catre'. In final, intrucit structurile, uniunile si functiile nu pot fi trecute unei functii, este fara utilizare declararea ca parametri formali a unei structuri, uniuni sau functii (pointerii la astfel de obiecte sint permisi).


10. 2. Definitii de date externe

O definitie de data externa are forma:


data definition:


declaration


Clasadememorare a unei astfel de date poate fi extern (in lipsa) sau static dar nu auto sau register.

11. Reguli despre domenii

Unprogram in C poate sa nu fie compilattotdeodata: textul sursa al progarmului poate fi pastrat in mai multe fisiere sirutine precompilate pot fi incaractedin biblioteci. Comunicatiileintre functiile unui program pot fiapeluri explicite sau utilitare de date externe.


Exista2 feluri:primul,ce ar putea fi numit obiectivul lexical al unui identificator,care este in esenta regiunea unui program in timpul caruia el poate fi folosit fara a apare eroarea de 'identificator nedefinit'; si al 2-lea obiectivul asociat cu identificatori externi care se caracterizeaza prin regula ca referinta la acelasi identificator extern sint referinte la acelasi obiect.


11. 1 Domeniu lexical

Obiectivul lexical al identificatorilor declaratiin definitiile externe se intindede ladefinitiepinala sfirsitul fisierului sursa in care apare. Intinderea lexicala a indentificatorilor care sint parametri formali persista in functia cu care sint asociati. Scopul lexical al identificatorilor declarati lainceputdebloctinepinalasfirsitul blocului. Intentia lexicala a etichetelor este in functia in care apar.


Intrucit toate referintele la acelasi identificator extern se refera la acelasi obiect(vezi 11. 2)compilatorul verifica toate declaratiile aceluiasi identificator externpt compatibilitate; de fapt puterea lor se intinde asupra intregului fisier pe care apar.


In toate cazurile, daca un identificator este explicit declarat la inceputul unui bloc,incluzind blocul care constitue o functie, orice declaratie al acelui identificatorinafara blocului este suspendata pina la sfirsitul bocului.


Dereamintit(vezi 8.5) ca identificatorii asociati cu varaibile ordinare pe de o parte si acei asociati cu membrii ai unor structuri sau reuniuni pe de alta parte,frmeaza doua clase disjuncte fara conflict intre ele. Membrii (de reuniuni sau structuri n. t. ) si etichetele urmeaza aceleasi reguli obiectuale casi identificatorii;numele declarate cu typedef sint de aceasi clasa cu identificatorii ordinari. Ei pot fi redeclarati in blocurile interne, dar un tip explicit se va da in declaratia interioara.


typedef floatdistance;


Denotat ca f trebuie declarata explicit in rutina apelanta pt ca aparitia sa in g(f) nu este urmata de (.


14. 3. Tablouri, pointeri si indici

De fiecare data cind un identificator de tipul tablou apare intr-o expresie el este convertit intr-un pointercatre primul element al tabloului. Din cauza acestei conversii tablourile nu sintlavlori.Prindefinitie operatorul indice [] este interpretat de asa maniera incit E1[E2] e identic cu *((E1)+(E2)). Din cauza regulilor de conversie care se aplica lui +, daca E1 este tablou si E2 intreg atunci E1(E2) se refera la al E2-lea membru al lui E1. Darin ciuda acestei aparente asimetrii, indicii formeaza o operatie comutativa.


O regula soloidaseaplicain cazul tablourilor multidimensionale. Daca E este un tablou de ordinul 'n' si indiciixjxxk atunci cind E apare intr-o expresie el va fi convertit intr-un pointer la un tablou cu 'n-1' dimensiuni cu indicijxxk. Daca se aplica operatorul *, explicit sau implicit ca rezultat al utilizarii indicilor, rezultatul este un tablou pointat de n-1 dimensiuni, care este imediat convertit intr-un pointer. De exemplu:


int x[3][5];


Unde x este un tablou de intregi cu 3X5 elemente. Cind x apare intr-o expresie, este convertit intr-un pointer catre(primul din cele 3) tabloul de 5 membrii intregi.In expresiax[i], care e echivalenta cu *(x+i), X este mai intii convertit intr-unpointer asa cum s-a descris;i este apoi convertit in tipul lui x, careimplicainmultirealuiiculungimea obiectuluispre care pointeaza,adica 5 obiecteintregi. Rezultatulse aduna si seaplica indirectarea producind untablou (de intregi) care este la rindul sau transformat intr-un pointer la primul dintre intregi. Daca mai este un indice acelasi procedeu se aplica din nou; acum rezultatul va fi un intreg.


RezultacainC tablourile sint stocate pe linii (ultimul indice variaza cel mai repede ) si ca primulindicedin declaratie permite sa se de termine necesarul de memorie dar nu are alt rol in calculul indicilor.


14. 4. Conversii de pointeri explicite

Uneleconversii de pointeri sint permise doar auaspecte dependente de implementare.Toate se specificaprin conversii explicite de tip ca in &7. 2 si &8. 7.


Unpointer se poate converti in oricare tip de intreg suficient de mare pentru a-l pastra.Dar a utiliza int sau long este dependent de masina. Functiile de mapare sint dependente de, dar nu vor surprinde pe aceea care cunosc structura de adresare a masinii. Detalii se dau mai jos.


Un obiect de tip intreg poate fi convertit explicit in pointeri. Maparea face ca un intreg convertit din pointer sa dea acelasi pointer, depinzind de masina. Un pointer catre un tip poate ficonvertit intr-un pointer la alt tip. Pointerulrezultat da exceptii de adresare la folosire daca pointerul subiect nu se referala un obiect aliniat corespunzator in memorie.Se garanteaza ca un pointer la un obiect de o marime data poate fi convertit intr-un pointer catre un obiect mai mic in dimensiune si inapoi fara modificari.


Deexemplu,rutinade alocare de memorie poate accepta o marime (in biti, a unui obiect de alocat si sa returneze un pointer char; acesta putind fi folosit conform scopului.


extern char *alloc();

double *dp;

dp=(double*)alloc(sizeof(double));

*dp=22. 0/7. 0;


alloctrebuie sa asigure (de o maniera dependenta de masina) ca valoarea pe care o returneaza este corespunzatoare connversiei intr-un pointer catre double < atunci utilizarea functiei este portabila.


Reprezentarea pointerului la PDP-11 este un intreg de 16 biti si se masoara in bytes;chars nu necesitaaliniere speciala; orice altceva trebuie sa aiba o adresa para.


PeHoneywell un pointer are 36 de biti si e intreg; adresa de cuvint e pe cei 18 biti din stinga, iar bitii care selecteaza caracterul din cuvint in partea dreapta;deci pointerii char sint masurati in unitati de 2 la 16 bytes; orice altcevain unitati de 2 la 18 cuvinte; double si agregatele care le contin trebuie sa fie la adresa de cuvint para.


IBM 370 si Interdata 8/32 sint similare. La ambele adresele se masoara in bytes;obiectele elementare sint aliniatela limite egale cu lungimea lor; pointeri catre short sint0 mod 2, catre int sau float 0 mod 4 si la double 0 mod 8. Agregatele sint aliniate la limitele stricte necesitate de constituenti.

15. Expresii 'constante'

Inmulte locuri C necesita expresii care dau o constanta: dupa case, ca limite de tablouri, la initializari. In primele 2, expresiile pot cuprinde doar constante intregi,constante caracter, expresii tip sizeof conectate la operatorii binari:


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


Sau prin operatorii unari:


- ~


Sau prin operatorul ternar:


? :


Parantezele sint folosite pt grupare, nu pt apeluri de functii. O latitudinemai mare o permit initializarile;in afara de expresiile constante se poate aplica operatorul unar&la obiecte externe sau statice, sau la tablouriexternesau statice avind ca indici expresii constante.


Operatorul unar & poate fi aplicat implicit prin aaparitia de tablouri fara indici sau functii.Regulade baza este ca initializarile conduc la o constanta sau la o adresa a unui obiect extern sau static plus sau minus o constanta.

16. Consideratii de portabilitate

Unele parti din C sint inerent dependente de masina. Lista care urmeazacontine sursele de prorbleme cele maiimportante: Lungimea cuvintului de memorie si proprietatea aritmeticei in VF sau impartirea intregilor au dovedit in practica ca nu sint o problema. Alte fatete ale hardware-ului sint reflectatein diversele implementari. Unele din ele, ca extensia de semn (

convertireaunui caracter negativ intr-un inttreg) si ordinea bytelor in cuvint, sint neplaceri care trebuie observate atent. Altele sint probleme minore.


Numarul de variabile register care pot fi plasate efectiv in registre depind de la masina la masina,ca si seturide tipurivalide.Compilatoarele fac lucrurile corespunzator proprieimasini;declaratiile register excesive sau invalide sint ignorate.


Unele dificultati cresc cind se folosesc practici de codificare dubioase. Nu este recomandat a se scrie programe care depind de aceasta proprietate.


Ordineade evaluare a argumentelor functiilor nu este specificata de limbaj. La PDP-11 este de la dreapta la stinga, la altele de la stinga la dreapta. Ordinea de aparitie a efectelor secundare nu e specificata.


Dacaconstantelecaractersintobiectedetipulint, constantele caracter multicaracter sin permise.Implementarea specifica depinde de masina pt ca ordinea in carecaracterele sint plasate in cuvint variaza de la o masina la alta.


Cimpurile apar in cuvint si caracterele in intregi de la dreapta la stinga in PDP si de la stinga la dreapta in alte masini. Aceste diferente sint invizibile in programe izolate carenufac apella dependente de tip (de exemplu conversia din pointer int in pointer char si implementarea memoriei pointate) dar trebuie considerate daca se doreste conformarea cu modalitatile de memorare externa.


Limbajulacceptat de diversele compilatoare difera putin. Dar, compilatorul pt PDP=11 folosit curent nu initializeaza structuri de cimpuri de biti, nu accepta operatori de asignare in unele contexte in care se foloseste valoarea asignarii.



17. Anacronisme


C este un limbaj in evolutie, unele constructii invechite pot fi intilnite in programe mai vechi. Unele compilatoare suporta aceste anacronisme, ele fiind pe cale de disparitie, raminind doar problema portabilitatii.


Versiunile mai vechi de C permiteau forma =op in locul lui op= pt asignare. Acestea duceau la ambiguitati, cum ar fi


x=-1


careacuminseamnascaderea unui 1 din x, = si - fiind adiacente, dar care poate insemna si asignarea lui -1 lui x.


Sintaxa initializarilor s-a schimbat; la inceput semnul = care anunta un initializator nu era prezent, adica in loc de


int x = 1;


se folosea


int x 1;


modificarea s-a facut pentru ca initializarea


int f(1+2)


semanacuo declaratie de functie atit de mult incit deranja compilatoarele.

18. Sumar al sintaxei

Acest sumaralsintaxei C-ului are scopul de aajuta intelegerea sa mai mult decit de a defini exact limbajul.


18. 1. Expresii

Expresii de baza sint:


expression:


primary

*expression

&expression

-expression

!expression

~expression

++lvalue

--lvalue

lvalue++

lvalue--

sizeof expression

(type-name)expression

expression binop expression

expression?expression:expression

lvalue asgnop expression

exprerssion, expression


primary:


identifier

constant

string

(expression)

primary(expression-listopt)

primary[expression]

lvalue. identifier

primary->identifier


lvalue:

identifier

primary[expression]

lvalue. identifier

primary->identifier

*expression

(lvalue)


Operatorii expresiilor primare


() []. ->


au cea mai mare prioritate si grupeaza stinga la dreapta.


Operatorii unari:


* & - ! ~ ++ -- sizeof(type-name)


au prioritatea sub cea a operatorilor primari dar mai mare decit a operatorilor binarisigrupeaza de la dreapta la stinga. Operatorii binari si operatorul conditional grupeaza stinga la dreapta si au priortatea descrescind asa cum e indicat


binop:


* / %

+ -

>><<

< > <=>=

==!=

&

^

|

&&

||

?!


Operatorii de asignare au aceeasi prioritate


asgnop:


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


Operatorul, au cea mai mica prioritate, grupeaza stinga spre dreapta



18. 2. Declaratii


declaration:


decl-specifiers init-declarator-listopt;


decl-specifiers:


type-specifier decl-specifiersopt

-specifier decl-specifiersopt


sc-specifier:

auto

static

extern

register

typedef


type-specifier:


char

short

int

long

unsigned

float

double

struct-or-union-specifier

typedef-name


init-declaration-list:


init-declarator

init-declarator, init-declarator-list


init-declarator:


declarator initializeropt


declarator:

identifier

(declarator)

*declarator

declarator()

declarator[constant-expressionopt]


struct-or-union-specifier:


struct

struct identifier

struct identifier

union

union identifier

union identifier


struct-decl-list:


struct-declaration

struct-declaration struct-decl-list


struct-declaration:


type-specifier struct-declarator-list;


struct-declarato-list:


struct-declarator

struct-declarator, struct-declarator-list


struct-declarator:


declarator

declarator:constant-expression

:constant-expression


initializer:


=expression

=

=


initializer-list:


expression

initializer-list, initializer-list



type-name:


type-specifier abstract-declarator


abstract-declarator:


empty

(abstract-declarator)

*abstract-declarator

abstract-declarator()

abstract-declarator[constant-expressionopt]


typedef-name:


identifier


18. 3. Enunturi


compound-statement:


declaration-list:


declaration

declaration declaration-list


statement-list


statement

statement statement-list


statement:


compound-statement

expression;

if(expression)statement

if(expression)statement else statement

while(expression)stament

do statement while(expression);

for(expression-1opt;expression-2opt;expression-3opt)statement

switch(expression)statement

case constant-expression:statement

default:statement

break;

continue;

return;

return expression;

goto identifier;

identifier:statement

;


18. 4. Definitii externe


program:


external-definition

external-definition program


external-definition:


function-definition

data-definition


function-definition


type-specifieropt function-declarator function-body


function-declarator


declarator(parameter-listopt)


parameter-list

identifier

identifier, parameter-list


function-body:


type-decl-list function-statement


function-statement


data-definition


externopt type-specifieropt init-declarator-listopt

staticopt type-specifieropt init-declarator-listopt


18. 5. Preprocesor

#define identifier token-string

#define identifier(identifier, , identifier)token-string

#undef identifier

#include 'filname'

#include <filname>

#if constant-expression

#ifdef identifier

#ifndef identifier

#else

#endif

#line constant identifier


biologie

botanica






Upload!

Trimite cercetarea ta!
Trimite si tu un document!
NU trimiteti referate, proiecte sau alte forme de lucrari stiintifice, lucrari pentru examenele de evaluare pe parcursul anilor de studiu, precum si lucrari de finalizare a studiilor universitare de licenta, masterat si/sau de doctorat. Aceste documente nu vor fi publicate.