+ All Categories

Pc_Cap5

Date post: 16-Nov-2015
Category:
Upload: bogdan-mihai-dumitru
View: 212 times
Download: 0 times
Share this document with a friend
Description:
Programarea calculatoarelor
25
5. Tipuri de date şi variabile Datele formează elementul de bază al unui program, pentru că ele reprezintă suportul de informaţie al programului. Instrucţiunile unui program acţionează în mod esenţial asupra datelor. Noţiunea de tip de date este specifică limbajelor de nivel înalt de tip procedural şi se bazează pe următoarea restricţie importantă: în timpul execuţiei unui program, o variabilă nu poate primi valori decât aparţinând unui singur tip. Observaţie. Nu toate limbajele de nivel înalt utilizează noţiunea de tip de date. De exemplu limbajele funcţionale (Lisp) sau cele logice (Prolog) nu o folosesc, gestiunea tipului datelor asociate la o variabilă este efectuată automat de către calculator. Un tip de date reprezintă o mulţime finită de elemente care au aceeaşi reprezentare internă într- un calculator şi asupra cărora se pot eventual efectua anumite operaţii. 5.1 Ierarhia tipurilor de date Limbajul C este un limbaj puternic tipizat, în sensul că permite utilizarea unui număr mare de tipuri de date. A) Tipuri de date predefinite şi tipuri derivate În C, precum şi în majoritatea limbajelor tipizate, tipurile de date se împart în două categorii: tipuri de date predefinite (sau fundamentale) şi tipuri definite de programator (tipuri utilizator). In cazul tipurilor predefinite, mulţimea valorilor acestora şi operatorii care se pot utiliza sunt incluse in sintaxa limbajului de programare. Tipurile predefinite au asociate un nume reprezentat printr-un cavânt cheie ce poate fi folosit la declararea variabilelor. De exemplu, dacă T reprezintă numele unui tip de date, declaraţia: T v; este similară cu următoarea declaraţie din matematică: vT In limbajul C tipurile predefinite sunt cele aritmetice, iar operatorii predefiniţi corespund principalelor operaţii aritmetice. Spre deosebire de tipurile predefinite, tipurile de date definite de programator se construiesc pe baza celor fundamentale cu ajutorul unor construcţii sintactice predefinite. În
Transcript
  • 5. Tipuri de date i variabile

    Datele formeaz elementul de baz al unui program, pentru c ele reprezint suportul de

    informaie al programului. Instruciunile unui program acioneaz n mod esenial asupra datelor.

    Noiunea de tip de date este specific limbajelor de nivel nalt de tip procedural i se bazeaz pe

    urmtoarea restricie important: n timpul execuiei unui program, o variabil nu poate primi

    valori dect aparinnd unui singur tip.

    Observaie. Nu toate limbajele de nivel nalt utilizeaz noiunea de tip de date. De exemplu

    limbajele funcionale (Lisp) sau cele logice (Prolog) nu o folosesc, gestiunea tipului datelor

    asociate la o variabil este efectuat automat de ctre calculator.

    Un tip de date reprezint o mulime finit de elemente care au aceeai reprezentare intern ntr-

    un calculator i asupra crora se pot eventual efectua anumite operaii.

    5.1 Ierarhia tipurilor de date

    Limbajul C este un limbaj puternic tipizat, n sensul c permite utilizarea unui numr mare de

    tipuri de date.

    A) Tipuri de date predefinite i tipuri derivate

    n C, precum i n majoritatea limbajelor tipizate, tipurile de date se mpart n dou categorii:

    tipuri de date predefinite (sau fundamentale) i tipuri definite de programator (tipuri

    utilizator).

    In cazul tipurilor predefinite, mulimea valorilor acestora i operatorii care se pot utiliza

    sunt incluse in sintaxa limbajului de programare. Tipurile predefinite au asociate un nume

    reprezentat printr-un cavnt cheie ce poate fi folosit la declararea variabilelor. De exemplu, dac

    T reprezint numele unui tip de date, declaraia: T v;

    este similar cu urmtoarea declaraie din matematic:

    vT

    In limbajul C tipurile predefinite sunt cele aritmetice, iar operatorii predefinii corespund

    principalelor operaii aritmetice.

    Spre deosebire de tipurile predefinite, tipurile de date definite de programator se

    construiesc pe baza celor fundamentale cu ajutorul unor construcii sintactice predefinite. n

  • acest caz, ntr-o declaratie ca cea anterioar, T nu este numele unei mulimi, ci descrierea unei

    mulimi prin intermediul unei proprieti:

    v {x | x are proprietatea T}

    Exemple: int i, j;

    /* declar 2 variabile apartinand

    tipului predefinit int

    */

    struct dreptunghi { double h, e} d;

    /* declar variabila d ca fiind de tipul structura

    ce conine dou componente de tip double

    cu numele h i e

    */

    n primul caz, T este int, iar n cazul al doilea T este: struct dreptunghi {double h, e}

    Limbajul C permite construirea unor tipuri de date utilizator cu ajutorul unor operatori de

    derivare. Operatorii de drivare se pot aplica oricrui tip de date definit ntr-un program

    (fundamental sau derivat) pentru a genera noi tipuri de date. n acest caz, tipul de date care s-a

    obinut se numete tip de date derivat, iar cel pe baza cruia s-a construit tipul derivat se numete

    tip de baz.

    Principalii operatori de derivare sunt:

    operatorul *: dac un tip T este un tip de date, atunci T* reprezint tipul de date pointer asociat elementelor de tipul T;

    operatorul []: dac un tip T este un tip de date, atunci T[] reprezint tipul tablou ce conine elemente ale tipului T;

    operatorul (): dac un tip T este un tip de date, atunci T() desemneaz mulimea funciilo ce au ca rezultat o vaoare de tipul T;

    Un pointer asociat la un element de tip T permite memorarea adresei zonei de memorie n care

    elementul respectiv i pstreaz valoarea curent.

    Exemple: char *ps;

    /* ps este o variabil de tip pointer la elemente

    de tip char (permite memorarea adresei unui

    element de tip char)

    */

    double v[10];

    /* v este un tablou cu 10 componente de tip double */

    n cazul n care se utilizeaz tipuri derivate, se pot folosi operatori specifici pentru selectarea

    elementelor tipului de baz. Principalii operatori de selecie sunt:

  • operatorul de adresare indirect (sau operator de derefeniere) specificat de caracterul * (ca i operaia de adunare); dac p este un pointer declarat T *p; atunci *p indic

    valoarea elementului de tip T spre care p indic la momentul curent;

    operatorul de indexare este notat tot cu [], ca i cel de derivare i permite selecia unui element dintr-un tablou; dac T v[10]; este declaraia tabloului v, atunci v[i]

    reprezint elementul (de tip T) din tabloul v cu indicele i;

    operatorul de apel de funcie este notat cu () i el permite apelul unei funcii; dac declaraia unei funcii f este T f(); atunci

    f() reprezint apelul lui f cu parametrii actuali respectivi.

    Se observ c n afar de tipurile pointer i tabou, limbajul C trateaz funciile ca un tip de date

    derivat al rezultatului acestora. Aceasta confer o mare flexibilitate n modul de tratare a

    funciilor n cadrul programelor. De exemplu, se pot defini pointeri la funcii, sau chiar tablouri

    ale cror elemente sunt pointeri la funcii: float a(float);

    /* a este o funcie cu un parametru float care

    returneaz un rezultat de tip float

    */

    int (*f)(float);

    /* f este un pointer la o funcie care are un

    parametru de tip float i care returneaz

    un ntreg

    */

    int (*g[])(float);

    /* g este un tablou cu elemente de tip pointer la

    funcii cu parametru de tip float i care

    returneaz un ntreg

    */

    n afar de tipurile specificate anterior, n limbajul C mai exist dou categorii de tipuri de date

    derivate, pentru care nu exist ns operatori de derivare: tipurile union i struct. Acestea

    permit construirea unui tip de date pe baza mai multor tipuri de baz. Tipul struct corespunde

    tipului record din limbajul Pascal, iar union prii variante a acestuia.

    B) Tipuri de date compuse (structurate)

    Acestea corespund unui alt principiu de clasificare a tipurilor de date ale limbajului C. Din acest

    punct de vedere, tipurile de date pot fi simple (ale cror valori sunt indivizibile), tipuri compuse

    sau structurate (ale cror valori sunt compuse din elemente ce aparin altor tipuri de date) i

    tipuri de date referin sau pointer (ale cror elemete specific adresele de memorie ale altor

    tipuri de date).

    n continuare se prezint o ierarhie a tipurilor de date ale limbajului C conform acestiu

    criteriu de clasificare:

    tipuri simple

  • tipul void

    tipuri ntregi

    tipuri reale

    tipul enumerat tipuri structurate

    tipul tablou

    tipul struct

    tipul union tipuri referin

    Tipurile ntregi i reale sunt tipuri predefinite ale limbajului. Tipul void este de asemenea un tip

    predefinit a crui semnificaie poate fi nimic sau orice, n funcie de context. Principalele

    tipuri ntregi sunt char i int, iar principalele tipuri reale sunt float i double. Se observ

    faptul c tipul caracter (char) este asimilat unui tip ntreg, asupra elementelor sale putndu-se

    deci efectua operaii aritmetice specifice numerelor ntregi.

    Un tip enumerat este un tip utilizator simplu care corespunde tipului enumerat din

    limbajul Pascal. Elementele unui tip enmerat au valor ntregi i pozitive, care se asociaz unor

    nume (constante simbolice). n mod uzual pentru elementele unui tip enumerat se folosesc nume

    simbolice n locul unor valori ntregi.

    Exemplu. Declaraia:

    enum {luni,marti,miercuri,joi,vineri,sambata,duminica} zi;

    declar variabila zi ca fiind de tip enumerat, care poate avea o valoare din mulimea de constante

    simbolice: {luni,marti,miercuri,joi,vineri,sambata,duminica}.

    Un element de tip structur este format dint-un numr de componente care pot avea tipuri de

    date diferite. Fiecare component se specific prin numele su i tipul de date asociat.

    Exemplu. n declaraia:

    struct student {

    char *nume;

    enum {m, f} sex;

    struct {

    int an;

    int luna;

    int zi;

    } data_nasterii;

    int grupa;

    int note[12];

    } st1, sr2;

    se declar variabilele st1 i st2 ca fiind de tip structur cu urmtoarele componente: nume

    (pointer la caractere), sex (enumerat), data_nasterii (structur), grupa (ntreg) i note (tablou).

  • Dei sintaxa tipului union este asemntoare cu cea a tipului struct, el permite ca o

    variabil de acest tip s poat avea o singur valoare dintre mai multe tipuri specificate. n acest

    caz, cmpurile unei uniuni partajeaz aceeai zon de memorie.

    Exemplu.

    union {

    float medie;

    int restante;

    } situatie;

    Variabila situatie poate avea o singur valoare n timpul execuiei unui program, care poate fi de

    tip float (reprezentnd media unui student, dac acesta este promovat) sau de tip int

    (reprezentnd numarul de restane dac este nepromovat).

    5.2 Variabile i clase de memorare

    O variabil este o entitate prin intermediul creia se pot stoca valori n memoria intern

    accesibil unui program, sau se pot accesa aceste valori. Spre deosebire de limbajele algoritmice,

    n limbajele de programare este esenial modul i locul n care se pstreaz valoarea curent a

    unei variabile. Citirea i scrierea valorii curente a unei variabile se realizeaz prin intermediul

    operaiilor de scriere n memorie i citire din memorie.

    O variabil poate fi reprezentat printr-o pereche (, ), unde este

    numele dat de programator variabilei, iar este adresa zonei de memorie alocat de ctre

    calculator pentru pstrarea valorii curente.

    Al treilea element care intervine n cazul variabilelor este tipul de date al valorii curente.

    Pentru gestiunea corect a valorilor unei variabile, nu este sufiecient determinarea adresei de

    memorie a zonei unde se pstreaz valoarea curent, ci i dimensiunea zonei respective, precum

    i modul de codifiare a informaiei. Aceste dou elemente sunt specifice tipului de date asociat

    variabilei.

    A) Declararea i definirea variabilelor

    n limbajul C exist o deosebire important ntre definirea unei entiti dintr-un program

    (variabi, funcie, etc.) i declararea acesteia. Declararea unei variabile are drept scop asocierea

    unui nume de variabil la un tip de date, fr intenia de a rezerva o zon de memorie pentru

    variabil. Definirea unei variabile cere calculatorului rezervarea unei zone de memorie

    (corespunztoare tipului de date asociat variabilei) pentru un nume de variabil. n mod implicit,

    orice definiie de variabil este i o declaraie. n mod suplimentar, la definiia unei variabile se

    poate specifica i o valoare iniial pentru aceasta.

    Observaie. O variabil nu poate exista ntr-un program dac nu a fost definit.

    n mod uzual variabilele se definesc. Declararea unei variabile se poate face, de exemplu, n

    cazul n care programul conine mai multe fiiere surs, iar n fiierul curent se dorete utilizarea

    unei variabile care a fost definit n alt fiier.

  • Exemple. float x, z; /* definire */

    int n = 10; /* definire cu iniializare */

    extern char s[20]; /* declarare */

    Observaie. O variabil nu poate fi definit de dou ori ntr-un program, pentru c cererea de

    alocare a unei zone de memorie se poate face o singur dat.

    n limbajul C exist mai multe moduri de alocare a memoriei pentru variabile, aa nct o

    definiie complet trebuie s specifice i acest lucru, indicnd clasa de memorare a variabilei.

    n afar de clasa de memorare i de tipul de date, n definirea sau declararea unei

    variabile pot s apar i calificatori. Acetia sunt utilizai pentru a specifica dac programul

    poate sau nu modifica valoarea unei variabile, sau dac valoarea variabilei poate fi modificat de

    ali ageni externi programului (alte programe de exemplu).

    Cel mai utilizat calificator este cuvntul cheie const, care specific faptul c valoarea

    variabilei respective nu poate fi modificat n timpul execuiei programului: const int nota_trecere = 5;

    n acest caz, variabila respectiv trebuie iniializat i se comport n timpul execuiei

    programului ca i o constant simbolic.

    Calificatorul volatile specific faptul c valoarea variabilei poate fi modificat n

    timpul execuiei programului de ageni externi, care pot afecta zona de memorie ataat

    variabilei.

    Sintaxa pentru definirea unei variabile este urmtoarea:

    unde:

    - tip reprezint tipul de date asociat valorilor variabilei; - declarator reprezint numele unei variabile, dac aceasta este de tipul respectiv, sau o

    construcie sintactic desemnnd o variabil derivat din tipul respectiv

    - iniializare reprezint valoarea iniial a variabilei; ea trebuie s fie o expresie constant care poate fi evaluat n etapa de compilare a programului;

    definire

    variabil

    calificator

    clas de

    memorare

    tip

    declarator

    = iniializare

    ,

    ;

  • - clasa de memorare este un cuvnt cheie ce poate fi auto, static, extern, sau

    register; n cazul n care lipsete, clasa de memorare se determin din context (n

    general ea poate fi auto sau extern n funcie de locul definirii variabilei).

    n general, compilatorul ncearc s optimizeze codul rezultat n urma compilrii, indiferent de

    calculatorul pe care se compileaz un program. n cazul utilizrii calificatorului volatile,

    compilatorul va fi informat s nu optimizeze secvena respectiv de cod.

    O variabil va fi declarat volatile, ori de cte ori valoarea acesteia va fi modificat

    n afara execuiei programului curent. Exemple cazuri n care este necesar utilizarea

    calificatorului volatile:

    variabil care este mapat pe un port de intrare/ieire;

    o variabil care este comun mai multor procese concurente;

    o variabil care este este modificat de o rutin de ntreruperi;

    o variabil de tip auto, declarat ntr-o funcie care apeleaz funcia sistem setjmp

    i a crei valoare este modificat ntre apelul lui setjmp i apelul corespunztor al

    celeilalte funcii sistem, longjmp.

    Exemple de declaraii volatile:

    - declararea unui obiect volatil prin intermediul unui pointer: volatile T *vptr;

    - declararea unui pointer volatil (a crui adres memorat de pointer se modific): T* volatile ptrv;

    - Pointer volatil pointer la o variabil volatil: int volatile * volatile ptr;

    B) Clase de memorare ale variabilelor

    Corespunztor celor patru cuvinte cheie, exit patru clase de memorare ale valorilor variabilelor.

    Acestea determin domeniul de vizibilitate, precum i durata de via a variabilelor.

    Domeniul de vizibilitate sau domeniul de definiie al unei variabile repreznt acea zon

    dintr-un program n care variabila respectiv este vizibil i poate fi referit prin numele su. n

    mod uzual domeniul de vizibilitate al unei variabile depinde de locul de definire al acesteia.

    n limbajul C exist dou moduri uzuale de definire a variabilelor:

    n cadrul blocurilor, nainte de prima instruciune,

    n afara oricrei funcii, la nivelul unui fiier surs.

    Variabiele definite n afara oricrei funcii se numesc variabile externe sau globale, iar cele

    definite n interiorul blocurilor se numesc variabile locale.

    O variabil extern este vizibil n toate funciile definite n caelai fiier cu variabila, dar

    aflate dupa definirea variabilei, domeniul de vizibilitate fiind reprezentat de corpurile funciilor

    din fiier aflate dup definiia variabilei. O variabil extern poate fi referit n cadrul funciilor

    respective, acesta fiind un mod prin care se poate face transferul de informaie ntre diferite

    funcii ale unui program.

  • Exemplul 5.1. n programul urmtor se folosete o variabil extern de tip tablou n cadrul mai

    multor funcii.

    #include

    float v[10];

    void Citeste(int n) {

    int i;

    for (i=0; i

  • if (!rest)

    { /* bloc NotRest */

    int k;

    float s=0;

    printf(\nNotele sunt: );

    for (k=0; k

  • B) Modul de alocare static sau persistent poate fi aplicat att variabilelor locale, ct i celor externe. n acest caz unei variabile nu i se aloc memorie n zona stiv, ci n zona de date

    statice. Datorit modului de alocare, variabilele alocate static se creaz nainte de nceputul

    execuiei programului (nainte de execuia funcieie main) i se distrug dup sfritul

    execuiei acestuia (dup execuia funcieie main), durata de via fiind dat de intervalul de

    timp al execuiei programului.

    Pentru variabilele externe aceasta reprezint o metod normal de alocare, deoarece ele pot fi

    apelate n mai multe funcii ale unui program. O atenie special o au variabilele locale cu

    alocare static. Deosebirea important ntre o variabil local alocat static i una alocat

    temporar const n faptul c cea alocat static i pstreaz valoarea i dup ieirea din blocul de

    definire, valoarea sa putnd fi regsit la urmtoarea intrare n blocul respectiv.

    Exemplul 5.3. S se calculeze valoarea expresiei:

    e = 1! + 2! + + n!

    Descrierea algoritmului.

    Notnd cu pi produsul 1*2* *i, expresia e se poate scrie:

    e = p1 + p2 + + pn

    unde pn este definit astfel:

    p1=1, pk = pk-1*k, k=2,3, , n

    iar e = sn poate fi definit astfel:

    s1=1, si = si-1+pi, i=2,3, , n

    Secvena din limbajul algoritmic ce corespunde calcului lui s este:

    pentru i 1 la n executa

    s s + pi

    Descrierea programului. Utiliznd o variabil static s, funcia SumaFactoriale permite att

    calculul produselor pk ct i memorarea sumelor pariale si. La fiecare apel al funciei se

    calculeaz un produs parial pi i se adaug la valoarea curent a variabilei s (care i pstreaz

    valoarea ntre apeluri).

    #include stdio.h

    int SumaFactoriale (int i) {

    int k, p = 1;

    static int s = 0;

    for (k=1; k

  • for (i=1; i
  • Observaie. Datorit momentului de timp cnd se realizeaz iniializarea variabilelor cu alocare

    static, expresiile de iniializare trebuie s poat fi evaluate nainte de nceperea execuiei

    programului. Urmtorea secven de program genereaz o eroare de compilare:

    void f() {

    int n = 5;

    static int *p = &n;

    }

    Motivul const n faptul c variabila n are un mod de alocare temporar (pe stiv), pe cnd

    pointerul p are un mod de alocare static (n zona de date). Compilatorul nu poate determina

    valoarea sa de iniializare, deoarece operaia de iniializare se efectueaz nainte de execuia

    programului, cnd variabila n nu exist nc.

    Acum se pot caracteriza clasele de memorare ale variabilelor:

    1) Clasa auto este reprezentat da variabilele declarate local n interiorul blocurilor, avnd

    o metod de alocare temporar a memoriei asociate. Aceasta este clasa implicit de

    memorare pentru variabilele locale.

    2) Clasa register este repezentat de variabilele definite local cu alocare temporar.

    Deosebirea ntre clasa register i auto const n locul de stocare al valorilor

    variabilelor: pentru variabilele din clasa register compilatorul ncearc s memoreze

    valorile curente n registrele generale ale calculatorului, accesul fiind mult mai rapid n

    acest caz; pentru variabilele din clasa auto stocarea se face n memoria intern. Nu ste

    ns sigur ns alocarea valorilor variabilelor auto n registrele generale, datorit

    numrului limitat al acestora. n cazul n care alocarea nu se poate face n registrele

    generale, o variabil register se comport asemntor variabilelor de tip auto.

    3) Clasa extern corespunde variabilelor externe care sunt definite n afara oricrei funcii

    i au o alocare static a memoriei, aceasta fiind i clasa implicit pentru variabilele

    globale. Asupra acestei clase trebuie fcut ns urmtoarea precizare: cuvintele cheie

    auto, register i static se asociaz unor definiii de variabile avnd drept rezultat

    alocarea de memorie pentru variabilele respective, pe cnd cuvntul cheie extern se

    asociaz doar unor declaraii de variabile. Se declar astfel c o anumit variabil a fost

    definit n alt modul de program, dar se dorete extinderea domeniului de vizibilitate i n

    modulul curent. n acest mod poate s apar un element oarecum bizar: definirea unei

    variabile externe nu trebuie s conin cuvtul cheie extern.

    Exemplul 5.4. S se afieze toate numerele palindrome mai mici dect un numr ntreg

    dat (un numr este palindrom dac cifrele egal deprtate de extremiti sunt identice).

    Descrierea programului. Pentru testarea faptului c un numr este palondrom, se vor

    extrage cifrele numrului respectiv i se vor introduce ntr-un vector. Se vor utiliza dou

    funcii, DeterminaCifre pentru determinarea cifrelor unui numr (n baza 10) i

    Palindrom pentru efectuarea testului de numr palindrom. Ambele funcii utilizeaz dou

    variabile globale: vectrul v ce conine cifrele numrului, precum i k ce specific numrul

  • de cifre al numrului curent. Cele dou funcii, precum i funcia main se grupeaz n

    dou fiiere separate.

    /* fisierul main.c */

    #include

    int k, v[10];

    extern int Palindrom();

    void DeterminaCifre (int n) {

    k = -1;

    while (n) {

    v[++k] = n%10;

    n = n/10;

    }

    }

    int main () {

    int i, n;

    printf (\nDati n: );

    scanf (%d, &n);

    for (i=1; i

  • discutat anterior. n cazul n care se aplic variabilelor globale, are au tot tipul static de

    alocare, trebuie fcut urmtoarea precizare: o variabil extern declarat static nu

    mai poate fi vizibil n alte fiiere surs ale unui program, chiar dac se redefinete cu

    acelai nume. Aceasta este o important restricie asupra domeniului de vizibilitate.

    O variabil extern se declar static atunci cnd se dorete ca ea s rmn local

    fiierului unde a fost definit, fr s poat fi importat n alte fiiere. De exemplu, dac o

    problem se descompune n mai multe subprobleme disjuncte, iar fiecare subproblem

    este rezolvat ntr-un fiier distinct, funciile aceluiai fiier pot comunica prin

    intermediul variabilelor globale declarate static, fr teama de a se suprapune cu alte

    variabile externe cu acelai nume din alte fiiere.

    5.3 Tipuri de date predefinite

    Tipurile de date standard sau predefinite ale limbajului C pot fi referite prin intermediul unor

    cuvinte cheie, pentru ele existnd moduri predefinite de reprezentare intern a datelor, precum i

    anumite operaii ce se pot efectua cu aceste date.

    A) Tipuri ntregi

    Valorile unui asemenea tip de date reprezint o submulime a numerelor ntregi, care se pot

    reprezenta intern ntr-un anumit calculator.

    Reprezentarea intern este dependent de calculator, dar n mod uzual ea se face pe doi

    sau patru octei. Indiferent de numrul de octei utilizai, un bit este folosit pentru reprezentarea

    semnului, ceilali bii fiind folosii pentru reprezentarea numrului pozitiv n baza doi.

    n afar de tipul int, mai exist tipuri ntregi derivate, care se specific astfel:

    short, sau short int;

    long, sau long int.

    long long, sau long long int.

    ntre tipurile ntregi exist urmtoarea relaie (sizeof este un operator specific limbajului C ce

    permite determinarea lungimii zonei de memorie alocat de compilator pentru un tip de date sau

    pentru reprezentarea valorii unei expresii): sizeof(short int) sizeof(int) sizeof(long int) sizeof(long long int)

    De asemenea, limbajul C permite utilizarea numerelor ntregi fr semn. Declararea acestora se

    realizeaz prin specificarea cuvntului cheie unsigned n faa tipului de date (unsigned

    int, unsigned short, unsigned long), dar nu modific mrimea zonei de memorie

    alocat elementelor. n cazul numerelor fr semn, toi biii sunt folosii pentru reprezentare.

    Dac se noteaz cu maxint valoarea cea mai mare ntreg pozitiv ce se poate reprezenta,

    domeniul valorilor unui tip ntreg cu semn este:

    -maxint maxint,

    pe cnd domeniul unui tip ntreg fr semn este:

  • 0 2*maxint.

    Observaie. Valorile maxime i minime ale constantelor ntregi sunt dependente de

    implementare. Exist ns nume predefinite (specificate cu ajutorul directivei preprocesor

    define) asociate acestor valori, aflate n fiierul header limits.h. Coninutul acestui fiier

    poate diferi la diversele vesriuni de compilatoere C. In continuare se prezint un fragment dintr-

    un asemenea fiier. Numele predefinite pentru aceste constante sunt SHRT_MIN, SHRT_MAX, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX,

    ULONG_MAX.

    #define SHRT_MIN (-32768) /* minimum (signed) short value */

    #define SHRT_MAX 32767 /* maximum (signed) short value */

    #define USHRT_MAX 0xffff /* maximum unsigned short value */

    #define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */

    #define INT_MAX 2147483647 /* maximum (signed) int value */

    #define UINT_MAX 0xffffffff /* maximum unsigned int value */

    #define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */

    #define LONG_MAX 2147483647L /* maximum (signed) long value */

    #define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */

    Constantele ntregi care se utilizeaz n cadrul programelor folosesc n mod uzual cifrele bazei de

    numeraie 10. Se pot folosi i constante ntregi n bazele de numeraie 8 sau 16, caz n care se

    utilizeaz un prefix: caracterul 0 pentru numerele din baza 8 i grupul de caractere 0x pentru

    numerele scrise n baza 16. Exemple:

    011 reprezint numrul 118 = 910

    11 reprezint numrul 1110 (care este diferit de constanta 011)

    0x11 reprezint numrul 1116 = 1710 (care este diferit de ambele constante precedente).

    Limbajul C permite specificarea n cadrul programelor a constantelor ntregi de tip long sau

    unsigned. Se utilizeaz pentru aceasta sufixele L i U. Exemple:

    1L reprezint constanta ntreg 1 de tip long ;

    1LL reprezint constanta ntreg 1 de tip long long ;

    2U reprezint constanta ntreg 2 de tip unsigned ;

    3LU reprezint constanta ntrag 3 de tip unsigned long .

    Asupra datelor ntregi se pot aplica operatorii aritmetici, care produc un rezultat ntreg.

    Principalii operatori sunt:

    * : nmulire;

    / : ctul mpririi a dou numere ntregi;

    % : restul mpririi a dou numere ntregi;

    + : adunare;

    - : scdere.

    Exemple: 5 / 2 = 2

  • 5 % 2 = 1

    Specificatorii de format utilizai n cadrul funciilor de intrare/ieire cei mai folosii sunt:

    %d i %i pentru numerele ntregi,

    %u pentru ntregii fr semn,

    %o pentru numere n baza 8,

    %x pentru numere n baza 16,

    %hd , %hi, %hu, %ho, %hx pentru ntregii de tip short,

    %ld , %li, %lu, %lo, %lx pentru ntregii de tip long,

    %lld , %lli, %llu, %llo, %llx pentru ntregii de tip long long.

    n mod uzual, numrul de caractere pe care se afieaz un numr ntreg este cel rezultat n urma

    conversiei. Dac se dorete ca afiarea s se realizeze pe un numr specificat de caractere,

    sintaxa pentru specificatorii de format se poate extinde opional astfel: %[][]

    Primul caracter poate fi 0, caz n care cifrele numrului se vor alinia la dreapta i se vor completa

    la stnga cu zerouri (dac este cazul), sau caracterul -, caz n care cifrele se vor alinia la stnga.

    specific numrul de caractere pe care se va afia numrul. De exemplu,

    specificatorul %06d utilizat ntr-o funcie printf pentru afiarea numrului 32 va genera irul

    de caractere 000032, pa cnd specificatorul %06d va genera caracterele 32 urmate de 4 spaii.

    B) Tipuri reale

    Valorile unui tip real de date reprezint o submultime finit a numerelor reale, care se pot

    reprezenta intern pe un anumit calculator. Reprezentarea intern se face n general pe 4, 8 sau 10

    octei, considernd numerele sub forma normalizat: x*10

    n,

    unde x reprezint un numr supraunitar cu o singur cifr la partea ntreaga, diferit de zero,

    numit mantis, iar n reprezint exponentul numrului. ntruct reprezentarea intern se face

    folosind baza de numeraie 2, forma normalizat a acestora este: x*2

    n,

    x reprezentnd un numr subunitar scris n baza 2 (cu cifra prii ntregi = 1).

    n afar de tipul float mai exist dou tipuri reale, care se pot specifica astfel:

    double

    long double

    Utiliznd acelai operator sizeof, relaiile ntre mrimea spaiului de memorie alocat de un

    compilator pentru tipurile reale este:

    sizeof(float) sizeof(double) sizeof(long double)

  • Dup cum s-a precizat n paragraful 1.4.2, n reprezentarea intern a valorilor reale, se reprezint

    separat mantisa i exponentul. Influena celor dou elemente la reprezentarea unui numr real

    este diferit: de numrul de bii alocai mantisei depinde precizia de reprezentare, pe cnd

    numrul de bii alocai exponentului determin domeniul de reprezentare a numerelor.

    Reprezentarea numerelor reale cu virgul flotant a fost standardizat la nceputul anilor

    80, prin standardul IEEE-754 (i revizuit n anul 2008). Standardul descrie trei tipuri de

    reprezentare:

    - reprezentare n simpl precizie (tipul float in limbajul C), unde numerele sunt

    reprezentate pe 4 octei,

    - reprezentare n dubl precizie (tipul double in limbajul C), unde numerele sunt

    reprezentate pe 8 octei,

    - reprezentare n precizie extins, unde numerele sunt reprezentate pe 10 sau 16 octei. Reprezentarea n simpl precizie utilizeaz 32 de bii:

    - 1 bit pentru semnul numrului - 8 bii pentru exponent - 23 bii pentru mantis (al 24-lea bit se omite, fiind 1, partea ntreag a mantisei

    normalizate)

    Pentru exponent nu se mai utilizeaz un bit pentru semn, deoarece se folosete un deplasament

    D = 127 = 28-1,

    astfel nct:

    Exponentul stocat n memorie = Exponentul real D,

    domeniul de reprezentare fiind astfel:

    - Emin = -126 - Emax = 127

    Exponentul se reprezint n complement fa de 2.

    Ordinea de stocare a biilor semnului (pentru toate cele trei tipuri de reprezentare, nu doar

    n cazul reprezentrii n simpl precizie), a exponentului i a mantisei este n ordine

    descresctoare a biilor din cuvntul de memorie: de la bitul 31 la bitul 0. n plus, ordinea de

    stocare a octeilor n cadrul unui cuvnt de memorie poate fi de dou tipuri:

    - litle endian: cel mai puin semnificativ octet se memoreaz la adresa cea mai mic (folosit in sistemele bazate pe procesoare Intel),

    - big endian: cel mai puin semnificativ octet se memoreaz la adresa cea mai mare (folosit in calculatoarele IBM).

    Reprezentarea n dubl precizie (double in limbajul C) utilizeaz 64 de bii:

    - 1 bit pentru semnul numrului - 11 bii pentru exponent - 52 bii pentru mantis (al 53-lea bit se omite, fiind 1)

    Deplasamentul (pentru exponent) este n acest caz, D = 1023 = 210-1, iar domeniul de

    reprezentare este:

    - Emin = -1022 - Emax = 1023

    Reprezentarea n precizie extins este definit n standardul IEEE 754, altfel dect n

    precedentele formate:

    - Specific doar un numr minim de cerine pentru un format extins - Nu impune modul de implementare intern, pentru diferite arhitecturi de calculatoare

    Exist dou categorii de formate:

  • - Reprezentarea n precizie dubl extins (n general pe 80 de bii), utilizat de procesoare, precum Intel i Motorola.

    - Reprezentarea n precizie quadrupl (pe 128 de bii), utilizat de ctre sistemele IBM/370.

    Reprezentarea n precizie dubl extins (long double in limbajul C) utilizeaz 80 de bii.

    Procesoarele Intel utilizeaz acest format, pe cnd procesoarele Motorola utilizeaz 96 bii (16

    nefiind utilizai efectiv).

    Structura de memoria a acestui format cuprinde:

    - 1 bit pentru semnul numrului - 15 bii pentru exponent - 64 bii pentru mantis:

    o Bitul 63 reprezint partea ntreag a mantisei, care nu mai este implicit n acest caz,

    o Biii 62-0 reprezint partea fracionar a mantisei. Deplasamentul (pentru exponent) este:

    D = 16383 = 214

    -1

    Domeniul de reprezentare al numerelor, n acest caz, este: -16382 ... 16383

    - Emin = -16382 - Emax = 16383

    n acest caz, standardul mai permite i reprezentri ale unor valori speciale, care nu pot fi

    reprezentate n celelalte cazuri: infinit i NaN (valoare care nu este numr). Cele dou valori se

    reprezint astfel:

    Constantele reale folosite n cadrul programelor pot avea dou forme: constante cu punct

    zecimal i constante cu format exponenial. Constantele cu punct zecimal folosesc punctul pentru

    separarea prii ntregi de partea fracionar. Constantele cu format exponenial sunt folosite

    pentru numerele de forma x*10n, unde x reprezint o constant cu punct zecimal. Baza de

    numeraie 10 este nlocuit de caracterul e sau E, iar exponentul se scrie la acelai nivel ca i

    baza. De exemplu, numrul 2.73*10-15 se poate scrie ca 2.73e-15 sau 2.73E-15.

    Asupra datelor de tip real se pot aplica operatorii aritmetici (*, /, +, -), care produc un

    rezultat de asemenea real. n cazul n care operanzii au tipuri diferite, se aplic o regul de

    conversie: operanzii care au un tip mai puin prioritar se convertesc la tipul cel mai prioritar.

    Ordinea descresctoare a prioritii tipurilor numerice este: long double, double, float,

    long long int, long int, int, short int.

    Astfel, n cazul expresiei: 5.0/2, se va converti constanta ntreg 2 la constanta real

    2.0 i se va efectua mprirea real (rezultatul fiind 2.5). n cazul expresiei: 5/2, ambii operanzi

    sunt de tip ntreg i mprirea este ntreag (rezultatul fiind 2).

    Specificatorii de format cei mai utilizai n cadrul funciilor de citire sunt:

    %f pentru tipul float,

    %lf pentru tipul double,

    %Lf pentru tipul long double.

  • n cazul operaiilor de scriere, alegerea specificatorilor se face n funcie de tipul de date al

    valorii ce se dorete afisat (care dup operaia de conversie a tipurilor poate fi doar double sau

    long double) i de forma de afiare (cu punct zecimal sau cu format exponenial). Pentru

    afiarea valorilor de tip double se pot utiliza urmtorii specificatori de format:

    %f, pentru reprezentarea cu punct zecimal n format implicit, cu 6 cifre la partea subunitar;

    %e sau %E, pentru reprezentarea exponenial n format implicit, cu o cifr la partea ntrag, 6 cifre la partea subunitar i separarea mantisei de exponent cu ajutorul literei e

    sau E;

    %g sau %G, caz n care se alege reprezentarea cu cel mai mic numr de caractere ntre %f i %e sau %E.

    n cazul valorilor long double, se pot utiliza specificatorii urmtori, care au aceeai

    semnificaie ca i cei anteriori: %lf, %le, %lE, %lg, %lG.

    Ca i n cazul valorilor ntregi, afiarea valorilor reale se poate face specificnd explicit

    numrul de caractere de afiare, numrul de caractere al prii subunitare i eventual modul de

    aliniere. ntre caracterul % i cel care specific tipul de conversie, se pot utiliza urmtoarele

    cmpuri opionale: .

    unde, are aceeai semnificaie ca i n cazul valorilor ntregi,

    reprezint numrul total al cifrelor ce se vor afia, iar reprezint numrul cifrelor

    prii subunitare.

    De exemplu, pentru valoarea real 43.5678, specificatorul %f va afia 43.5678,

    specificatorul %9.2f va afia 43.56, iar specificatorul %12.5e va afia 4.35678e+01.

    C) Tipul caracter

    Tipul caracter reprezint o mulime finit de elemente utilizat de un calculator pentru operaiile

    de intrare/ieire. n mod uzual, aceast mulime are 256 de elemente i conine caractere

    alfabetice (literele mari si mici), caractere numerice (cifrele bazei zece de numeraie), caractere

    speciale (de exemplu: punctul, virgula, paranteze, etc.), precum i caractere neafiabile care au

    un rol de control asupra operaiilor de intrare/ieire.

    Codificarea intern se face n mod uzual pe un octet, reprezentnd numrul (n baza doi)

    pe care l ocup fiecare caracter ntr-o tabel predefinit, numit tabela de caractere. Poziiile

    caracterelor n aceast tabel ncep cu numrul 0 i se termin cu 255.

    Din punct de vedere al tipurilor de date, exist trei categorii de tipuri caracter: char,

    unsigned char i signed char, toate reprezentnd valori pe un octet. Dei standardul

    limbajului C nu specific, cele mai multe compilatoare asimileaz tipul char cu tipul

    unsigned char. Tipul signed char este asimilat n mod uzual tipurilor ntregi i conine

    valori ntre -127 i 127.

    Constantele de tip caracter folosite n cadrul programelor pot fi de mai multe tipuri:

    1. Caractere afibile, care se reprezint ntre dou apostrofuri (cu excepia apostrofului i a caracterului \). De exemplu:

  • a A 3 * (

    2. Secvene escape simple, formate din dou caractere, care ncep cu caracterul \:

    a. \, \, \?, \\ (reprezint al doilea caracter)

    b. \a, \b, \f, \n, \r, \t, \v (reprezint caractere de control neafiabile: alert,

    backspace, form feed, new line, carriage return, horizontal tab, vertical tab)

    3. Secvene escape octale, care ncep cu caracterul \ i sunt urmate de o secven de

    maxim trei caractere octale, reprezentnd poziia caracterului respectiv n tabela de

    caractere (de exemplu \23). Caracterul \0 reprezint caracterul nul (cu codul 0).

    4. Secvene escape hexazecimale, care ncep cu caracterele \x i sunt urmate de o

    secven de maxim trei caractere hexazecimale, reprezentnd poziia caracterului

    respectiv n tabela de caractere (de exemplu \xa1).

    Pentru datele de tip caracter, specificatorul de format este %c.

    Observaie. Elementele de tip caracter sunt asociate n limbajul C tipurilor ntregi de date, astfel

    nct specificatorii de format i operatorii specifici numerelor ntregi se pot aplica i asupra

    caracterelor. n acest caz se folosete grupul de caracere hh:

    %hhd , %hhi, %hhu, %hho, %hhx

    D) Tipul void

    Tipul void nu a fcut iniial parte din mulimea tipurior fundamentale n vaianta Kernighan i

    Ritchie. El a fost adugat ulterior pentru a uniformiza tratarea tipurilor de date derivate, inclusiv

    a funciilor.

    Din punct de vedere al tipurilor de date, el reprezint o mulime vid de constante.

    Spre deosebire de celelalte tipuri fundamentale, utilizaea tipului void este supus

    urmtoarelor restricii:

    variabilele simple nu pot fi de tipul void; de exemplu, declaraia urmtoare este greit: void x, z;

    tipul void poate fi derivat doar cu ajutorul operatorilor * i (), cu alte cuvinte, se pot folosi doar pointeri la void, precum i funcii care nu returneaz un rezultat; urmtoarele

    declaraii sunt corecte: void *p;

    void f(int n);

    de asemenea, tipul void poate fi utilizat n antetul unei funcii sau la declararea acesteia, pentru a specifica lipsa parametrilor formali; de exemplu:

    float Citeste(void);

    Dac utilizarea tipului void n cadrul funciilor are o interpretare simpl, nu acelai lucru se

    ntmpl i n cazul pointerilor la void. Principalul raionament care a condus la utilizarea

    pointerilor la void const n faptul c el permite construcia tipurilor de date generice. Un tip

    de date generic este o generalizare a noiunii de tip de date n sensul c el permite specificarea

    doar a operaiior ce se pot efectua asupra elementelor unui tip de date, nu i a valorilor propriu-

    zise ale elementelor.

  • Un exemplu elocvent de utilizare a tipului void* este acela al gestionrii obiectelor

    dinamice cu ajutorul pointerilor. Pentru a crea un obiect dinamic trebuie alocat zona de

    memorie necesar acestuia, iar funcia cea mai des utilizat este malloc care are urmtoarea

    declaraie (n fiierul alloc.h): void* malloc (size_t dim);

    Aceast funcie rezarv o zon de memorie de dim octei i reurneaz adresa de nceput a ei.

    Adresele de memorie ntr-un program C pot fi gestionate cu ajutorul pointerilor. ntruct aceeai

    funcie este folosit pentru orice tip de pointer, tipul returnat de malloc este void*, urmnd ca

    n program s se realizeze o conversie a acestui tip la tipul folosit (cu ajutorul unui operator de

    converise). De exemplu: float* p;

    p = (float*)malloc(sizeof(float));

    5.4 Tipul enumerat. Construcia typedef.

    Tipul enumerat este un tip de date utilizator, dar are o poziie singular printre tipurile de date

    ale limbajului C, pentru c nu este un tip compus, i nici derivat din alte tipuri de date. Din punct

    de vedere al reprezentrii interne ale valorilor de tip enumerat, precum i al operatorilor ce se pot

    aplica asupra acestor elemente, tipurile enumerate sunt considerate tipuri de date ntregi.

    Constantele de tip enumerat se specific n cadrul programelor prin nume simbolice,

    acesta fiind i principalul avantaj al utilizrii tipurilor enumerate: posibilitatea specificrii unor

    valori ntregi prin nume simbolice. Definirea unui tip enumerat se face prin specificarea

    constantelor simbolice care formeaz mulime elementelor sale, conform urmtoarei sintaxe:

    unde:

    identificatorul specificat dup cuvntul cheie enum reprezint numele tipului de date enumerat ce se definete sau se declar, pe cnd identificatorii dintre acolade reprezint

    numele simbolice ale elementelor tipului respectiv;

    reprezint o expresie ntreag constant i este o expresie de iniializare opional pentru elementele unui tip enumerat.

    Exemplu. n secvena urmtoare se definesc tipurile de date enumerat logic, zi i note_limita: enum logic {false, true};

    enum zi {luni, marti, miercuri, joi, vineri, \

    tip

    enumerat enum ident { } ident

    ident

    ,

    constant =

  • sambata, duminica};

    enum note_limita {nota_trecere=5, nota_bursa=8};

    Observaii. Definiia sintactic anterioar necesit cteva informaii suplimentare:

    1) n cazul n care elementele mulimii nu sunt specificate, aceasta reprezint o declaraie i nu o definiie. Limbajul C permite o asemenea declaraie (care poate fi utilizat eventual n

    cadrul altor declaraii sau definiii de tipuri de date utilizator), cu observaia c n program

    trebuie s existe o definiie a tipului enumerat nainte de prima definiie a unei variabile

    aparinnd tipului respectiv. De exemplu, linia urmtoare reprezint declararea unui tip

    enumerat: enum valori;

    2) Deoarece tipurile enumerate sunt asociate unor tipuri ntregi, valorile constantelor simbolice sunt numere ntregi ce pot fi specificate explicit de ctre programator prin valorile de

    iniializare, sau pot fi ataate n mod automat de ctre compilator. n acest din urm caz,

    valorea atribuit pentru fiacare constant simbolic este mai mare cu 1 dect valoarea

    constantei precedente, valoarea primei constante fiind implicit zero. n exemplul urmtor se

    precizeaz valorile constantelor simbolice din definirea unor tipuri enumerate: enum A {x, y, z}; /* x=0, y=1, z=2 */

    enum B {a=2, b, c=7, d, e}; /* a=2, b=3, c=7, d=8, e=9 */

    3) n cazul unei definiii, numele tipului enumerat este opional. n cazul n care acesta lipsete, tipul respectiv reprezint un tip anonim. Un tip anonim nu poate fi dect definit, nu i

    declarat, deoarece el nu poate fi ulterior identificat n cadrul programului. Din acest motiv,

    tipul anonim poate fi utilizat n dou situaii uzuale: (a) fie mpreun cu definirea unor

    variabile ale tipului respectiv, care nu mai pot fi definite ulterior, fie (b) doar pentru definirea

    unor constante simbolice ce pot fi referite direct prin numele lor n acea zona de program ce

    corespunde domeniului de definiie a tipului enumerat respectiv.

    Exemplul 5.5. Programul urmtor, care afieaz studenii restanieri i cei bursieri dintr-o

    grup, utilizeaz a doua situaie uzual.

    #include

    enum {nota_trecere=5, nota_bursa=8};

    /* domeniul de definitie al constantelor nota_trecere

    si nota_bursa este global in fisierul curent */

    int main () {

    int i, n;

    printf (\nDati numarul de studenti: );

    scanf (%d, &n);

    for (i=0; i

  • printf (\n%d est restantier, i+1);

    else (nota >= nota_bursa)

    printf (\n%d est bursier, i+1);

    }

    return 0;

    }

    Unul dintre avantajele utilizrii n acest mod a constantelor simbolice const n modificarea

    simpl a programelor la care anumite constante trebuie schimbate. De exemplu, pentru

    programul precedent, n cazul n care se modific nota pentru burs, va trebui modificat doar

    linia din program n care se definete valoarea constantei, nu i n tot restul programului.

    Definirea unor variabile aparinnd unui tip enumerat se poate face fie n cadrul aceleiai

    definiii, fie ntr-o definiie separat, ce succede definiiei tipului respectiv. n cazul n care

    variabilele se definesc mpreun cu tipul enumerat, acestea se specific dup definiia tipului. De

    exemplu, n definiia urmtoare se definete tipul enumerat TipEnumerat, mpreun cu

    variabilele t1 i t2: enum TipEnumerat {x=3, u, v} t1, t2;

    n cazul n care variabilele se definesc separat, specificarea tipului enumerat se face prin numele

    asociat acestuia precedat de cuvntul cheie enum. Avantajul unui asemenea mod de definire

    const n faptul c un tip de date enumerat se definete o singur dat n program, dar poate fi

    utilizat de cte ori este nevoie.

    Pentru exemplul precedent, urmtoarele dou definiii sunt echivalente cu cea precedent: enum TipEnumerat {x=3, u, v};

    enum TipEnumerat t1, t2;

    pe cnd sevena urmtoare este greit: enum TipEnumerat {x=3, u, v};

    TipEnumerat t1, t2;

    Limbajul C permite ca unui anumit tip de date s i se poat asocia un nume, care s poat fi

    utilizat n definiille i declaraiile variabilelor dintr-un program ca i numele unui tip de date

    predefinit. De exemplu, secvena urmtoare este echivalent cu ultimele definiii corecte: typedef enum {x=3, u, v} TipEnumerat;

    TipEnumerat t1, t2;

    Aceast operaie se poate realiza cu ajutorul construciei typedef, care definete un tip de date

    utilizator, n sensul c asociaz un nume la un tip de date ce poate fi definit cu ajutorul sintaxei

    limbajului. n majoritatea cazurilor (de exemplu, o excepie o constituie definirea unei mulimi

    de pointeri la un tip de funcii), construcia are o sintax de forma urmtoare:

    unde reprezint tipul de date definit, iar reprezint

    numele asociat acestuia.

    identificator definire

    tip typedef definire tip

  • Observaii.

    1) Construcia typedef nu creeaz o zon de memorie, ea doar asociaz un nume la un tip de

    date.

    2) Tipul de date specificat ntr-o construcie typedef poate fi un tip de date predefinit,

    definirea unui tip utilizator conform unei sintaxe specifice, sau numele unui alt tip de date

    definit anterior ntr-o alt construcie typedef.

    Exemplul 5.6. Secvena urmtoare de program definete o funcie ce permite planificarea

    activitilor dintr-o sptmn.

    typedef enum {luni, marti, miercuri, joi, vineri, \

    sambata, duminica} ZiSaptamana;

    void Planifica (ZiSaptamana ziua) {

    if (ziua >= luni && ziua

  • 5.5 Probleme

    5.1. Declarai o funcie cu numele f1 care returneaz un pointer la double i are doi parametri

    de tip int i double. Declarai apoi un pointer cu numele f2 la o funcie care returneaz

    un double i are doi parametri de tip int i double.

    5.2. Utilizai construcia typedef pentru a defini un tip de date cu numele PF, asociat

    mulimii pointerilor la funcii care returneaz void i au un parametru de tip int.

    Definii apoi doi pointeri de acest tip, cu numele pf1 i pf2.

    5.3. Definii un pointer v1 la un tablou cu 10 componente de tip int. Definii apoi un tablou

    v2 de 10 componente care sunt pointeri la int.

    5.4. Definii o structur cu numele student care s conin urmtoarele cmpuri: - nume student - grupa - an de studiu - dac este promovat sau restanier - media anual a sa, dac studentul este promovat - numrul de restane, dac studentul este restanier.

    5.5. S se modifice programul din exemplul 5.4, astfel nct s permit i afiarea tuturor numerelor mai mici dect k, pentru care suma cifrelor este ptrat perfect (adic exist un

    numr natural p, astfel nct suma cifrelor numrului este p2).

    5.6. S se modifice programul din exemplul 5.5, astfel nct s permit o afiare mai detaliat a studenilor: cu burs de merit, cu burs obinuit, nebursieri dar nerestanieri, restanieri

    cu o restan, cu dou restane, cu trei restane, cu mai multe de trei restane.

    5.7. Generarea numerelor pseudo-aleatoare se poate realiza cu ajutorul urmtorului ir: a0 = 0,

    an+1=(an + p) % m, unde p i m sunt numere ntregi 1. irul generat de relaia anterioar

    este un ir ciclic: dup un numr de ori, care depinde de p i m, valorile se repet. S se

    scrie un program care citete valorile lui p i m i determin dac irul ciclic generat an

    este uniform, adic va conine mulimea de numere {0, 1, ..., m-1}. De exemplu, pentru

    p=3 i m=5, irul generat va fi 0, 3, 1, 4, 2 (este uniform), iar pentru p=5 i m=20, irul

    generat va fi 0, 15, 10, 5 (nu este uniform).

    5.8. S se scrie un program pentru decriptarea unei secvene de numere ntregi, folosind dou chei cu valori complexe. Se consider cheile X i B, reprezentnd doua valori complexe,

    specificate prin perechile (XRe, XIm) i (BRe, BIm). S se determine i s se afieze, dac

    este posibil, un numr natural n i secvena de numere ntregi a0, a1, ..., an, aa nct:

    X = a0 + a1B + a2B2 + ... + anB

    n

    Dac n i secvena de numere ntregi a0, a1, ..., an nu se pot determina, se va afia un mesaj

    de eroare.