Programare in C

download Programare in C

of 130

Transcript of Programare in C

  • 7/29/2019 Programare in C

    1/130

    Limbajul de programare C

    6.2. Limbajul de programare C

    6.2.1. Vocabularul limbajului. Caractere

    La scrierea programelorTURBO Cse folosete setul de caractere al codului ASCII.

    Caracterele din acest set se codific prin ntregi din intervalul [0,127]. Un astfel de ntreg

    poate fi pstrat n binar pe un octet (8 bii). Mulimea caracterelor poate fi mprit n trei

    grupe: caractere negrafice, spaiu i caractere grafice.

    Spaiulare codul 32. Caracterele negrafice, exceptnd caracterulDEL, care are codul

    ASCII127, au coduri ASCIImai mici dect 32. Caracterele grafice au codurile ASCIImai

    mari dect 32. n grupa caracterelor grafice distingem: litere mari, litere mici, cifre, caractere

    speciale.Literele mari i mici sunt cele ale alfabetului englez. Literele mari au codurile ASCII

    n intervalul [65,90]. Valoarea 65 este atribuit literei A, iar 90 literei Z. Celelalte valori

    corespund celorlalte litere n aa fel nct ordinea alfabetic a lor s induc ordinea cresctoare

    a codurilorASCII.

    n mod analog, literele mici au codurile ASCII n intervalul [97,122]. Cifrele 0-9 se

    codific prin codurileASCII48-57.

    Codul ASCII de valoare zero definete caracterul NUL. Acesta este un caracter

    impropriu i spre deosebire de celelalte caractere el nu poate fi generat de la tastatur i nu areefect nici la ieire. El poate fi utilizat pentru a termina un ir arbitrar de caractere deoarece nici

    un caracter de la intrare nu poate coincide cu el.

    Restul caracterelor negrafice au diferite funcii. Aa, de exemplu, codul ASCII 10

    realizeaz deplasarea cursorului n coloana 1 de la linia urmtoare, iar codul 13 deplaseaz

    cursorul n coloana ntia de pe aceeai linie. Caracterul cu codul ASCII10 se numete LF

    (Line Feed) iar caracterul cu codul ASCII13 se numete CR (Carriage Return). Cele dou

    caractere se pot introduce de la tastatur acionnd tasta Enter (numit i RETURN)

    obinndu-se caracterul de rnd nou (newline). Acest caracter are i o notaie special n

    limbajul C i anume el se noteaz prin: \n. Pentru tabulator se utilizeaz notaia: \t.Caracterele: spaiu, newline, tabulator orizontal le numim caractere sau spaii albe (white

    space).

    6.2.1.1. Identificatori (nume)

    Un identificator (nume), n limbajul C, este o succesiune de litere i eventual cifre,

    care ncepe cu o liter. n calitate de litere se folosesc litere mici i litere mari ale alfabetului

    englez, precum i caracterul de subliniere (_). Literele mici se consider distincte de cele

    134

  • 7/29/2019 Programare in C

    2/130

    Limbajul de programare C

    mari. Exemple corecte de identificatori: ecuatia_de_grad_doi, x1,x2, a, b, anul_I, _functie, A,

    XB. Exemplegreite de identificatori: 1_EM, 3_ut.

    6.2.1.2. Cuvinte cheie

    Un cuvnt cheie este un cuvnt mprumutat din limba englez, care are un neles

    predefinit. Cuvinte cheie se scriu cu litere mici n limbajul C.Un cuvnt cheie nu poate avea alt utilizare ntr-un program C dect cea care i-a fost

    predefinit. Fiind o succesiune de litere, un cuvnt cheie este totodat i un nume.

    Exemple: if while for break do

    Lista cuvintelor cheie este dat n anexa I.

    Sensul fiecrui cuvnt cheie va rezulta la definirea construciei n care se utilizeaz.

    6.2.1.3. Tipurile de baz din limbajul C

    Un program n limbajul C, ca de altfel n orice limbaj de programare, realizeaz osuccesiune de prelucrri asupra unor date. Datele sunt diferite funie de natura (tipul) lor.

    n limbajul Cdistingem cteva tipuri predefinite de date, pe care le numim tipuri de

    baz. n afara acestor tipuri utilizatorul i poate defini tipuri noi funcie de specificul datelor

    problemei pe care o are de rezolvat.

    n tabelul 6.1 de mai jos se indic tipurile de baz din limbajul TURBO C.

    Tabelul 6.1.

    Cuvnt

    cheie

    Lungime

    n bii

    Tip de reprezentare intern

    int 16 ntreg binar reprezentat prin complement fa de 2 pe 2 octei

    short 16 idem

    long 32 ntreg binar reprezentat prin complement fa de 2 pe 4 octei

    unsigned 16 ntreg binar fr semn

    char 8 caracter reprezentat prin cod ASCII

    float 32 numr reprezentat n virgul flotant n simpl precizie

    double 64 numr reprezentat n virgul flotant n dubl precizie

    long double 80 numr reprezentat n virgul flotant n dubl precizie

    Datele de tip int(ntregi cu semn) aparin intervalului [-32768, 32767]. Datele de tip

    long(ntregi cu semn n dubl precizie) aparin intervalului [-231, 331]. Datele de tip unsingned

    (ntregi fr semn) aparin intervalului [0,65535]. Datele de tip char au valori n intervalul

    [0,255] sau [-128,127]. Se pot utiliza ntregi fr semn n dubl lungime folosind succesiunea

    de cuvinte cheie: unsigned long. O dat flotant n simpl precizie de tipfloat, difer de zero,

    135

  • 7/29/2019 Programare in C

    3/130

    Limbajul de programare C

    are valoarea absolut n intervalul [3.4*10-38, 3.4*1038]. O dat flotant n dubl precizie de tip

    double, long double n intervalul [3.4*10-4932, 1.1*104932].

    6.2.1.4. Constante

    O contant are o valoare i un tip. Att tipul ct i valoarea unei constante se definescprin caracterele care compun constanta respectiv.

    a) Constante ntregi

    O constant ntreag poate fi un ir de cifre, care eventual este precedat de un semn. O

    constant ntreag se reprezint prin complement fa de 2 pe 16 bii sau chiar 32 de bii dac

    nu ncape pe 16 bii. n cazul n care dorim ca o constant ntreag s fie reprezentat pe 32 de

    bii, chiar dac ea se poate reprezenta pe 16 bii, vom termina constanta respectiv prin L sau l.

    n felul acesta, se impune tipul longpentru constanta respectiv.

    O constant ntreag, precedat de un zero nesemnificati, se consider scris nsistemul de numeraie cu baza 8. De asemenea, o constant ntreag care ncepe cu 0x sau 0X

    (zero urmat de litera x mic sau mare) se consider scris n sistemul de numeraie cu baza 16.

    n rest se consider c baza de numeraie este 10.

    Exemple de reprezentri sunt artate n tabelul 6.2.

    Tabelul 6.2.

    Repreze

    ntare

    Lungimea

    reprezentriiLungime de reprezentare intern

    31645 16 bii ntreg zecimal reprezentat n binar prin complement fa de 2

    -12345 16 bii ntreg zecimal reprezentat n binar prin complement fa de 2

    12345L 32 bii ntreg zecimal reprezentat n binar prin complement fa de 2

    012345 16 biintreg octal reprezentat n binar

    (o cifr octal se reprezint pe 3 bii)

    0xa12b 16 biintreg hexazecimal reprezentat n binar

    (o cifr hexazecimal se reprezint pe 4 bii)

    923456 32 bii ntreg zecimal reprezentat n binar prin complement fa de 2

    b) Constant flotant (real)

    O constant flotant este un numr raional care se compune din:

    - un semn care poate i lipsi n cazul unui numr nenegativ;

    - o parte ntreag care poate fi i vid;

    - o parte fracionar care poate fi i vid;

    - un exponent care poate fi i vid;

    136

  • 7/29/2019 Programare in C

    4/130

    Limbajul de programare C

    Exemple:

    7125.34 -49.0 85. 367e-2 .3789 -.128 4.3E20 -.29e+15

    c) Constant caracter

    O constant caracter reprezint un caracter i are ca valoare codul ASCII al

    caracterului respectiv. O constant caracter grafic se poate scrie incluznd caracterul

    respectiv ntre caractere apostrof.

    Anumite caractere negrafice au notaii speciale la scrierea crora se utilizeaz

    caracterul backslash (\). Aa, de exemplu, am vzut c pentru caracterul tabulator orizontal

    folosim notaia: \t.

    O astfel de constant caracterse va scrie incluznd notaia respectiv ntre caractere

    apostrof. Deci constanta caractertabulator orizontalse va scrie: \t

    n mod analog, constanta caracter de rnd nou (newline) se va scrie: \n

    Alte constante caracter care au notaii consacrate sunt prezentate n tabelul 6.3:Tabelul 6.3

    CaracterReprezentare prin constant

    caracterValoare

    revenire cu o poziie (backspace) \b 8

    retur de car \r 13

    salt de pagin la imprimant \f 12

    Caracterul backslash poate fi folosit pentru a reprezenta nsui constanta caracterapostrof sau chiarbackslash. Astfel:

    \ - reprezint constanta caracterapostrof;

    \\ - reprezint constanta backslash.

    d) Constant ir sau ir de caractere

    O constant ir este o succesiune de zero sau mai multe caractere delimitate prin

    ghilimele. Ghilimelele nu fac parte din irul de caractere. Dac dorim s folosim caractere

    negrafice n compunerea unui ir de caractere, atunci putem folosi convenia de utilizare a

    caracterului backslash indicat mai sus. n particular, dac ntr-un ir de caractere dorim s

    reprezentm chiar caracterul ghilimele, atunci vom scrie: \. De asemenea, nsui caracterul

    backslash se va scrie: \\.

    6.2.1.5. Variabile simple

    Prin variabil nelegem o dat a crei valoare se poate schimba n timpul executrii

    programului care o conine.

    137

  • 7/29/2019 Programare in C

    5/130

    Limbajul de programare C

    Unei variabile i se ataeaz un nume prin intermediul cruia putem referi sau chiar

    modifica valoarea variabilei respective. Valorile pe care le poate avea o variabil trebuiesc s

    aparin unui acelai tip. De aceea, unei variabile i corespunde un tip.

    Corespondena ntre numele i tipul unei variabile se realizeaz printr-o construcie

    special numit declaraie.Sintaxa unei declaraiin limbajul Ceste urmtoarea:

    nume_tip lista_de_variabile;

    Exemple:

    int i,k,x; - i,kixsunt variabile de tip int(ele pot avea ca valori ntregi binari

    reprezentai prin complement fa de 2 pe 16 bii);

    float a,b; - a i b sunt variabile de tip float (valorile lor sunt reprezentate n

    format flotant simpl precizie pe 32 de bii);

    char c; - c este o variabil de tip char(valorile ei sunt ntregi din intervalul

    [0,255] sau [-128, 127]).

    6.2.1.6. Comentarii

    n limbajul C un comentariu ncepe prin succesiunea de caractere: /* i se termin

    prin: */.

    Se pot aduga comentarii pe o singur linie precedate de o succesiune de dou

    caractere /.

    6.2.2. Expresii

    6.2.2.1. Structura expresiilor n limbajul C

    O expresie n limbajul Cse compune dintr-un operand sau mai muli operanzi legai

    prin operatori.

    O expresie are o valoare i un tip care se determin aplicnd operatorii prezeni

    conform prioritilor i asociativitii acestora.

    n limbajul Coperatorii se asociaz de la stnga la dreapta, exceptnd operatorii unari,

    condiionali i de atribuire, care se asociaz de la dreapta la stnga.ntr-o expresie pot fi folosite parantezele rotunde pentru a impune o anumit ordine n

    executarea operaiilor.

    Operatorii limbajului Cpot fi grupai n mai multe clase. Cu toate acestea ei pot fi

    utilizai mpreun ntr-o aceeai expresie.

    6.2.2.2. Operatorii aritmetici

    Acetia sunt:

    138

  • 7/29/2019 Programare in C

    6/130

  • 7/29/2019 Programare in C

    7/130

    Limbajul de programare C

    ! (negaia logic operator unar);

    && (Ilogic); (SAUlogic).Operatorul ! are aceeai prioritate cu operatorii unari + i -. De altfel toi

    operatorii unari au aceeai prioritate n limbajul C.

    Operatorul && (Ilogic) este mai prioritar dect operatorul (SAUlogic), darare o prioritate mai mic dect operatorii de egalitate.

    n limbajul C nu exist valori logice speciale. Valoarea fals se reprezint prin zero.

    Orice valoare diferit de zero reprezint valoarea adevrat.

    Operatorii logici se evalueaz de la stnga la dreapta. Dac la evaluarea unei expresii

    se ajunge ntr-un punct n care se cunoate valoarea ntregii expresii, atunci restul expresiei nu

    se mai evalueaz.

    Exemplu:

    an%4= = 0 && an% 100! = 0 || an% 400 = = 0.

    Variabila an, din expresia de mai sus, are valoarea unui ntreg ce reprezint un an

    calendaristic. Expresia are valoarea 1 dac anul reprezentat prin valoarea variabilei an este

    bisect i zero n caz contrar.

    ntr-adevr, un an este bisect dac are loc una din urmtoarele condiii:

    a) anul este multiplu de 4 i nu este multiplu de 100; sau

    b) este multiplu de 400.

    Condiia a) se exprim prin: multiplu de 4: an%4 = = 0

    i: &&nu e multiplu de 100: an%100! = 0

    Condiia b) se exprim prin: multiplu de 400: an%400 = = 0

    n final cele dou condiii se leag prin operatorul || (SAU) i n felul acesta se obine

    expresia cerut.

    6.2.2.6. Operatori logici pe bii

    Acetia, n ordine descresctoare a prioritii lor sunt:

    ~ (operator unar; complement fa de unu)

    > (deplasri)

    & (Ipe bii)

    ^ (SAU-EXCLUSIVpe bii)

    | (SAUpe bii)

    Operatorul ~are ca effect inversarea tuturor biilor: biii care iniial au avut valoarea 1

    vor deveni 0, iar cei care au avut valoarea 0 vor deveni 1.

    Operatorul

  • 7/29/2019 Programare in C

    8/130

  • 7/29/2019 Programare in C

    9/130

  • 7/29/2019 Programare in C

    10/130

    Limbajul de programare C

    Construciile de mai jos sunt eronate:

    x%=y - operatorul % nu se poate aplica la operanzi care nu sunt

    ntregi.

    i=j - construcia op= implic un operator binar;x=i+(j*(k-y)+2.3 - lipsete o parantez nchis;

    y=3(x-10) - lipsete operatorul * dup 3.

    6.2.2.8. Operatori de incrementare i decrementare

    Aceti operatori sunt unari i deci au aceeai prioritate cu ceilali operatori unari din

    limbajul C. Operatorul de incrementare se noteaz prin ++, iar cel de decrementare prin

    --.

    Operatorul de incrementare mrete valoarea operandului su cu unu, iar cel de

    decrementare micoreaz valoarea operandului cu unu. Operatorii pot fi astfel :

    prefixai: ++ operand -- operandpostfixai: operand ++ operand --

    n cazul n care sunt folosii prefixai, ei se aplic nti i apoi se folosete valoarea

    operandului la care s-a aplicat. Cnd sunt postfixai, se folosete valoarea operandului

    nemodificat de operatorul respectiv, apoi se aplic.

    Exemple:

    Dacxare valoarea 3, atunci n atribuireay= ++xluiy i se atribuie valoarea 4 deoarece

    nti s-a incrementatxi apoi s-a folosit valoareax. n schimb, dac folosim atribuireay=x++,

    pentru aceeai valoare a lui x, atunci lui y i se atribuie valoarea 3. n ambele cazuri x se

    mrete cu 1. Diferena const numai n valoarea atribuit: n primul caz ( operator prefixat),

    se atribuie valoarea incrementat, iar n al doilea caz (operator postfixat), se atribuie valoarea

    neincrementat.

    Menionm c aceti operatori se pot aplica numai la urmtorii operanzi: variabil

    simpl cu indici, referire la elementul unei structuri(structurile vor fi definite mai trziu).

    Exemple:

    int i,j; double x,y;

    j=i++ - este echivalent cu atribuirile j=i; i=i+1;

    y= -- x - este echivalent cu secvena de atribuire: x=x-1; y=x;x=tab[3]-- - este echivalent cu: x= tab[3]; tab[3]=tab[3]-1;

    i=++tab[j+1] - este echivalent cu: tab[j+1]=tab[j+1]+1; i=tab[j+1];

    x=tab[++j] - este echivalent cu: j=j+1; x= tab[j];

    x = tab[i--] - este echivalent cu: x=tab[i]; i=i-1;

    y=++i-j - este echivalent cu: i=i+1;y=i-j;

    y=i++-j - este echivalent cu: y=i-j; i=i+1;

    Construciile urmtoare sunt eronate:

    y=(i-j)++ - operatorul ++ nu se poate aplica expresiei i-j;

    143

  • 7/29/2019 Programare in C

    11/130

    Limbajul de programare C

    x= --(i-j) - operatorul nu se poate aplica expresiei i-j;

    i=j- - - - - nu mai reprezint operatorul de decrementare.

    6.2.2.9. Operatorul de conversie explicit (operatorul cast)

    Adesea dorim s form tipul unui operand sau chiar al unei expresii. Acest lucru este

    posibil folosind o construcie de forma: (tip) operand.

    Prin aceasta, valoarea operandului se convertete spre tipul indicat n paranteze.

    Exemplu:

    int x,y;double z;

    Fie x = 10 i y = 4, valorile lui x i respectiv y. Atunci n urma atribuirii: z = x/y, z

    primete valoarea 2 deoarece 10/4 d ctul 2 (mprirea dintre operanzi ntregi are ca

    rezultat ctul ntreg). n schimb, dac vom converti cei doi operanzi spre tipul double,

    atunci mprirea nu mai este ntreag i rezultatul va fi 2,5. O astfel de conversie areforma:

    z = (double)x/y

    n expresiile de mai sus, construcia (tip) este un operator unar prin care se expliciteaz

    conversia dorit. El are aceeai prioritate ca restul operatorilor unari, iar expresia

    (tip)operandse numete expresie cast.

    6.2.2.10. Operatorul dimensiune (sizeof)

    Lungimea n octei a unei date se poate determin folosind o construcie de forma:

    sizeof(data) unde data este numele unei variabile simple, al unui tablou, al unei structuri, alunui tip sau referirea la elementul unui tablou sau structur. Sizeof este operatorul unar

    dimensiune i are aceeai prioritate ca ceilali operatori unari. n expresia de mai sus,

    parantezele rotunde sunt obligatorii numai n cazul n care data este numele unui tip.

    Exemple:

    int i; float x; double d; char c; int tab[10]; double dtab[10];

    sizeof(i) sau sizeof i - are valoarea 2;

    sizeof(x) sau sizeof x - are valoarea 4;

    sizeof(float) - are valoarea 4;sizeof(d) sau sizeof d - are valoarea 8;

    sizeof(double) - are valoarea 8;

    sizeof(c) sau sizeof c - are valoarea 1;

    sizeof(tab[i]) sau sizeof tab[i] - are valoarea 2;

    sizeof(tab) sau sizeof tab - are valoarea 20;

    sizeof(dtab) sau sizeof dtab - are valoarea 80.

    6.2.2.11. Regula conversiilor implicite

    144

  • 7/29/2019 Programare in C

    12/130

    Limbajul de programare C

    O expresie poate conine operanzi de tipuri diferite. Nu exist restricii n acest sens.

    Astfel, de exemplu ntr-o expresie se pot folosi operanzi de tip char. Acetia se convertesc n

    mod automatspre tipul int, nainte de a face operaii cu ei.

    Dac operanzii unui operator binar sunt de acelai tip, se aplic operatorul asupra

    operanzilor respectivi, iar tipul rezultatului este acelai cu al operanzilor. n caz contrar

    sunt necesare conversii care se execut n mod automat, conform regulii de mai jos

    (regula conversiilor implicite):

    1.Fiecare operand de tip charse convertete spre tipul int;

    2.Dac unul dintre operanzi este de tip long double, atunci cellalt operand se

    convertete spre tipul long double i rezultatul va avea tipul long double;

    3.Dac unul dintre operanzi este de tip double, atunci cellalt operand se convertete

    spre tipul double i rezultatul va avea tipul double;

    4.Dac unul dintre operanzi este de tipfloat, atunci cellalt operand se convertete spretipulfloati rezultatul va avea tipulfloat;

    5.Dac unul dintre operanzi este de tip long, atunci cellalt operand se convertete spre

    tipul longi rezultatul va avea tipul long;

    6.Dac unul dintre operanzi este de tip unsigned, atunci cellalt operand se convertete

    spre tipul unsignedi rezultatul va avea tipul unsigned;

    7.Dac unul dintre operanzi este de tip int, atunci cellalt operand se convertete spre

    tipul inti rezultatul va avea tipul int;

    Exemple:

    int i,j,k; float a,b; double x,y;unsigned p; long r; char c;

    Valorile diferitelor expresii sunt prezentate n tabelul 6.3.

    Tabelul 6.3.

    Expresii Conversii Tipul expresieii+j/k - inta/b - float

    x+y - doublei+a i spre float float

    i-3.5 i spre double doublei+5 - inti+32767 - int

    i+x i spre double doublei-c c spre int int

    x+100 100 spre double doublep-20 20 spre unsingned unsignedr*5 5 spre long longi*31 - int

    (long)i*3 i spre long, 3 spre long long(double)i/j i spre double, j spre double double

    145

  • 7/29/2019 Programare in C

    13/130

    Limbajul de programare C

    (double)(i/j)

    se realizeaz mprirea ntreag

    ntre i i j i rezultatul se

    convertete spre double.

    double

    6.2.2.12. Operatori condiionali

    Operatorii condiionalise utilizeaz n evaluri de expresiicare prezint alternative.

    O astfel de expresie are formatul: exp1? exp2:exp3 unde exp1, exp2 i exp3 sunt

    expresii.

    O astfel de expresie se evalueaz n felul urmtor:

    1.Se evalueaz expresia exp1;

    2.Dac exp1 este diferit de zero, atunci valoarea i tipulexpresiei condiionale este

    egal cu expresia exp2, altfel cu expresia exp3.

    Operatorii condiionali sunt ? i :. Ei trebuie s fie folosii mpreun, adic operatorul

    ? Trebuie s aib un corespondent : i numai unul.Ei au prioritatea imediat mai mic dect operatorul logic SAU(||) i imediat mai mare

    dect operatorii de atribuire.

    Exemple:

    1. y?x/y:x*x

    n acest exemplu, exp1 estey, exp2 estex/y iarexp3 estex*x.

    Expresia se evalueaz astfel: dac y este diferit de zero atunci rezultatul este valoarea

    i tipulexpresieix/y, altfel este valoarea i tipulexpresieix*x.

    O expresie condiional este un caz particular de expresie i deci este legal i

    urmtoarea expresie de atribuire:z=y?x/y:x*x.

    Aceast expresie exprim un proces de calcul pe care l putem descrie n pseudocod,

    astfel:

    dac y 0 atunci z x/y

    altfel z x*x

    2. Determinarea maximului dintre dou numere a i b.

    dac a>b atunci max a

    altfel max b

    Expresia corespunztoare din limbajul Cva fi:

    max = (a > b)?a : b

    n acest exemplu: exp1 este a > b, exp2 este a, iarexp3 este b.

    6.2.2.13. Operatorul virgul

    146

  • 7/29/2019 Programare in C

    14/130

    Limbajul de programare C

    Exist cazuri n care este util s grupm mai multe expresii ntr-una singur, expresii

    care s se evalueze succesiv.

    n acest scop se folosete operatorul virgul, care separ secvena de expresii, acestea

    grupndu-se ntr-o singur expresie.

    Operatorul virgul are cea mai mic prioritate dintre toi operatorii limbajului C.

    Prioritatea lui este imediat mai mic dect a operatorilor de atribuire.

    Cu ajutorul lui construim expresii de forma: exp1, exp2,,expn .

    Aceast expresie, ca oricare alta, are o valoare i un tip. Att valoarea, ct i tipul

    ntregii expresii coincide cu valoarea i tipul lui expn deci cu a ultimei expresii.

    Exemple:

    ++i,--j - i se mrete cu o unitate, apoi j se micoreaz cu o

    unitate; valoarea i tipul ntregii expresii coincid cu ale luij;

    k=(x=10,y=2*i-5,z=3*j,i+j) - se execut pe rnd cele 3 atribuiri, apoi se efectueazsuma i+jcare se atribuie lui k.

    Amintim c toi operatorii se asociaz de la stnga la dreapta, exceptnd cei unari,

    condiionali i de atribuire care se asociaz de la dreapta la stnga. n tabelul 6.4 sunt

    prezentate prioritile operatorilor.

    Tabelul 6.4

    ( ) [ ] .-(unar) +(unar) *(unar) &(unar) ! ++ -- (tip) sizeof

    * / %+ -

    >< = >

    = = ! =&^

    &&

    ? :

    = op= op poate fi: (binar) / % +(binar) -(binar) >>

  • 7/29/2019 Programare in C

    15/130

    Limbajul de programare C

    6.3. Structura programelor C

    6.3.1. Structura unui program n limbajul C

    Un program n limbajul Cse compune din una sau mai multe funcii. Dintre acestea

    una este funcia principal. Funcia principal definete adresa de lansare a programului. Un

    program n Cse lanseaz cu prima instruciune a funciei principale.

    Fiecare funcie are un nume. Funcia principal are numele main.

    6.3.2. Structura unei funcii

    n limbajul Cexist dou feluri de funcii: funcii care returneaz o valoarei funcii

    care nu returneaz o valoarela revenirea din ele.Structura unei funciieste urmtoarea:

    tip nume (lista parametrilor formali)

    {

    declaraii de variabile locale

    instruciuni

    }

    unde:

    - tip definete tipul valorii returnate de funcie i este un cuvnt cheie pentru tipurile de

    baz. Dac funcia nu returneaz nici o valoare, se poate utiliza cuvntul cheie void. Dac tip

    este absent, se presupune c funcia sau nu returneaz nici o valoare sau returneaz o valoare

    de tip int. Se recomand ca utilizatorul s indice totodat tipul deoarece absena lui constituie

    o surs potenial de erori.- lista_parametrilor_formali este fie vid, fie conine declaraiile parametrilor formali

    separate prin virgul.

    Menionm c parantezele rotunde sunt prezente chiar i atunci cnd lista

    parametrilor formali este vid.

    6.4. Preprocesare

    Un program n limbajul C poate fi prelucrat nainte de a fi compilat . O astfel de

    prelucrare se numetepreprocesare.

    Prin preprocesare se pot realiza:

    - includeri de texte;

    - definiii i apeluri de macrouri simple;

    - compilare condiionat;

    6.4.1. Includerea unui fiier surs

    148

  • 7/29/2019 Programare in C

    16/130

    Limbajul de programare C

    Fiierele surs pot fi incluse cu ajutorul construciei #include. Aceast construcie are

    una din urmtoarele formate:

    #include specificator_de_fiier sau

    #include

    unde:

    - specificator_de_fiier trebuie s fie un nume de fiier valid din punct de vedere alsistemului de operareDOS, care poate avea o extensie (.h, .cetc.) i opional o

    cale. Diferena dintre cele dou formate const n algoritmul de cutare al

    fiierului care se include.

    Astfel, varianta specific includerea unui fiier standard, care este cutat de

    obicei n directorulINCLUDE.

    n cazul n care se utilizeaz caracterele ghilimele, utilizatorul furnizeaz fiierul care

    se include. Acest fiier va fi cutat n directorul curent sau ntr-un director precizat.

    Un fiier standard care trebuie inclus frecvent este fiierul stdio.h. Includerile defiiere, de obicei, se fac la nceputul fiierului surs. n felul acesta datele coninute n el se pot

    utiliza n tot fiierul surs. De aceea, la nceputul fiierelor surs vom ntlni mai multe

    includeri de fiiere, printre care de obicei se va afla i fiierul stdio.h: #include .

    Un exemplu de nchidere a unui fiier utilizator este: #include mouse.h.

    6.4.2. Constante simbolice

    O alt construcie tratat de procesor este construcia define. Un format simplu al

    acestei construcii este urmtorul:

    #define nume succesiune_de_caractere.

    O constant simbolic este definit din punctul apariiei construciei define

    corespunztoare ei i pn la sfritul fiierului surs respectiv sau pn la redefinirea sau

    anihilarea ei prin intermediul construciei #undef.

    Exemplu: #define A 100

    6.5. Intrri/ieiri standard

    Operaiile de intrare/ieire se realizeaz prin apeluri de funcii. Datele de

    intrare/ieire se presupune c sunt organizate nfiiere.

    Unui programBORLAND C i se ataeaz n mod automat urmtoarele fiiere:

    - stdin - intrare standard;

    - stdout - ieire standard;

    - stderr - ieire standard pentru erori;

    - stdprn - ieire standard pentru imprimant;

    - stdaux - intrare/ieire serial.

    149

  • 7/29/2019 Programare in C

    17/130

    Limbajul de programare C

    6.5.1. Funcia standard printf

    Funcia de bibliotecprintfrealizeaz ieiri cu format. Sintaxa funciei este:

    printf(control, par1, par2,parn),

    unde controleste un ir de caractere care conine texte de scris, specificatori de format pentru

    datele care se scriu, iarpar1, par2,parn sunt expresii ale cror valori se scriu conform

    specificatorilor de format prezentai n parametrul de control.

    Un specificator de format ncepe cu un caracter procent (%). n continuare, ntr-un

    specificator de format mai putem avea:

    1.Un caracter- opional: implicit, datele se aliniaz n dreapta cmpului n care se

    scriu. Atunci cnd caracterul - este prezent, data corespunztoare este ncadrat la stnga.

    2.Un ir de cifre zecimale opionale, care definete dimensiunea minim a cmpului

    afectat datei respective.3.Un punct opional, urmat de unir de cifre zecimal. irul de cifre zecimal aflat dup

    punct defineteprecizia datei care se scrie sub controlul specificatorului respectiv.

    4.Una sau dou litere, care definesc tipul de conversie aplicatdatei care se scrie. n

    cazul n care specificatorul de format conine dou litere, prima poate fi l.

    n tabelul 6.5 sunt prezentate intrrile/ieirile standard utilizate n limbajul C.

    Tabelul 6.5.

    Litera Conversia realizat

    ddata se convertete din tipul intizecimali se scriu la ieire caracterele zecimale

    ale ei, eventual precedate de semnul -, dac este negativ.o data se convertete din tipul intn octali se scriu la ieire caracterele ei octale;

    xdata se convertete din tipul intn hexazecimali se scriu la ieire caracterele ei

    hexazecimale; cifrele peste 9 se scriu cu literele mici (a-f);X ca i n cazul literei x, dar se vor folosi literele mari (A-F);u data se convertete din tipul usingnednzecimal ntreg fr semn;

    cvaloarea parametrului care i corespunde se consider c reprezint codul ASCIIal

    unui caracteri se scrie caracterul respectiv;

    sparametrul care-i corespunde se scrie ca un ir de caractere; se consider c irul se

    termin la ntlnirea caracteruluiNUL (\0);

    f

    valoarea parametrului care-i corespunde se convertete din tipfloatsau double n

    formatul: dd ...d.ddd(d reprezint o cifr zecimal), unde numrul de cifre dup

    punctul zecimal este fie cel indicat de precizie specificatorului de format, fie este

    egal cu 6; partea ntreag este precedat de semnul minus dac numrul este negativ;

    e

    conversia se realizeaz de tipulfloatsau double n formatul:

    d.dd..dedddunde numrul cifrelor de dup punctul zecimal este dat de preciziaspecificatorului de format sau este egal cu 6, dac acesta este absent; partea ntreag

    este precedat de minus dac numrul este negativ;

    150

  • 7/29/2019 Programare in C

    18/130

    Limbajul de programare C

    E

    ca i n cazul literei e cu deosebirea c litera e se schimb cu literaE:

    d.dd..dEdddn ambele cazuri, la exponent se va scrie una, dou sau trei cifre, nfuncie de valoarea numrului;

    g

    se aplic una din conversiile definite de literelefsau e, alegndu-se aceea care se

    reprezint pe un numr minim de caractere; de asemenea, zerourile de la sfritul

    prii fracionare se omit;G ca igcu singura deosebire c se utilizeazEn loc de e.

    Funcia printf returneaz lungimea total n octei a datelor scrise la terminal sau

    valoarea simbolic EOF n caz de eroare. EOFeste o constant simbolic definit n fiierul

    stdio.h. Ea este definit astfel: #define EOF 1.

    Exemple:

    Fie declaraiile: int i,j; float a; double x; int c; long k;

    i = 558 a = 47.389 x = -123.5e20 c = x j = -123 k = 45678

    Mai jos apelm funciaprintfcu diferii specificatori de format care permit afiarea laterminal a valorilor acestor variabile. n tabelul 6.6sunt prezentate rezultatele afiate n cazul

    apelrii funcieiprintf:

    Tabelul 6.6.

    Nr.crt. Apelul funciei printf Afiri

    1. printf (i=%d\n,i); i = 5582. printf (i=%2d\n,i); i = 5583. printf (i=%5d\n,i); i = 5584. printf (i=%o\n,i); i = 1056

    5. printf (i=%x\n,i); i = 22e6. printf (j=%d\n,j); j = -1237. printf (a=%.3f\n,a); a = 47.3898. printf (a=%.2f\n,a); a = 47.399. printf (x=%e\n,x); x = -1.235000e+22

    10. printf (c=%c,cod = %d\n,c,c); c = x, cod = 12011. printf (k=%ld\n,k); k =45678

    6.5.2. Funcia standard scanf

    Funcia bibliotec scanf realizeaz intrri cu format de la intrarea standard stdin

    (intrare de la terminalul de la care s-a lansat programul). Ea poate fi apelat printr-o

    instruciune de apel de forma:

    scanf(control, par1, par2, .., parn);

    Ca i n cazul funciei printf, parametrul control este delimitat de ghilimele i poate

    conine texte i specificatori de format.

    Caracterele albe din parametrul de control sunt neglijate.

    - parametrii par1, par2, .., parn definesc zonele receptoare ale datelor citite prin

    intermediul funciei scanf. Fiecare dintre ei reprezint adresa unei zone receptoare.

    151

  • 7/29/2019 Programare in C

    19/130

    Limbajul de programare C

    Acest lucru se indic, n limbajul C, printr-o construcie de forma: &nume care

    determin adresa zonei de memorie rezervat variabilei num. Caracterul&, din

    construcia de mai sus, reprezint un operator unar, numit operatorul adres. El

    are aceeai prioritate ca i ceilali operatori unari din limbajul C.

    Funciascanf

    citete toate cmpurile care corespund specificatorilor de format i

    eventual textelor scrise n parametrul de control. n cazul unei erori, citirea se ntrerupe n

    locul n care s-a ntlnit eroarea. La revenirea din ea funcia scanf returneaz numrul

    cmpurilor citite corect.

    Exemplul 1:

    voidmain () /* citete un intreg de 4 cifre i scrie cifrele

    respective precedate fiecare de cte un spaiu */

    {

    intcif1, cif2, cif3, cif4;

    scanf (%1d%1d%1d%1d, &cif1, &cif2, &cif3, &cif4);

    printf(%2d%2d%2d%2d\n, cif1, cif2, cif3, cif4);

    }

    Exemplul 2:

    Programul urmtor citete o dat calendaristic scris sub forma: zzllaaaa

    zz - ziua cu 2 cifre;

    ll - luna cu 2 cifre;

    aaaa - anul cu 4 cifre.

    apoi se scrie data respectiv permutnd anul cu ziua, astfel nct dac la intrare se citete, spreexemplu, 01031992, la ieire se va obine 19920301.

    voidmain () /* citete zzllaaaa i rescrie aaaallzz */

    {

    intziua, luna, anul;

    scanf (%2d%2d%4d, &ziua, &luna, &anul);

    printf(%4d%02d%02d\n, anul, luna, ziua);

    }

    Exemplul 3:

    #define MAX 50

    voidmain () /* citete nume, prenume i data naterii i rescrie datele respective astfel:

    linia 1: nume prenume

    linia 2: zi luna an */

    { intziua, luna, an;

    char nume [MAX+1], prenume [MAX+1];

    scanf (%50s%50s%d%d%d, nume, prenume, &zi, &luna, &an);

    152

  • 7/29/2019 Programare in C

    20/130

    Limbajul de programare C

    printf(%s%s\n, nume, prenume);

    printf(%d %d %d\n, zi, luna, an);

    }

    Exemplu de linie de intrare: Popescu Ion 1 9 1991

    6.5.3. Funcia standard putchar

    Funcia standardputcharse poate utiliza pentru a scrie un caracter n fiierul standard

    de ieirestdout, n poziia curent a cursorului.

    Exemple:

    1) putchar(A);

    - se scrie caracterul A n fiierul de ieire n poziia curent a cursorului;

    2) putchar(A+10);

    - se scrie caracterul de cod A+10 = 65+10=75, adic literaK;

    3) putchar(\n);- se scrie caracterul de rnd nou (newline). Aceasta are ca efect deplasarea

    cursorului n coloana 1 din linia urmtoare.

    6.5.4. Funcia standard getchar

    Aceast funcie citete de la intrarea standard (fiierul standard stdin) caracterul curent

    i returneaz codul ASCIIal caracterului citit. Tipul valorii returnate este int. La ntlnirea

    sfritului de fiier (^Z) se returneaz valoareaEOF.

    Funciagetcharpoate fi apelat printr-o instruciune de forma:getchar()

    sau utiliznd-o ca operand ntr-o expresie. Folosind expresia de atribuire:

    c =getchar ()

    se citete caracterul curent de la intrare.

    6.5.5. Funciile standard getch i getche

    Funcia getche citete de la intrarea standard caracterul curent i returneaz codul

    ASCII al caracterului citit. Spre deosebire de getchar, aceast funcie are acces direct lacaracter, de ndat ce acesta a fost tastat. Se apeleaz la fel ca i getchar, adic fie printr-o

    instruciune de apel de forma:getche ();

    Funcia getch este similar cu funcia getche cu singura deosebire c citirea se face

    fr ecou (caracterul tastat nu se afieaz la terminal i nici cursorul nu se deplaseaz). Ea se

    apeleaz n acelai mod ca i funciagetche.

    6.5.6. Funciile standard gets i puts

    153

  • 7/29/2019 Programare in C

    21/130

    Limbajul de programare C

    Pentru a introduce de la terminal un ir de caractere se poate folosi funcia gets. Ea

    permite citirea cu ecou a caracterelor coduluiASCII.

    Funciagets are ca parametru adresa de nceput a zonei n care se pstreaz caracterele

    citite. De obicei, aceast zon de memorie poate fi zona alocat unui tablou de tip char.

    Funciagets

    returneaz adresa de nceput a zonei n care s-au pstrat caracterele sau

    zero n cazul n care s-a ntlnit sfritul (^Z).

    Exemplu:

    char t[255]; gets(t);

    La acest apel se citesc caracterele tastate pe un rnd i se pstreaz n tabloul t.

    Caracterul tastat nainte de a aciona tasta ENTER este urmat n tabloul tde caracterulNUL,

    iar la revenirea din funcie se returneaz adresa zonei receptoare adic valoarea lui t.

    Funcia puts realizeaz operaia invers fa de funciagets. Ea afieaz la terminal

    caracterele irului de caractere ASCII aflate ntr-o zon de memorie. Adresa de nceput a

    acestei zone de memorie este parametrul funcieiputs.Exemplu:

    char t[255]; gets(t); puts(t);

    Se d funciay(x) definit ca mai jos:

    ( )

    +

  • 7/29/2019 Programare in C

    22/130

  • 7/29/2019 Programare in C

    23/130

    Limbajul de programare C

    ( )

    >+

    =

  • 7/29/2019 Programare in C

    24/130

    Limbajul de programare C

    f = f*i;

    i++;}

    printf(n = %d,n! = %g\n, n,f);

    }

    Observaie:Instruciunile din corpul ciclului while:

    f = f*i;

    i++;

    pot fi nlocuite cu una singur:f*=i++; Deci ciclul while se poate scrie mai compact astfel:

    while(i max) max = i;

    printf(max = %d\n, max);

    }

    6.6.5. Instruciunea FOR

    Instruciunea for, ca i instruciunea while, realizeaz o structur repetitivcondiionat anterior. Este folosit pentru repetarea operaiilor n care se cunoate numrul de

    pai i dup o condiie. Formatul instruciunii este:

    for(exp1; exp2; exp3) instruciune

    unde exp1, exp2, exp3 sunt expresii.

    Antetulciclului este definit de:for(exp1; exp2; exp3)

    Instruciunea care se execut repetat formeaz corpulciclului, exp1 constituie partea de

    iniializare a ciclului, exp2 este partea de reiniializare a lui, iarexp3 reprezint condiia de

    continuare a ciclului. De obicei, exp1 i exp3 reprezint atribuiri.Instruciuneaforse execut conform urmtorilor pai:

    1.Se execut secvena de iniializare definit de expresia exp1.

    2.Se evalueaz exp2. Dac exp2 are valoarea zero, atunci se iese din ciclu. Altfel se

    execut instruciunea din corpul ciclului.

    3.Se execut secvena de reiniializare definit de exp3, apoi se reia de la pasul 2.

    Echivalena dintre instruciunile while iforeste sintetizat astfel:

    exp1;

    while (exp2)

    157

  • 7/29/2019 Programare in C

    25/130

    Limbajul de programare C

    {

    instruciune

    exp3;

    }

    Un exemplu foarte simplu de ciclu cu pas este nsumarea elementelor unui tablou.s = 0;

    for(i=0; i

  • 7/29/2019 Programare in C

    26/130

  • 7/29/2019 Programare in C

    27/130

    Limbajul de programare C

    Aceast instruciune realizeaz structura repetitiv condiionat posterior. Aceast

    structur nu este obligatorie pentru a scrie programe, ea putndu-se realiza prin celelalte

    structuri. Are urmtorul format:

    do

    instruciunewhile (expresie);

    Aceasta, la rndul ei, poate fi scris printr-o secven n care se folosete instruciunea

    while:

    instruciune

    while (expresie) instruciune

    Exemple:

    1. Programul urmtor utilizeaz o metod iterativ simpl pentru extragerea rdcinii

    ptrate dintr-un numr. Fie irul:

    x0, x1, ... xn,

    unde xn=1/2(xn-1+a/xn-1)

    Se poate demonstra c acest ir converge, pentru a>0, ctre rdcina ptrat din a.

    Convergena este rapid pentru 0

  • 7/29/2019 Programare in C

    28/130

  • 7/29/2019 Programare in C

    29/130

    Limbajul de programare C

    default: printf (luna eronata);

    }

    printf (\t%d\n, zz);

    }

    6.6.8. Instruciunea BREAKFormatul instruciunii este urmtorul:

    break;

    Aa cum s-a vzut n paragraful 6.6.7, se poate folosi instruciunea breakpentru a iei

    dintr-o instruciune switch.

    Ea mai poate fi utilizat pentru a iei dintr-o instruciune ciclic.

    6.6.9. Instruciunea CONTINUE

    Instruciunea are urmtorul format: continue;Efect:

    1.n ciclurile while i do-while realizeaz saltul la evaluarea expresiei care decide

    asupra continuitii ciclului;

    2.n ciclul for realizeaz saltul la pasul de reiniializare.

    Un exemplu de program n care se poate utiliza instruciunea continue este urmtorul:

    Se citesc de la tastatur temperaturile nregistrate pe durata a n zile. Se cere

    programul C care afieaz pe ecran media temperaturilor pozitive. Programul va citi toate

    temperaturile indiferent dac sunt pozitive sau negative i calculeaz media celor pozitive. ncazul n care se ntlnete o temperatur negativ se va ignora.

    #include

    #include

    voidmain()

    {

    intn,i;

    floatsuma_temp,temperatura,temp_medie,nr_temp_pozitive;

    puts("\nIntroduceti numarul de zile:");

    scanf("%d",&n);

    nr_temp_pozitive=suma_temp=0;

    for(i=1;i

  • 7/29/2019 Programare in C

    30/130

    Limbajul de programare C

    }

    temp_medie=suma_temp/nr_temp_pozitive;

    printf("\nTemperatura medie pozitiva este %.2f",temp_medie);

    getch();

    }

    6.6.10. Instruciunea GOTO

    Instruciuneagoto are urmtorul format:

    goto nume_de_etichet;

    Ea realizeaz saltul la instruciunea prefixat de eticheta al crui nume se afl scris

    dup cuvntul cheiegoto.

    Eticheta trebuie s fie urmat de caracterul :.

    Un exemplu de program n care se folosete instruciuneagoto este urmtorul:

    Se citesc de la tastatur temperaturile nregistrate pe durata a n zile. Se cere

    programul Ccare afieaz numrul zilei n care s-a ntlnit prima temperatur negativ sau un

    mesaj n cazul n care nu s-a ntlnit o temperatur negativ.

    #include

    #include

    voidmain()

    { intn,i;

    floattemperatura;

    puts("\nIntroduceti numarul de zile:");

    scanf("%d",&n);for(i=1;i

  • 7/29/2019 Programare in C

    31/130

    Limbajul de programare C

    Untablou este reprezentat printr-o mulime finit i ordonat de elemente de acelai tip

    care are asociat un nume.

    Tablourile se folosesc n cazul aplicaiilor care lucreaz cu mai multe date i pentru

    care declararea unor variabile simple nu mai este suficient. Un astfel de exemplu ar fi un

    program care citete temperaturile nregistrate ntr-o perioad oarecare de timp i apoi le

    prelucreaz (determin temperatura minim, maxim, le ordoneaz cresctor sau descresctor,etc.).

    n acest caz declararea unei variabile simple cum este variabila temperatura din

    exemplele anterioare nu mai este suficient, deoarece ea poate memora la un moment dat doar

    temperatura curent, nu i pe celelalte temperaturi.

    n astfel de situaii se utilizeaz date structurate. Datele structurate sunt date care

    conin mai multe date de acelai tip sau de tipuri diferite. Tablourile sunt structuri de date care

    conin date de acelai tip. Referirea la o dat din cadrul tabloului se face utiliznd un indice.

    Indicele reprezint poziia datei n tablou.Untablou, ca orice variabil simpl, trebuie declarat nainte de a fi utilizat. Declaraia

    de tablou, n forma cea mai simpl, conine tipul comun, al elementelor sale, numele tabloului

    i limitele superioare pentru fiecare indice, incluse ntre paranteze drepte:

    tip lista_de_elemente;

    unde lista_de_elemente se compune dintr-un element sau mai multe, separate prin virgul. Un

    element dintr-o astfel de list are formatul: nume[lim1][lim2][limn] n care lim1, lim2, ,

    limn sunt expresii constante care au valori ntregi. Prin expresie constant nelegem o

    expresie care poate fi evaluat la ntlnirea ei de ctre compilator.

    Exemple:

    1.Fie v un vector cu 10 componente de tip ntreg. El se declar astfel: int v[10];

    2.Fie a o matrice cu 100 de linii i 4 coloane. Elementele ei sunt reprezentate n virgul

    flotant simpl precizie. Ea se declar astfel:float a[100] [4];

    La elementele unui tablou ne referim prin variabile cu indici. O astfel de variabil se

    compune din numele tabloului urmat de unul sau mai muli indici, fiecare indice inclus n

    paranteze drepte. Numrul indicilor definete dimensiunea tabloului.Indiciisunt expresii care

    au valori ntregi.Limita inferioar a indicilor estezero.

    Astfel, dac v este tabloul declarat n exemplul 1, atunci elementele lui sunt: v[0], v[1],v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9].

    n cazul matricei a declarate n exemplu 2, elementele ei vor fi

    pe prima linie: a[0] [0], a[0] [1], a[0] [2], a[0] [3]

    pe a doua linie: a[1] [0], a[1] [1], a[1] [2], a[1] [3]

    . . .

    pe ultima linie: a[99] [0], a[99] [1], a[99] [2], a[99] [3]

    164

  • 7/29/2019 Programare in C

    32/130

  • 7/29/2019 Programare in C

    33/130

    Limbajul de programare C

    for(i=0;i

  • 7/29/2019 Programare in C

    34/130

    Limbajul de programare C

    printf("\nIntroduceti nr. de coloane:");

    scanf("%d",&m);

    printf("\nIntroduceti elementele matricei\n");

    for(i=0;i

  • 7/29/2019 Programare in C

    35/130

    Limbajul de programare C

    relativ simplu, algoritm cunoscut sub denumirea de bubblesort sau sortare prin metoda

    bulelor.

    Algoritmul const din parcurgerea vectorului de mai multe ori, n fiecare parcurgere

    comparndu-se elementele aflate pe poziii alturate. Ori de cte ori cele dou elemente

    comparate nu se afl n ordinea dorit, ele se vor interschimba. Pentru interschimbare se va

    folosi o variabil auxiliaraux. Algoritmul se consider ncheiat n urma unei parcurgeri avectorului n care nu se mai efectueaz nici o interchimbare. Pentru a se marca efectuarea unei

    interschimbri se va utiliza o variabil de tip ntreg, gata, cu rol de adevrat/fals.

    Aceast variabil va primi valoarea 1 nainte de fiecare parcurgere a vectorului i valoarea

    0 n momentul n care se efectueaz o interschimbare. Algoritmul se va considera ncheiat

    cnd variabilagatava rmne 1 la sfritul parcurgerii vectorului.

    Algoritmul este explicat pentru vectorul:

    A = [9, 2, 6, 1, 3 ].a) Prima parcurgere:

    gata = 1

    i=0 i=1 i=2 i=39 2 2 2 2 gata=02 9 6 6 6 gata=06 6 9 1 1 gata=01 1 1 9 3 gata=03 3 3 3 9

    b) A doua parcurgere:

    gata = 1

    i=0 i=1 i=2 i=32 2 2 2 26 6 1 1 1 gata=01 1 6 3 3 gata=03 3 3 6 69 9 9 9 9

    168

  • 7/29/2019 Programare in C

    36/130

  • 7/29/2019 Programare in C

    37/130

    Limbajul de programare C

    getch();

    }

    6.8. Apelul i revenirea dintr-o funcie

    6.8.1 Apelul unei funcii

    Am amintit n capitolul 1 c funciile sunt de dou feluri:

    - funcii care returneaz o valoare la revenirea din ea;

    - funcii care nu returneaz o valoare la revenirea din ea.

    O funcie care nu returneaz o valoare la revenirea din ea se apeleaz printr-o

    instruciune de apel. Ea are urmtorul format:

    nume(lista_parametrilor_efectivi);

    n cazul n care o funcie returneaz o valoare, ea poate fi apelat fie printr-o

    instruciune de apel, fie sub forma unui operand al unei expresii. Apelul se face printr-oinstruciune de apel atunci cnd nu dorim s utilizm valoarea returnat de funcia respectiv.

    Definiiaunei funcii are structura urmtoare:

    Antet

    instruciune compus

    Antetulare formatul:

    tip nume(lista_parametrilor_formali)

    Funciile care nu returneaz o valoare la revenirea din ele au ca tip cuvntul cheie void.

    De asemenea, dac lista_parametrilor_formali este vid, ea poate fi definit prin cuvntul

    cheie void. Lista parametrilor formali conine declaraiile acestora separate prin virgul.

    Parametrii formali ai unei funcii sunt reprezentai de datele prin care funcia respectiv

    comunic cu alte funcii din cadrul programului respectiv. Ea se pune n coresponden cu lista

    parametrilor efectivi din instruciunea de apel. Cele dou liste de parametrii trebuie s coincid

    ca numr, ordine i tip.

    6.8.2 Prototipul unei funcii

    O funcie poate fi apelat dac ea este definit n fiierul surs nainte de a fi apelat.

    Acest lucru nu este totdeauna posibil i n astfel de cazuri apelulfunciei trebuie s fie

    precedat deprototipulei.Prototipulpoate fi scris la nceputul fiierului surs i n acest caz el

    va fi valabil n tot fiierul surs.

    Prototipul unei funcii este de fapt antetul funciei i conine toate informaiile

    referitoare la funcia respectiv: numele funciei, tipul returnatde funcie, numruli tipul

    parametrilor funciei.

    170

  • 7/29/2019 Programare in C

    38/130

    Limbajul de programare C

    Exemple:

    1) double val(double x, int a); Acest prototip indic faptul c funcia valreturneaz o

    valoare flotant n dubl precizie i are doi parametri, primul de tip double i al doilea de tip

    int.

    Exemple de instruciuni de apel:

    y= val(z,b); s=val(12.6, 5);n aceste exemple s,ziy trebuie s fie variabile de tipul double iarb o variabil de

    tipul int.

    Se observ c o funcie poate fi apelat fie cu parametrii constani, fie cu parametrii

    variabili.

    2) void citire(void);

    Conform acestui prototip funcia citire nu returneaz nici o valoare i nu are

    parametrii. Funcia poate fi apelat printr-o instruciune de apel de forma:

    citire( );3) double sum (double x[], int n);

    Funcia sum returneaz o valoare flotant n dubl precizie. Ea are doi parametrii: un

    tablou unidimensional de tip double i o variabil de tip int. Aceast funcie se poate apela

    printr-o instruciune de apel de forma:

    s=sum(a,m);

    unde a trebuie s fie un tablou cu elemente de tip double, mo variabil de tipul int, iars o

    variabil de tipul double.6.8.3. Apel prin valoare i apel prin referin

    La apelul unei funcii, fiecrui parametru formal i se atribuie valoarea parametrului

    efectiv care-i corespunde. Deci, la apelul unei funcii, se transfer valorile parametrilor

    efectivi. Din aceast cauz, se spune c apelul este prin valoare.

    n anumite limbaje de programare, la apel se transfer nu valorile parametrilor efectivi

    ci adresele acestor valori. n acest caz se spune c apelul este prin referin.

    ntre cele dou tipuri de apeluri exist o diferen esenial i anume: n cazul apelului

    prin valoare, funcia apelat nu poate modifica parametrii efectivi din funcia care a fcutapelul, neavnd acces la ei. De fapt funcia primete o copie a valorilor de apel.

    n cazul apelului prin referin, funcia apelat dispunnd de adresa parametrilor

    efectivi, i poate modifica pe acetia.

    n limbajul C, apelul prin referin se realizeaz n cazul n care parametrul efectiv este

    numele unui tablou. n acest caz, se transfer valoarea numelui tabloului, adic adresa

    primului su element. n felul acesta, funcia apelat dispune de adresa de nceput a tabloului

    utilizat ca parametru i n consecin ea poate modifica elementele tabloului respectiv.

    171

  • 7/29/2019 Programare in C

    39/130

    Limbajul de programare C

    n concluzie, n limbajul C, transferul parametrilor se face prin valoare. Acest

    transfer devine prin referin n cazul n care parametrul efectiv este numele unui tablou sau se

    cere explicit acest lucru adugnd caracterul & n faa parametrului.

    6.8.4. Revenirea dintr-o funcie

    Revenirea dintr-o funcie se poate face n dou moduri:

    -la ntlnirea instruciunii return;

    -dup execuia ultimei sale instruciuni, adic a instruciunii care precede acolada

    nchis ce termin corpul funciei respective.

    Instruciunea return are dou formate: return;

    sau return expresie;

    Primul format se utilizeaz cnd funcia nu returneaz o valoare, iar cel de al doilea

    format se utilizeaz atunci cnd funcia returneaz o valoare.

    Un exemplu de program care utilizeaz funcii definite de utilizatori este urmtorul:Se citesc de la tastatur cele n elemente de tip ntreg ale unui vector. Se cere

    programul Ccare determin:

    a) Suma cifrelor fiecrui element din vector;

    b) Inversul fircrui element din vector;

    c) Cel mai mare divizor comun al elementelor din vector.

    Pentru ca programul s realizeze aceste cerine vom defini trei funcii utilizator:

    a) O funcie suma_cifrecare va calcula suma cifrelor unui numr ntreg transmis

    ca parametru;b) O funcie invers care va returna inversul unui numr ntreg transmis ca

    parametru;

    c) O funcie cmmdccare va determina cel mai mare divizor comun a dou numere

    ntregi transmise ca parametri.

    Programul este prezentat n continuare:

    #include

    #include

    intsuma_cifre(intn){ ints;

    s = 0;

    while (n!=0)

    { s = s + n % 10;

    n = n / 10; }

    return s; }

    intinvers(intn)

    { intinv;

    172

  • 7/29/2019 Programare in C

    40/130

  • 7/29/2019 Programare in C

    41/130

    Limbajul de programare C

    O prim clas de memorie este aceea alocat variabilelor globale. Lor li se aloc

    memorie pe toat perioada execuiei programului i ele pot fi utilizate n tot programul.

    O alt clas de memorie este alocat variabilelor locale. O astfel de variabil nu este

    valabil n tot programul. Ea are o utilizare local.

    6.9.1. Variabile globale

    O variabil globalare o definiie i attea declaraii de variabil extern cte sunt

    necesare.

    n mod implicit, definiia unei variabile globale determin ca variabila respectivs fie

    definit ncepnd din punctul scrierii ei i pn la sfritul fiierului surs respectiv. De aceea

    se recomand ca definiiile variabilelor globale s fie scrise la nceputul fiierului surs.

    Exemplu:

    inti; double x;

    voidmain (){

    i = 100;

    x = i*x;

    }

    Variabilele iix, fiind definite n afara funciilor programului, sunt globale.

    Construciile int ii respectiv double xsunt definiiile lor, iar din punct de vedere

    sintactic ele au acelai format ca declaraii obinuite.

    Ele pot fi folosite n toate funciile din fiierul surs care conine definiiile lor fr alte

    declaraii suplimentare.

    n schimb, pentru a le utiliza n funcii ale programului situate n alte fiiere surs dect

    n cel n care sunt definite, ele trebuie declarate ca externe n funciile respective.

    O declaraie de variabil extern este la fel ca i o declaraie obinuit, doar c ea

    ncepe prin cuvntul extern.

    De exemplu, dac dorim s folosim variabile globale i i x definite mai sus ntr-o

    funcief, aflat ntr-un alt fiier surs dect cel n care au fost ele definite, atunci n corpulfunciei fle vom declara ca externe:

    f ()

    { extern inti;

    extern double x;

    x = i*x;

    }

    174

  • 7/29/2019 Programare in C

    42/130

    Limbajul de programare C

    Compilatorul aloc memorie pentru variabilele globale n momentul ntlnirii

    definiiilor lor. Aceast memorie se afl ntr-o zon special destinat acestui scop i ea

    rmne alocat pe ntreaga durat a execuiei programului.

    6.9.2. Variabile locale

    Variabilele localenu sunt valabile n tot programul. Exemple de variabile locale suntvariabilele declarate n corpul unei funcii i care nu sunt declarate ca externe. Ele pot fi

    folosite numai n corpul funciei respective, adic ncepnd din momentul apelrii funciei

    respective i pn la revenirea din ea.

    Astfel de variabile pot fi alocate pe stiv. n acest caz, lor li se aloc memorie pe stiv

    la intrarea n funcia n care sunt declarate i i pierd alocarea respectiv la ieirea din funcie,

    cnd se reface stiva la forma dinaintea apelului.

    Stiva este o zon de memorie cu o destinaie special. Ea are o structur de tip LIFO

    (LastInput First Output). ntr-o astfel de zon de memorie se aloc pe rnd memorievariabilelor locale declarate n corpul funciilor. Eliberarea memoriei astfel alocate se face n

    ordine invers alocrii ei, la terminarea execuiei funciei respective.

    Variabilele alocate n acest fel se numesc automatice. Ele se declar n corpul

    funciilor i au sintaxa obinuit.

    Se poate ca variabilele locale s nu fie alocate pe stiv, ci ntr-o zon de memorie

    destinat special n acest scop. O astfel de variabil se spune c este static.

    O variabil static declarat n corpul unei funcii are domeniul de valabilitate numai

    corpul funciei respective, ca i variabilele automatice. Spre deosebire de ele, variabila staticnu se aloc pe stiv, ci ntr-o zon de memorie destinat acestui scop.

    n cazul n care o variabil static este declarat n afara funciilor, ea este definit din

    punctul n care a fost declarat i pn la sfritul fiierului surs care conine declaraia ei.

    Spre deosebire de variabilele globale, o variabil static declarat n acest fel nu poate fi

    declarat ca extern.

    Menionm c tablourile de dimensiuni mari se recomand a fi declarate statice,

    deoarece dac ele sunt automatice, pot s conduc la depirea stivei alocate programului.

    Amintim c, implicit, dimensiunea stivei alocate unui program este de 4K octei.

    Exemple:

    1. Fiierul fis1.cpp este un fiier surs care conine dou variabile globale i i x o

    variabil staticy i dou funcii main if, care i ele conin la rndul lor variabilele statice a

    i b.

    /* variabile globale

    int i; /* definitia variabilei i */

    175

  • 7/29/2019 Programare in C

    43/130

    Limbajul de programare C

    double x; /*definitia variabilelor x

    */

    /* variabile statice */

    static int y;

    voidmain ()

    {

    static char a; /* variabila statica

    */

    int c; /* variabila automatica

    */

    .

    /* se pot folosi variabilele i, x, y, a si c*/

    .

    }

    f()

    { intp; /* variabila automatica

    */

    staticfloat b; /* variabila statica */

    ..

    /* se pot folosi variabilele i, x, y, p si b */

    .

    }

    Variabilele a i c sunt locale funciei maini ele nu pot fi folosite n funcia f. La fel,

    variabilelep i b sunt locale n funciafi nu pot fi folosite n funcia main.

    2. Funcia fis2.cpp conine funciile f1 i f2 care intr n componena aceluiai

    program ca i funciile mainifdin fiierul fis2.cpp.

    /* variabile statice */

    staticusingnedt;

    f1 ()

    {

    extern inti; /* declaratie externa pentru i */

    extern double x; /* declaratie externa pentru x */

    static intk;

    .

    /* se pot folosi variabilele i, x, k si t */

    }

    176

  • 7/29/2019 Programare in C

    44/130

  • 7/29/2019 Programare in C

    45/130

    Limbajul de programare C

    evaluat de compilator la ntlnirea ei, deoarece variabilele globale i statice se iniializeaz

    prin valori definite la compilare.

    Variabilele automatice se iniializeaz la execuie, de fiecare dat cnd se activeaz

    funcia n care sunt declarate. Din aceast cauz, nu mai este necesar ca expresia s fie o

    expresie constant. Totui, la ntlnirea ei, trebuie s fie definii operanzii expresie de

    iniializare.Exemplu:

    f (intn) ;

    { intx = 10;

    int y = x*n;

    }

    La ntlnirea expresieix*n sunt deja definii ambii operanzi:

    - xa fost n prealabil iniializat;

    - n are o valoare care a fost deja transferat la apel.

    Variabilele globale i statice neiniializate au implicit valoarea egal cu zero.Variabilele automatice neiniializate au o valoare iniial imprevizibil.

    Tablourile se pot iniializa printr-o list de expresii incluse ntre acolade. Astfel, un

    tablou unidimensional se poate iniializa folosind urmtorul format:

    tip nume [n] = {exp1, exp2, , expn}; sau

    static tip nume [n] = {exp1, exp2, , expn}; dac tabloul este static

    Pentru un tablou bidimensional vom folosi urmtorul format:

    tip nume [n] = {

    {exp11, exp12, , exp1m},{exp21, exp22, , exp2m},...............

    {expn1, expn2, , expnm},

    };

    Exemple:

    int it[ ] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    intmatrice [4] [3] = {{-1, 0, 1}, {-1}, {0, 1}, {0, 0, 1}}.

    Observaii:1. n cazul vectorului it nu s-a specificat la declarare dimensiunea acestuia deoarece

    ea rezult n urma iniializrii, fiind egal cu 9;

    2. La iniializarea elementelor tabloului matrice o parte din elemente pot rmne

    neiniializate.

    6.10. Pointeri n limbajul C

    Unpointereste o variabil care are ca valori adrese.

    178

  • 7/29/2019 Programare in C

    46/130

    Limbajul de programare C

    Pointerii se utilizeaz pentru a face referire la date cunoscute prin adresele lor. Astfel,

    dac p este o variabil de tip care are ca valoare adresa zonei de memorie alocat pentru

    variabila ntreagx, atunci: p reprezint valoarea variabileix, ca n figura 6.2:

    n figura 6.2 valoarea 2500 reprezint adresa de memorie a valorii 5, adic este un

    pointer.

    Operatorul (unar) are aceeai prioritate ca i ceilali operatori unari dinlimbajul C.

    Dac p conine adresa zonei de memorie alocat variabilei x, vom spune c p

    pointeaz sprexsau c p conine adresa lui x.

    Pentru a atribui unui pointeradresa unei variabile, putem folosi operatorul unar &.

    Astfel, dac dorim cap s pointeze sprex, putem utiliza atribuirea:p = &x;

    6.10.1. Declaraia de pointer

    n general, unpointerse declar prin:

    tip nume;ceea ce nseamn c numeeste un pointer care pointeaz spre o zon de memorie ce conine o

    dat de tipul tip.

    Comparnd declaraia anterioar de pointer cu una obinuit:

    tip nume;putem considera c tip dintr-o declaraie pointerreprezint tip dintr-o declaraie obinuit.De aceea, construcia tip se spune c reprezint un tip nou, tipul pointer.

    Exist cazuri n care dorim ca un pointers fie utilizat cu mai multe tipuri de date. n

    acest caz, la declararea lui nu dorim s specificm un tip anume. Aceasta se realizeaz folosind

    cuvntul cheie voidastfel:

    voidnume;Exemple:

    179

    x

    Memoria p (adresa de memorie

    a variabilei x)

    5

    Memoria

    2500

    Fig. 6.2. Referirea la o variabil utiliznd pointeri.

  • 7/29/2019 Programare in C

    47/130

    Limbajul de programare C

    Fie declaraiile:

    intx,y;

    intp;

    1. y = x+100; este echivalent cu secvena:

    p = &x;

    y = p+100;n care luiy i se atribuie suma dintre coninutul zonei a crei adres se afl np i 100.

    2. x = y; este echivalent cu secvena:

    p = &x;

    p = y;

    n care coninutul zonei a crei adres se afl np devine egal cu valoarea luiy.

    3. x++; este echivalent cu secvena:

    p = &x;

    (p)++;n care coninutul zonei a crei adres se afl np se mrete cu 1.

    4. Fie funciaperm de mai jos:

    voidperm(intx,inty)

    { int temp;

    temp=x;

    x=y;

    y=temp; }

    Un apel de forma:

    perm (a,b);nu are nici un efect, deoarece la acest apel valoarea lui a se transfer parametruluix, iar a lui b

    parametrului y. Apoi funcia perm permut valorile parametrilorx i y, ns prin aceasta

    valorile parametrilor efectivi a i b rmn nemodificate. Deci la revenirea din funcia perm,

    variabilele a i b au aceleai valori nemodificate de apel.

    Pentru a realiza o permutare a valorilor acestor variabile, este necesar s se transfere nu

    valorile, ci adresele variabilelor.

    Acest lucru este posibil dac modificm apelul n felul urmtor:perm (&a, &b);

    n acest caz parametrii formali ai funciei perm au ca valori adrese, deci ei sunt

    pointeri. Avnd n vedere acest fapt, funciaperm sufer urmtoarele modificri:

    voidperm(intx,inty); /*x si y sunt pointeri spre

    intregi*/

    { inttemp;

    180

  • 7/29/2019 Programare in C

    48/130

  • 7/29/2019 Programare in C

    49/130

    Limbajul de programare C

    float medii[30];

    Aceast declaraie va avea ca efect alocarea unei zone contigue de 30 de locaii

    (fiecare avnd dimensiunea de 4 octei), chiar dac programatorul va stoca doar 25 de medii.

    Varianta cupointeriva consta n declararea unui pointersprefloat, la care se va aloca exact

    attea locaii ct studeni sunt.

    Un alt exemplu este cel n care lucrm cu tablouri de caractere. De exemplu, pentru apstra numele unei persoane, se putea folosi un tablou declarat astfel:

    char Nume[20];

    Varianta cu pointeri va consta n declaraia urmtoare:

    char *Nume;

    Aceast variant este mult mai flexibil oferind posibilitatea de a aloca exact attea

    poziii ct este necesar.

    6.10.3. Operaii cu pointeri

    Asupra pointerilor se pot face diferite operaii, indicate n cele ce urmeaz.

    a) Operaii de incrementare i decrementare

    Operatorii de incrementareidecrementarese pot aplica variabilelor de tip pointer.

    Ei se execut altfel dect asupra datelor de alte tipuri.

    Efect:

    - operatorul de incrementare aplicat asupra unui operand de tip pointer spre tipul t

    mrete adresa coninut de operand cu numrul de octei necesari pentru a pstra o dat detipul t;

    - operatorul de decrementare se execut n mod analog.

    Observaie:

    Aceast proprietate este foarte util cnd se au n vedere prelucrri de tablou. Fie

    declaraiile de mai jos:

    int tab[n];

    int *p;

    int i;

    unde n este o constant ntreag, fiep = &tab[i]; unde 0

  • 7/29/2019 Programare in C

    50/130

    Limbajul de programare C

    Efect:

    - expresia p+n mrete valoarea lui p cu nt, unde teste numrul de octei necesaripentru a memora o dat de un tip spre care pointeazp;

    - n mod analog, expresiap-nmicoreaz valoarea luipcu nt.Dac a este un tablou cu elemente de tipul t, atunci a este un pointer, deci expresia

    a+n este corect i va reprezenta un pointerspre elementul a[n](adresa acestuia). Valoareaacestui element se poate obine din expresia (a+n).

    n acest fel se pot nlocui indicii de tablou prin expresii cu pointeri.

    c) Compararea a doi pointeri

    Doipointericare pointeaz spre elementele aceluiai tablou pot fi comparai folosind

    operatorii de relaie i de egalitate.

    Astfel, dacp i q sunt doipointericare pointeaz spre elementele t[i]respectiv t[j]ale

    tabloului t, expresia p

  • 7/29/2019 Programare in C

    51/130

    Limbajul de programare C

    void *malloc (usingned n);

    unde n este numrul de octei ai zonei de memorie care se aloc.

    n cazul n care n este prea mare, funcia returneaz pointerulNULL.

    Funcia calloc are prototipul:

    void *calloc (usingned nrelem, usingned dimelem);

    unde: - dimelem este dimensiunea n octei a unui element de dat;- nrelem este numrul elementelor pentru are se aloc memorie.

    Prin aceast funcie se aloc nrelem*dimelem octei.

    Ea returneazpointerulspre nceputul zonei rezervate saupointerul NULL n cazul n

    care numrul octeilor este prea mare (depete zona de memorie liber afectat alocrilor

    dinamice).

    Elementele din zona de memorie alocat prin calloc au valoareazero.

    Funciafree elibereaz o zon de memorie care n prealabil a fost alocat prin malloc

    sau calloc. Prototipul ei este:

    void free(void *p);

    unde p este pointerul returnat de malloc sau calloc la alocare, deci este pointerul spre

    nceputul zonei care se elibereaz.

    Exemplu:

    Funcia memoreaz un ir de caracatere ntr-o zon de memorie alocat prin funcia

    malloc. Ea returneaz adresa de nceput a zonei n care s-a salvat irul de caractere, deci

    returneaz un pointer spre tipul char.

    #include #include

    #include

    char *memoreaza (char *s)

    /* memoreaza sirul de caractere spre care pointeaza s in zona

    de memorie furnizata de malloc*/

    {

    if((p = (char *) malloc (strlen(s)+1)) ! = NULL)

    { strcpy(p,s); return p;

    }

    elsereturn NULL;

    }

    n exemplul anterior s-au utilizat dou funcii specifice irurilor de caractere, strlen,

    care returneaz lungimea unui ir de caractere i strcpy, care copiaz un ir de caractere n

    altul, funcii definite n fiierul string.h.

    184

  • 7/29/2019 Programare in C

    52/130

    Limbajul de programare C

    6.10.5. Prelucrarea tablourilor unidimensionale folosind pointeri

    S-a artat c numele unui tablou estepointer constant care are ca valoare adresa

    primului element al su.Pentru declaraia:

    tip a[];

    identificatorul a are ca valoare adresa elementului a[0], adic &a[0].Fie tip*p; atunci atribuirea de formap = a; este corect i n urma acestei atribuiri, p

    are valoare tot adresa lui a[0].

    Dac utilizm ca parametru efectiv numele unui tablou unidimensional, atunci

    parametrul formal corespunztor poate fi declarat fie ca un tablou unidimensional (cu

    paranteze ptrate vide), fie printr-un pointer:

    tip a [100]

    f(a);

    Antetul luifse definete prin unul din formatele:

    f(tip t[]) sau f(tip*t).

    Indiferent care dintre antete se alege, n corpul funcieifse pot folosi att variabilele cu

    indici: t[exp]ct i expresii cu pointeri: *(t+exp) pentru a face acces la elementele tabloului

    tab.

    S-a artat c n general, dac tab este un tablou unidimensional de tipul tip, atunci a+n

    este chiar adresa elementului a[n]. Deci:

    x = a[n] sau x = *(a+n)sunt atribuiri care au acelai effect (atribuire lui xvaloarea elementului a[n]). Expresiile cu

    pointeri pot fi folosite i n stnga operatorului de atribuire, adic:

    a[n] = x

    i *(a+n) = x

    au acelai efect.

    Din cele de mai sus rezult c variabilele cu indici se pot echivala prin expresii cu

    pointeri. Este posibil s procedm i invers, adic s nlocuim expresiile cu pointeri prin

    variabile cu indici, dei acest lucru nu este recomandabil.

    Fie, de exemplu, declaraia: tip*p = (tip*)malloc(...);

    Expresia *(p+n) este echivalent cu expresiap[n].

    Exemplu:

    Programul urmtor calculeaz i afieaz suma elementelor ntregi ale unui vector de

    dimensiune n .

    #include

    185

  • 7/29/2019 Programare in C

    53/130

  • 7/29/2019 Programare in C

    54/130

  • 7/29/2019 Programare in C

    55/130

    Limbajul de programare C

    Dac n cazul tablourilor unidimensionale, tab+n este adresa elementului tab[n], adic

    &tab[n], n cazul tablourilor bidimensionale, expresia tab+n este adresa elementului

    tab[n][0].

    Aceast interpretare rezult din faptul c un tablou bidimensionaltrebuie considerat ca

    fiind un tablou de tablouri unidimensionale. n general, un tablou k dimensional este un

    tablou de tablouri k-1 dimensionale.Fie, de exemplu, declaraia:

    tip tab[m][n];

    Tabloul tab poate fi privit ca m tablouri unidimensionale. Astfel, tab[0], tab[1], ,

    tab[m-1] sunt cele m elemente ale lui tab i fiecare este un pointer spre cte un tablou

    unidimensional de n elemente. De aici rezult c tab[0] are ca valoare adresa lui tab[0][0],

    tab[1]are ca valoare adresa lui tab[1][0]i n general tab[i]are ca valoare adresa lui tab[i][0].

    n figura 6.4 este prezentat interpretarea tablourilor bidimensionale descris anterior.

    Cum *(tab+i) are ca valoare chiar tab[i], rezult c tab[i][0] are aceeai valoare cu

    *(*(tab+i)).De asemenea, tab[i]+j are ca valoare adresa lui tab[i][j]. Deci tab[i][j] are aceeai

    valoare ca i expresia *(tab[i]+j), iar aceasta din urm are aceeai valoare cu expresia

    *(*(tab+i)+j).

    nseamn c atribuirile *(*(tab+i)+j) = xi tab[i][j] = xsunt echivalente.

    Dac tab este un tablou unidimensionaldeclarat prin:

    tip tab[...];

    atunci tab are tipul tip*adicpointerspre tip.

    Dac tab este un tablou bidimensionaldeclarat prin:

    tip tab[m][n];

    atunci tab are tipul tip (*)[n]adicpointerspre tip.

    Menionm c n declaraia de mai sus m i n sunt expresii constante.

    S presupunem c tab este parametru la apelul funcieif:

    ... f(tab).

    n acest caz, parametrul formal al funcieifpoate fi declarat n urmtoarele moduri:

    ... f (tip t[ ][n]) sau ... f(tip(*p)[n]).

    188

    tab[0][0] tab[0][1] tab[0][n-1]

    tab[1][0] tab[1][1] tab[1][n-1]

    ... ... ...

    tab[m-1][0] tab[m-1][1] tab[m-1][n-1]

    tab[0]

    tab[1]

    ...

    tab[m-1]

    Fig. 6.4. Interpretarea tabloului bidimensional ca o mulime detablouri unidimensionale.

  • 7/29/2019 Programare in C

    56/130

    Limbajul de programare C

    Fie declaraia:

    tip *tab1[n];

    n acest caz tab1 este un tablou unidimensional de pointeri spre tipul tip, adic

    fiecare element din cele n ale tabloului tab1 este unpointerspre tip. Tablourile tab i tab1 nu

    trebuie confundate. Tabloului tab i se aloc o memorie de m*n*sizeof(tip) octei. Tabloului

    tab1 i se aloc n*sizeof(tip*) octei.Dac o funcie g are la apel ca parametru pe tabloul tab1: ... g(tab1) ... atunci

    parametrul formal al funcieigpoate fi declarat n urmtoarele moduri:

    ... g(tip*p[]) sau ...g(tip**p).

    Exemple:

    1. Fie declaraiile:

    double tab[2][3] = {{0, 1, 2}, {3, 4, 5}};

    double *p;

    n tabelul 6.7sunt prezentate rezultate ale execuiei unor instruciuni:

    Tabelul 6.7.

    Instruciuni

    Eleme

    ntul

    afiat

    Valoarea

    elementului

    p = tab[0];

    printf (%g, *p);tab[0] [0]; 0

    p = tab[1];

    printf (%g, *p);tab[1] [0]; 3

    printf (%g, *(*(tab))); tab[0] [0]; 0

    printf (%g, *(*(tab+1)+2)); tab[1] [2]; 5

    2. Considerm funciafdefinit astfel:

    voidf(double (*p)[3])

    { inti, j;

    for(i=0; i

  • 7/29/2019 Programare in C

    57/130

    Limbajul de programare C

    double t0[3] = {10, 11, 12};

    double t1[3] = {13, 14, 15};

    i atribuirile t[0] = t0; t[1] = t1;

    Definim funciaf1 astfel:

    voidf1(double *p[ ])

    {

    }

    unde corpul funcieif1 coincide cu al funcieif.

    La apelurilef1(t); se listeaz valorile elementelor tablourilort0 i t1, separate prin cte

    un spaiu, adic:

    10 11 12 13 14 15

    Acelai rezultat se obine dac antetul luif1 se schimb cu:

    void f1 (double **p)

    n ambele situaii, expresiap[i][j]poate fi schimbat cu *(*(p+i)+j).Ca o consecin a celor prezentate anterior,putem renuna la tablourile bidimensionale

    statice i putem folosi tablouri de pointeri. Acest lucru este posibil pentru c pointerii, fiind

    variabile, pot forma alte tipuri de date structurate, de exemplu tablouri. Dac Teste un tip de

    date oarecare, tipul pointerilor spre acel tip va fi T*.

    Un tablou de pointeri spre tipul Tse declar prin :

    T *Nume[dim];

    unde Nume va fi numele tabloului de pointeri, iardim numrul depointeridin tablou.

    Cu ajutorul unui tablou de pointeri, se pot pstra datele unei matrici, darcu avantajul cfiecare linie are o lungime variabil.

    S considerm un exemplu n care se dau notele a n candidai la cele m probe date la

    un concurs pentru obinerea unui post. Putem folosi un tablou de pointeri pentru afiarea

    notelor fiecrui candidat i pentru determinarea mediei obinute de fiecare candidat. Notele

    candidailor vor putea fi stocate i accesate cu ajutorul unui tablou de pointeri, declarat astfel:

    Note[I]

    Note[0]Note[1]

    .Note[19]

    Prezentm programul surs n varianta cu tablouri de pointeri:

    #include

    #include

    #include

    190

    4 5 8 9 6 7 5

    9 9 6 7 9 8 8

    8 7 4 5 6 7 8

    Fig. 6.5. Memorarea notelor studenilorutiliznd pointerii.

    int *Note[20];

    adic ca un tablou de 20 de pointeri, cte un

    pointer pentru fiecare candidat. De fapt,fiecare pointer va conine adresa unei zone

    de memorie unde sunt stocate notele acelui

    candidat (zona ce trebuie rezervat ). Acest

    lucru se observ n figura 6.5:

  • 7/29/2019 Programare in C

    58/130

    Limbajul de programare C

    intN, M, *Note[20];

    float*Media;

    voidCitire (void)

    { intI, J;

    printf("\n Dati numarul de candidati");

    scanf("%d",&N);printf("\n Dati numarul de probe");

    scanf("%d",&M);

    for(I=0; I

  • 7/29/2019 Programare in C

    59/130

  • 7/29/2019 Programare in C

    60/130

  • 7/29/2019 Programare in C

    61/130

  • 7/29/2019 Programare in C

    62/130

    Limbajul de programare C

    (*p)(double) - nseamn cp este un pointer spre funcii cu argumente de

    tip double.

    double (*p)(double) - nseamn c p este un pointer spre funcii care

    returneaz o valoare de tip double i are ca parametru un double.

    Pointerul p va putea fi folosit pentru a accesa valorile funciei. Apelarea funciei se

    face cu expresia (*p)(x). Mai mult, funcia general construit anterior, se va putea apela( pentru exemplele de funcii prezentate anterior) astfel :

    ValInt= Integrala(10, 20, 100, f1);

    sau

    A=-3.14; B=3.14 ; // adic A i B sunt egale cu Pi i Pi

    ValInt= Integrala(A, B, 100, f2);

    Trebuie s atragem atenia asupra faptului c construcia double *p(double) este

    corect, dar are alt semnificaie: reprezint prototipul unei funcii ce returneaz un pointer

    spre double (!!). Acest lucru este datorat faptului c parantezele () sunt mai prioritare dect

    operatorul *.Prezentm programul care calculeaz valoarea integralei.

    #include

    #include

    #include

    #include

    double f(double x)

    { return x*x-1; }

    double f1(double x)

    { return sin(x*x); }

    double f2(double x)

    { return exp(x); }

    double Integrala(double A, double B, intn, double (*p)(double))

    { double pas,S;inti;

    pas=(B-A)/n;

    S=0;

    for(i=0;i

  • 7/29/2019 Programare in C

    63/130

    Limbajul de programare C

    A=-3.14;

    B=3.14;

    ValInt=Integrala(A,B,100,f1);

    printf("\n valoarea integralei din f=sin(x*x) este %lf",ValInt);

    ValInt=Integrala(10,100,100,f2);

    printf("\n valoarea integralei din f=exp(x) este %lf",ValInt);getch(); }

    196

  • 7/29/2019 Programare in C

    64/130

    Limbajul de programare C

    6.10.8. Tratarea parametrilor din linia de comand

    n linia de comand folosit la apelul execuiei unui program se pot utiliza diferii

    parametri. n cazul utilizrii mediului de dezvoltare integratBorland C, aceti parametri se pot

    defini utiliznd submeniul Arguments al meniului Options. Se selecteaz meniul Options

    folosind sgeile sau tastnd O. Apoi se selecteaz submeniul Arguments cu ajutorul

    sgeilor sau tastndA. n acest moment se afieaz o fereastr i se vor tasta parametrii care

    s fie prezeni la lansarea programului. Parametrii se tasteaz unul dup altul, separai prin

    blancuri. Dup ultimul parametru se va aciona tastaENTER.

    Aceti parametri pot fi utilizai parametrii argc i argv ai funciei principale.

    Parametrul argc este de tip ntreg i indic numrul de parametri din linia de comand

    (sau diferii cu ajutorul submeniului Arguments). Parametrul argv este un tablou de pointeri

    spre zonele n care sunt pstrai parametrii liniei de comand. Acetia se consider iruri de

    caractere. n felul acesta, antetul funciei principale va fi:

    main (int argc, char *argv[])Exemplu:

    Considernd c la lansarea programuluiprogs-au furnizat parametrii:

    15 SEPTEMBRIE 2001

    n acest caz argc = 4, iar tabloul argv conine pointerii:

    - argv[0] - pointeri spre numele programului (calea, numele i extensia.EXE);

    - argv[1] - pointeri spre 15;

    - argv[2] - pointeri spre SEPTEMBRIE;

    - argv[3] - pointeri spre 2001.

    Observaii:1) Lansarea unui program se face cu prima instruciune a funciei principale. Parametrii

    argc i argv au deja n acest moment valorile indicate mai sus. Deci ei pot fi analizai chiar

    ncepnd cu prima instruciune a funciei principale.

    2) n mod frecvent aceti parametri reprezint diferite opiuni ale programului, date

    calendaristice, nume de fiiere etc.

    3)argv[0]este ntotdeaunapointerulspre numele fiierului cu imaginea executabil a

    programului.Exemple:

    1. Programul urmtor afieaz parametrii din linia de comand.

    voidmain(intargc, char*argv[])

    /*afiseaza parametrii din linia de comanda */

    { inti;

    for(i = 0; i

  • 7/29/2019 Programare in C

    65/130

  • 7/29/2019 Programare in C

    66/130

  • 7/29/2019 Programare in C

    67/130

  • 7/29/2019 Programare in C

    68/130

    Limbajul de programare C

    *(int*) &k=3;

    *(int*) &1 = -3;

    printf(dimensiunile lui I,j,n,1\n);

    printf(%d %d %d %d\n, sizeof(i), sizeof(j), sizeof(n), sizeof(1));

    printf(dimensiunile lui x,s,s1,s2\n);

    printf(%d %d %d %d\n, sizeof(x), strlen(s), strlen(s1), strlen(s1),strlen(s2));

    printf(valorile lui i,n,s,s1,s2\n);

    printf(i = %d n=%d s=%s s1=%s s2=s%\n, i,n,s,s1,s2);

    printf(valorile lui j,k,1\n);

    printf(j=%d k=%d l=%d\n, j,k,l);

    *(double *) &pi=3.14159;

    printf(valorile lui x,pi\n);

    printf(x=%.10f pi=%.10f\n, x,pi);

    /* modificari folosind pointeri */

    *(int*)&i = 10000;

    q=&l; *q=7;

    printf(valorile modificate ale lui i si l\n);

    printf(i=%d l=%d\n, i, l);

    *(double *) &pi = 3.14159265;

    printf(valorea modificata a lui pi\n);

    printf(%.10f\n, pi);

    *s = 1; *(s+1) = 2;printf(valorea modificata a zonei spre care pointeaza s\n);

    printf(s=%s\n, s);

    p = s1; *p=1;

    printf(valorea modificata a zonei spre care pointeaza s1\n);

    printf(s=%s\n, s1);

    }

    Rezultatele programului:

    dimensiunile lui i,j,n,1

    2 2 2 2

    dimensiunile lui x,s,s1,s2

    8 3 3 5

    valorile lui I,n,s,s1,s2

    i = 10 n = 12 s = sir s1 = abc s2 = ABCDE

    Valorile lui j,k,l

    j = 1234 k=3 l=3

    201

  • 7/29/2019 Programare in C

    69/130

    Limbajul de programare C

    Valorile lui x, pi

    x = 1.2345678900 pi=3.1415900000

    Valorile modificate ale lui I si l

    i = 10000 l=7

    valoarea modificata a lui pi

    3.1415926000valoarea modificata a zonei spre care pointeaza s

    s = 12r

    valoarea modificata a zonei spre care pointeaza s1

    s1 = 1bc

    Observaii:

    1) Declaraia constpermite protejarea valorii atribuite unui nume fa de eventualele

    ncercri ulterioare de a modifica accidental aceste valori prin simple atribuiri.

    2) n cazul n care programatorul dorete s fac o astfel de modificare, ea se poate

    realiza, dar nu direct, ci doar indirect, folosind pointerii.De exemplu, dac dorim s modificm valoarea constantei idin exemplu 1 de la 10 la

    100, putem realiza acest lucru prin instruciunea urmtoare:

    *(int*)&i = 100

    Aceasta este posibil deoarece unui nume declarat prin consti se aloc memorie.

    Expresia de mai sus este echivalent cu secvena:

    int*p;................

    p = &i;

    *p = 100;

    ntr-adevr, &ireprezint adresa zonei alocate numelui i. Atunci (int *)&iconvertete

    aceast adres spre un pointer spre ntregi, deci ea are aceeai valoare ca i p dup

    instruciunea p = &i; Prin urmare, instruciunea *p = 100; devine echivalent cu

    *(int*)&i = 100;

    Modificatorul const se folosete frecvent la declaraia parametrilor formali de tip

    pointer. O astfel de declaraie are formatul:

    Un parametru formal declarat prin construcia:tip*nume_parametru_formal

    corespunde unui parametru efectiv a crui valoarea este o adres.

    La apel, valoarea parametrului formal devine egal cu aceast adres. Datorit acestui

    fapt funcia apelat poate s modifice data aflat la adresa respectiv.

    Modificatorul const utilizat la declararea unui astfel de parametru formal interzice

    funciei apelate s modifice data de la adresa recepionat la apel de ctre parametrul formal

    corespunztor.

    202

  • 7/29/2019 Programare in C

    70/130

    Limbajul de programare C

    Acest mecanism este utilizat frecvent n cazul funciilor de tratare a irurilor de

    caractere.

    Exemple:

    1. Funcia strlen din biblioteca standard a limbajului Care prototipul:

    unsigned strlen(const char*s);

    Ea se apeleaz prin expresii de atribuire de forma:n = strlen(x);

    undexeste un pointer spre o zon de memorie n care se afl un ir de caractere.

    Funcia strlen determin lungimea irului aflat la adresa recepionat de ctre

    parametrul s. Ea nu are voie s modifice irul respectiv i din aceast cauz parametrul s se

    declar folosind modificatorul const.

    2. Funcia strcpy din biblioteca standard a limbajului Care prototipul:

    Char * strcpy (char*dest, const char * sursa);

    Aceast funcie copiaz irul aflat la adresa recepionat de parametrul surs n zonade memorie a crei adres este atribuit parametrului dest. Deoarece funcia strcpy nu are voie

    s modifice irul de la adresa surs, la destinaia acestui parametru s-a utilizat modificatorul

    const. n schimb, funcia schimb coninutul de la adresa dest, unde se copiaz irul i deci

    parametrul destnu se mai declar prin modificatorul const.

    Funcia strcpy returneaz adresa din dest, adic adresa zonei n care s-a copiat irul.

    3. Funcia strcatdin biblioteca standard a limbajului Care prototipul:

    char*strcat(char*a, const char*b);

    irul spre care pointeaz bse concateneaz la sfritul irului spre care pointeaz a.irul spre care pointeaz nu poate fi modificat de ctre funcia strcat i din aceast cauz

    parametrul b este declarat cu modificatorul const.

    Funcia returneaz pointerul spre irul rezultat, deci chiar valoarea parametrului a.

    4. Funcia strcmp din biblioteca standard a limbajului Care prototipul:

    int strcmp (const char *a, const char *b);

    Funcia compar irurile spre care pointeaz a i b. Ea nu poate modifica cele dou

    iruri i de aceea cei doi parametri au fost declarai prin modificatorul const.

    6.10.10. Stiva, exemplu de structur ce folosete pointeri

    Prin stiv se nelege o mulime ordonat de elemente la care accesul se realizeaz

    conform principiuluiLIFO (LastIn FirstOut).

    Cel mai simplu procedeu de implementare a unei stive este pstrarea elementelor ei

    ntr-un tablou unidimensional.

    n zona de memorie afectat stivei se pot pstra elementele ei unul dup altul. De

    asemenea ele se pot scoate din aceast zon n ordine invers pstrrii lor. Astfel, la un

    moment dat, se scoate ultimul element pus n stiv i numai acesta.

    203

  • 7/29/2019 Programare in C

    71/130

  • 7/29/2019 Programare in C

    72/130

    Limbajul de programare C

    Exemplul 1: Se vor defini funciile push, pop i clearpentru o stiv de tip nreg de

    maxim 1000 de elemente.

    # define MAX 1000

    staticintstack[MAX]

    static next = 0; /* indicele pentru baza

    stivei */voidpush(x) /* pune pe stiva valoarea

    lui x */

    intx;

    { if(next0) return stack [--next];

    else { printf (stiva este vida\n); return 0; }

    }

    voidclear() /* videaza

    stiva */

    { next = 0;

    }

    Exemplul 2: S se rescrise funciile push, pop i clear folosind pointeri n locul

    variabilelor cu indici, considernd un numr maxim de 1000 de elemente.

    # define MAX 1000staticintstack[MAX]

    staticint*next = stack;

    /* pointerul next se initializeaza cu adresa de indice a zonei afectate stivei */

    voidpush(intx) /* pune pe stiva valoarea

    lui x */

    { if(nextstack) return (*--next);

    else { printf (stiva este vida\n); return 0;}

    }

    voidclear() /* videaza

    stiva */

    { next = stack; }

    205

  • 7/29/2019 Programare in C

    73/130

    Limbajul de programare C

    6.11. Structuri i tipuri definite de utilizator

    n anumite situaii practice se lucreaz cu seturi mari de date. Aceste date pot s fie

    toate de acelai tip sau s fie de tipuri diferite. Dac datele sunt de acelai tip ele se pot grupa

    n structuri de tip tablou. Dac sunt de tip diferit, spunem despre grupa respectiv de date c

    formeaz o structur.

    6.11.1. Declaraia de structur

    O structur se poate declara n felul urmtor:

    struct nume { list de_declarat