Borland c Manual

download Borland c Manual

of 113

description

Borland c Manual

Transcript of Borland c Manual

  • BORLAND

    C

    Versiunea 2.0

    Manual de utilizare

  • STRUCTURA GENERAL A UNUI PROGRAM C

    1.1. ISTORIC, CONCEPIE, EVOLUIE

    Limbajul C a fost finalizat n 1972 de Dennis M. Ritchie i Brian W.

    Kernighan de la firma american Bell Laboratories.

    Prima versiune a limbajului se numete BCPL apoi urmtoarele poart

    numele de A, B i C. Cei doi autori au dezvoltat aceste prime versiuni n

    jurul sistemului de operare UNIX.

    La vremea respectiv din aproximativ 13000 linii surs ale UNIX-ului

    doar 200 de linii surs nu erau scrise n limbajul C. De acest fapt se

    leag detractorii limbajului care spun c limbajul C nu este un limbaj

    deosebit ci doar un fel de limbaj oficial al sistemului de operare UNIX.

    n anul 1978 apare manualul The C Programming Language care este de

    fapt i prima standardizare a limbajului. Cei doi autori intr astfel n

    istorie...

    Dup anul 1980 odat cu dezvoltarea hardware apar i primele PC-uri

    iar acestea implic i produse software adecvate. Principalele firme

    productoare de sofware -MICROSOFT i BORLAND - au dezvoltat unelte

    adecvate pentru programarea i utilizarea limbajului C. Deocamdat firma

    BORLAND deine supremaia prin versiunile mediului BORLAND C. Cele mai

    folosite sunt versiunile 2.0, 3.1, 4.0. n ultimii doi ani au aprut aa

    numitele medii visuale: VISUAL C versiunile 4.5 i 5.0 care sunt de fapt

    extensii ale mediului BORLAND C adaptate programrii orientate obiect i

    interfeei grafice WINDOWS 95. Mediile de programare BORLANDC pot compila 3

    tipuri de programe surs C:

    fiiere cu extensia .C (fiiere cu prg. standard C); fiiere cu extensia .CP (fiiere cu prg. C+,); fiiere cu extensia .CPP (fiiere cu programe C++).

    Menionm c limbajul C++ a fost elaborat de Bjarne Stroustrup de la

    AT&T. El este un superset al limbajului C i permite principalele concepte

    ale programrii prin abstractizarea datelor i programrii orientate spre

    obiecte.

    Limbajul C este un limbaj hibrid avnd faciliti caracteristice

    limbajelor de asamblare ct i faciliti ale limbajelor de nalt nivel.

    Cteva dintre principalele caracteristici ale limbajului C sunt:

    portabilitate: chiar dac acest concept nu-i definit foarte riguros spunem c un program este portabil dac el poate fi transferat uor de

    la un tip de calculator la altul; limbajul C este un astfel de limbaj;

    flexibilitate: compilatorul face un numr mai redus de controale (face multe conversii implicite);

    programare structurat: limbajul are principalele structuri ale programrii structurate: structura secvenial, structura iterativ i

    structura de selecie;

    compactizare: unele instruciuni sunt scrise foarte compact; de exemplu i:=i+1 se poate scrie mai scurt ca i++;

    lucrul pe bii i calcule cu adrese.

    CONCEPTUL DE FUNCIE

    Un program C se compune din una sau mai multe funcii. Funcia este o

    unitate lexical de program compilabil independent.

    Una dintre funcii este funcie principal, numele ei este predefinit

    i anume main.

    Execuia programului ncepe cu prima instruciune din funcia

    principal.

    Dm n continuare 2 exemple de structuri de program (fiiere surs):

  • [directive de preprocesare]

    [declaraii de date globale]

    [declaraie prototip funcia f1 . . .

    declaraie prototip funcia fn]

    [Void main (void)

    { declaraii

    instruciuni instruciuni

    }]

    [Implementare funcia f1]

    . . .

    [Implementare funcia fn]

    [directive de preprocesare]

    [declaraii de date globale]

    [declaraie prototip funcia f1 . . .

    declaraie prototip funcia fn]

    [Void main (void)

    { declaraii

    instruciuni instruciuni

    }]

    [implementare funcia f1]

    . . .

    [implementare funcia fn]

    Funcia principal main este obligatorie pentru orice program

    celelalte elemente fiind optionale. Pentru ca o anumit funcie s poat fi

    apelat e necesar ca ea s aib declarat prototipul dac implementarea

    (definiia) ei se afl dup funcia main (exemplul 1). Dac funcia

    principal se afl la sfritul fiierului atunci nu mai e necesar

    prototipul funciei apelate ci doar implementarea ei (exemplul 2).

    Comparnd structura unui program C cu structura unui program PASCAL se

    observ nivelul de imbricare diferit. n PASCAL apare o imbricare a

    procedurilor i funciilor pe cnd n C nu exist o astfel de imbricare

    (rmne la nivelul fiecrei funcii dac e cazul).

    PASCAL C

    ...

    1.2.1. Definiia unei funcii

    Definiia unei funcii n limbajul C se compune din antet i corp. O

    funcie poate fi apelat dac este precedat de definiia sau de prototipul

    ei. Aceste lucruri care sunt valabile n limbajul C se regsesc i n

    limbajul C++.

    Antet i prototip

    Antetul simplificat al unei funcii n C are formatul:

    tip nume_funcie (lista_parametrilor_formali)

    unde: tip - reprezint tipul valorii returnate de funcie sau dac

    funcia nu

  • returneaz nici o valoare se pune cuvntul cheie void;

    nume_funcie - reprezint un identificator clasic format dintr-un

    mixaj

    de litere i cifre, primul caracter fiind obligatoriu litera;

    printre litere se numr i liniua de subliniere;

    lista_parametrilor_formali nume de variabile separate prin virgule.

    Exemple:

    1) double radical (double x) // calculeaza radacina patrata din x si returneaza valoarea gasita

    2) double radical_n (double x, int n) // calculeaza radacina de ordinul n din x

    Prototipul unei funcii este asemntor antetului dar la sfrit se

    pune caracterul ;

    1.2.3. Corpul unei funcii

    Corpul unei funcii C se compune din declaraii de variabile locale

    i instruciuni scrise ntre acolade conform figurii de mai jos.

    { declaraii

    instruciuni

    }

    i pentru c autorii limbajului C consider c un limbaj de

    programare se nva mai repede scriind i executnd programe ct mai

    timpuriu vom da un mic exemplu de funcie.

    int modul (int i) // determina valoarea absoluta a intregului i si returneaza aceasta valoare

    { if (i < 0) return i; if (i = = 0) return 0; else return i; }

    1.3. CONSTRUCIILE DE BAZ ALE LIMBAJULUI

    1.3.1. Caractere

    Limbajul C folosete setul de caractere al codului ASCII care se

    codific prin numere ntregi din intervalul [0,127], adic 128 de coduri.

    Un astfel de ntreg se pstreaz pe un BYTE (OCTET) adic pe 8 bii.

    Mulimea caracterelor se mparte n trei grupe:

    - caractere negrafice (coduri cuprinse ntre 00=NUL i 31) i

    127=DEL;

    - spaiu (codul 32);

    - caractere grafice (coduri cuprinse ntre 33 i 126).

    Caracterele grafice se mpart la rndul lor n:

    litere mari (coduri ntre 65 i 90);

    litere mici (coduri ntre 97 i 122);

    cifre (coduri ntre 48 i 59);

    caractere speciale (celelalte coduri).

    Caracterele negrafice au diferite funcii. Astfel codul 10 semnific

    LF (Line Feed), adic deplaseaz cursorul pe linia urmtoare n coloana 1,

    iar codul 13 semnific CR (Carriage Return) adic deplaseaz cursorul n

    coloana 1 aceeai linie. n limbajul C combinaia celor dou caractere se

    noteaz prin:

    \n

    i are semnificaia trecerii cursorului la linie nou i coloana 1

    (newline).

    Tabulatorul orizontal (deplasarea cursorului peste un anumit numr de

    poziii) se precizeaz prin notaia:

  • \t

    S mai precizm c urmtoarele 3 caractere: spaiu, newline i

    tabulator orizontal se mai numesc spaii albe (white spaces).

    1.3.2. Nume

    n limbajul C, un nume este o succesiune de litere i eventual

    cifre, care ncepe cu o liter. Ca lungime un nume poate fi orict de lung

    dar numai primele 32 de caractere se iau n considerare. Folosind notaia

    BNF (vezi anexa) un nume se poate defini recursiv, ca mai jos:

    ::= | |

    ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Z|

    a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|z|_

    ::= 0|1|2|3|4|5|6|7|8|9|

    Numele se folosesc pentru denumirea variabilelor, tablourilor,

    funciilor, etc.

    Exemple:

    A, _start, a_, matrice, matrice_patratica.

    Dm i cteva contraxemple:

    &B - conine caracterul &;

    x+y - conine caracterul +;

    1.3.3. Cuvinte cheie

    Un cuvnt cheie este un cuvnt mprumutat din limba englez,

    care are un neles predefinit. Aceste cuvinte se scriu cu litere mici. 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 un

    nume. Lista cuvintelor cheie se d n anexa de la sfritul crii. Sensul

    fiecrui cuvnt cheie va rezulta la definirea construciei n care se

    utilizeaz.

    Exemple:

    for, do, if, while, else, break, return, int, long, double,

    static, extern.

    1.3.4. Tipuri de baz

    n limbajul C distingem cteva tipuri predefinte de date care se mai

    numesc tipuri de baz. n general un tip de dat are trei atribute bine

    conturate:

    mulimea valorilor;

    reprezentarea (intern i extern)

    comportamentul (adic operaiile ce se pot face cu acel tip).

    n tabelul de mai jos dm cuvntul cheie, mulimea valorilor,

    reprezentarea intern.

    Reprezentarea intern

    Cuvnt cheie Mulimea valorilor Lungime (bii) Formatul intern

    int ntregii din [-215; 215-1] 16 reprezentare

    binar

    short ntregii din [-215; 215-1] 16 reprezentare

    binar

    long ntregii din [-231; 231 - 1] 32 reprezentare binar

    unsigned ntregii din [0; 216-1] 16 reprezentare binar

    char 8 cod ASCII

    float [-3.4*10-38; 3.4*1038] 32 virgul flotant

    simpl precizie

    double [-1.7*10-308; 1.7*10308] 64 virgul flotant

    dubl precizie

  • Facem precizarea c se poate folosi i combinaia unsigned long

    pentru ntregii fr semn n dubl precizie.

    Cu tipurile de baz se pot defini i tipuri utilizator folosind

    instruciunea struct.

    1.3.5. Constante

    O constant are un tip i o valoare. Att tipul ct i valoarea

    unei constante se definesc prin caracterele care compun constanta

    respectiv.

    Constant ntreag zecimal

    O constant ntreag este un ir de cifre care eventual este

    prefixat de un semn (+ sau -) i postfixat de litera L sau l. O constant

    ntreag se reprezint n binar pe 16 sau 32 de bii. Sufixul L sau l

    foreaz reprezentarea pe 32 de bii.

    Constant ntreag octal

    O constant ntreag octal este un ir de cifre octale (cifre

    cuprinse ntre 0 i 7) precedat de un zero nesemnificativ.

    Constant ntreag hexazecimal

    O constant ntreag hexazecimal este un ir de cifre hexazecimale

    prefixat cu 0x sau 0X.

    Exemple:

    Reprezentare Interpretare

    12345 ntreg zecimal reprezentat n binar pe 16 bii

    -12345 ntreg zecimal reprezentat n binar pe 16 bii

    12345L ntreg zecimal reprezentat n binar pe 32 bii

    012345 ntreg octal reprezentat n binar pe 16 bii (o cifr

    octal pe 3 bii)

    0xabcd ntreg hexa reprezentat n binar pe 16 bii (o cifr pe 4

    bii)

    12345678 ntreg zecimal reprezentat pe 32 de bii

    Constant flotant

    O constant flotant este un numr raional care se compune din

    urmtoarele elemente:

    un semn (+ sau -) care poate lipsi pentru numerele pozitive;

    o parte ntreag care poate fi i vid;

    o parte fracionar care poate fi i vid;

    un exponent care poate fi i vid.

    Prezena prii fracionare este suficient pentru ca numrul

    respectiv s reprezinte o constant flotant. Absena prii fracionare

    implic prezena prii ntregi i a exponentului.

    Partea ntreag reprezint o succesiune de cifre zecimale.

    Partea fracionar se compune din caracterul punct urmat de o succesiune de

    cifre zecimale, care poate fi i vid. Exponentul se compune din litera e

    sau E urmat de un + sau -, opional, i un ir de cifre zecimale.

    Constantele flotante se pstreaz n format flotant dubl

    precizie.

    Exemple:

    3.14; 0.314e1; 3.1415926; 2.71828; 2.; 271828E-5.

    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.

  • Exemple:

    Constant caracter valoare cod ASCII

    A 65

    B 66

    a 97

    0 48

    9 58

    * 77

    Anumite caractere negrafice au notaii speciale la scrierea

    crora se utilizeaz caracterul backslash (\). Dm n continuare un tabel

    cu cele mai folosite caractere negrafice:

    Caracter Reprezentare ca i constant caracter Valoare cod ASCII

    Backspace \b 8

    Retur de car \r 13

    Newline \n 10

    Apostrof \ 39

    Backslash \\ 92

    Tabulator vertical \v 11

    Salt pagin imprimant \f 12

    Carcterul NUL \0 0

    Constant ir de caractere

    O constant ir de caractere este o succesiune de zero sau mai

    multe caractere delimitate prin ghilimele. Ghilimelele nu fac parte din

    irul de caractere.

    Exemple:

    123; Limbajul C; sir de caractere; sir\; (irul vid).

    Constanta ir de caractere se reprezint n memoria

    calculatorului printr-o succesiune de octei n care se pstreaz codurile

    ASCII ale caracterelor irului, iar ultimul octet conine caracterul NUL

    care marcheaz sfritul irului de caractere.

    Dup cum se observ din exemplele date putem s folosim i convenia

    cu backslash.

    De reinut c X i X reprezint construcii diferite.

    1.3.6. Variabile simple

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

    timpul execuiei programului care o conine. Unei variabile i se ataeaz

    un nume prin intermediul cruia o putem referi sau modifica. Totodat

    valorile pe care le poate lua o variabil trebuie s aparin aceluiai

    tip. Corespondena dintre numele i tipul unei variabile se realizeaz

    printr-o construcie special numit declaraie.

    Dup modul de grupare datele sunt:

    date izolate denumite i variabile simple;

    date grupate:

    - mulimi ordonate de date de acelai tip la care ne referim cu

    indici,

    - structuri n care date de tipuri diferite se grupeaz.

    Declaraia de variabil simpl are formatul general:

    tip list_de_nume;

    unde list_de_nume este format fie dintr-un singur nume fie din mai

    multe, separate prin virgule.

  • n limbajul C trebuie declarate toate variabilele nainte de a fi

    utilizate.

    Exemple:

    int a,b,c; // a, b, c sunt variabile de tip int reprezentate in binar pe 2 octei; float x,y,z; // x, y, z sunt variabile de tip float in format flotant simpla precizie pe 32 de

    bii; char car; // car este o variabila de tip char pe 1 octeti poate conine coduri ASCII; long i,j,k; // i, j, k sunt variabile de tip long in format binar pe 32 de bii.

    Tablouri

    Un tablou ca orice variabil simpl trebuie declarat nainte de a fi

    utilizat. Dac referirea la elementele tabloului se face cu un singur

    indice se spune c tabloul este unidimensional (se mai numete vector);

    dac referirea se face cu doi indici tabloul se numete

    bidimensional(matrice); iar cu n indici tabloul este n-dimensional.

    Declaraia unui tablou n forma cea mai simpl este:

    tip nume[l1][l2]...[ln];

    unde:

    l1, l2, ... ln sunt expresii constante care au valori ntregi ce

    pot fi evaluate de compilator la ntlnirea lor.

    Evident c se pot declara mai multe tablouri deodat i atunci numele

    de tablouri se pot nirui ntr-o list, fiecare separat prin virgul.

    Exemple:

    int t[5]; // s-a declarat un tablou unidimensional de 5 componente; float a[5][3]; // s-a declarat un tablou bidimensional de 5*3=15 componente;

    La elementele unui tablou ne referim prin variabile cu indici.

    O variabil cu indici se compune din numele tabloului urmat de unul sau mai

    muli indici, fiecare indice fiind inclus n paranteze drepte. Numrul

    indicilor definete dimensiunea tabloului. Indicii sunt expresii care au

    valori ntregi. Limita inferioar a indicilor este zero. Astfel dac t este

    tabloul de tip int n exemplul de mai sus, elementele lui sunt:

    t[0], t[1], t[2], t[3], t[4].

    n cazul matricii a declarate mai sus elementele ei vor fi:

    prima linie: a[0][0], a[0][1], a[0][2];

    a doua linie: a[1][0], a[1][1], a[1][2];

    ...

    a cincea linie: a[4][0], a[4][1], a[4][2];

    Deci pentru dimensiunea k indicele variaz ntre 0 i lk-1.

    Repartizarea memoriei pentru un tablou se face astfel: pentru

    fiecare element al tabloului se repartizeaz o zon de memorie necesar n

    conformitate cu tipul tabloului respectiv (pentru tipul int cte 2 octei,

    pentru tipul float cte 4 octei, etc). Numele unui tablou este un pointer,

    el poate fi utilizat n diferite construcii i el are ca valoare adresa

    primului su element.

    n desenul urmtor se indic repartizarea memoriei pentru

    tabloul t din exemplul de mai nainte:

    t

    adresa lui

    t[0]

    t[0] t[1] t[2] t[3] t[4]

    Comentariu

  • n limbajul C un comentariu se scrie ntre /* i */ pe oricte

    rnduri. ntre /* i */ se poate scrie o succesiune arbitrar de caractere,

    care ns nu poate s conin secvena de terminare (adic */). Comentariul

    poate fi inserat ntr-un program n orice poziie n care este legal s

    apar un caracter alb. El constituie o explicaie pentru programator sau

    pentru utilizator. Compilatorul nu interpreteaz comentariul n nici un

    mod. Comentariul se recomand a fi inserat n punctele n care

    programatorul poate lmuri prin explicaii, anumite aspecte ale procesului

    de calcul sau ale datelor utilizate. n mediile BORLAND C exist i o alt

    convenie de a marca un comentariu la nivelul unui rnd cu ajutorul a dou

    caractere slash (//), convenie pe care am folosit-o de altfel n exemplele

    anterioare.

    1.4. PREPROCESARE

    Un program surs C poate fi prelucrat nainte de a fi compilat.

    O astfel de prelucrare se numete preprocesare sau precompilare. Acest

    lucru se realizeaz printr-un program special numit preprocesor. Acesta

    este apelat automat nainte de a ncepe compilarea.

    Preprocesorul limbajului C realizeaz urmtoarele:

    includeri de alte fiiere (de obicei fiiere surs);

    definiii i apeluri de macrouri simple;

    compilare condiionat.

    1.4.1. Includerea unui fiier surs

    Fiierele surs pot fi incluse cu ajutorul directivei include.

    Dou formate se folosesc pentru a include un fiier surs n locul n

    care apare directiva (de obicei se pune la nceputul programului):

    #include specificator_de_fisier

    sau

    #include

    unde: specificator_de_fiier trebuie s fie un nume de fiier valid

    din punct de vedere al sistemului de operare DOS i de obicei are extensia

    .h sau .c.

    Prima variant este folosit de obicei cnd fiierele de inclus sunt

    furnizate de utilizator; dac nu este indicat calea atunci fiierele sunt

    cutate n directorul curent i apoi n directoarele setate pentru

    directiva include.

    A doua variant este folosit pentru ncorporarea unui fiier

    standard care se caut n directoarele setate pentru directiva include (de

    obicei astfel de fiiere standard sunt livrate n biblioteci ataate

    mediului de programare C).

    Odat localizat fiierul dintr-o directiv include se

    nlocuiete aceasta prin textul fiierului surs. Deci compilatorul nu va

    mai ntlni directiva include ci textul fiierului inclus de preprocesor.

    Includerile de fiiere se fac de obicei la nceput pentru ca

    textele fiierelor surs (date i funcii) s poat fi utilizate n tot

    fiierul surs de lucru. De aceea, la nceputul fiierelor surs vom

    ntlni mai multe includeri de fiiere standard: stdio.h, stdlib.h, etc.

    Textul unui fiier inclus poate la rndul su s conin directiva include.

    Fiierul stdio.h (prescurtarea de la standard input output header) conine

    printre altele i funciile standard de intrare-ieire printf i scanf.

    Fiierele cu extensia .h se mai numesc i fiiere header (fiiere care se

    pun la nceputul fiierului surs). Un alt exemplu de fiier header este

    iostream.h folosit n mediul BORLAND C care conine funciile cin (console

    input) i cout (console output).

  • 1.4.2. Constante simbolice

    Cu directiva define se pot defini constante simbolice i

    macrouri. Constantele simbolice se definesc astfel:

    #define nume succesiune_de_caractere

    Preprocesorul substituie nume cu succesiune_de_caractere peste

    tot n fiierul surs care urmeaz poziiei directivei define. Dac

    succesiune_de_caractere nu ncape pe un rnd atunci se poate continua pe

    rndul urmtor scriind caracterul \ la sfritul primului rnd.

    Numele nume definit ca mai sus se spune c este o constant

    simbolic. Se recomand ca nume s fie scris cu litere majuscule pentru a

    scoate n eviden c este o constant simbolic.

    Construcia succesiune_de_caractere folosit pentru a defini o

    constant simbolic poate la rndul ei s conin alte constante simbolice.

    O constant simbolic poate fi redefinit (tot cu define) sau

    poate fi anihilat cu undef (#undef nume).

    Exemple:

    1) #define PROCENT 10 // din acest punct al fisierului sursa se substituie

    // PROCENT cu 10 . . . #define PROCENT 15 // de aici PROCENT se substituie cu 15 . . . #undef PROCENT // din acest punct constanta simbolica PROCENT

    // isi inceteaza existenta . . . #define DIM 100 // s-au definit doua constante simbolice DIM #define DOI_PI (2*3.1415926) // si DOI_PI . . . int vector[DIM]; // DIM va fi inlocuit cu 100 . . . x=DOI_PI; . . . LECIA 2.

    CLASE DE VARIABILE (DE MEMORIE)

    Compilatorul C aloc memorie variabilelor din program de

    dimensiune corespunztoare tipului fiecreia.

    Memoria se aloc n 2 moduri:

    static, repartizat ntr-o zon special asociat programului;

    dinamic, repartizat ntr-o zon special numit stiv (se comport

    ca o list LIFO).

    n funcie de modul cum se aloc memorie, vom distinge mai multe

    clase de variabile.

    O prim clas de variabile este aceea a variabilelor globale crora

    li se aloc memorie pe toat durata execuiei programului i ele pot fi

    utilizate n orice funcie a programului. Alt clas de variabile este

    clasa variabilelor locale, aceste variabile au o utilizare local la

    nivelul unei funcii.

    2.1. VARIABILE GLOBALE

    O variabil global are o definiie i attea declaraii de

    variabil extern cte sunt necesare.

    Definiia unei variabile globale coincide sintactic cu o

    declaraie obinuit, dar care este scris n afara oricrei funcii a

    programului (fiierului surs). Implicit, definiia unei variabile globale

    determin ca variabila respectiv s 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, pentru a fi accesate n orice funcie a fiierului.

    Pentru a utiliza variabilele globale i n alte funcii 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 coincide cu o declaraie obinuit

    doar c ncepe cu cuvntul cheie extern.

    Exemplu:

    fiierul n care sunt declarate ca variabile globale fiierul n care sunt folosite ca variabile externe

    int i; float f; void functie(. . .) void main(void) { extern int i; { i = 10; extern double f; . . . . . . f = 3.14; f = f*i; . . . . . . } }

    Variabilele i i f sunt declarate n afara funciei main i n afara

    oricrei funcii, deci sunt variabile globale. Ele pot fi folosite n toate

    funciile din fiierul surs care conine definiiile lor. Pentru a le

    utiliza n funcii situate n alte fiiere surs dect n cel n care sunt

    definite ele sunt declarate ca externe. Deci variabilele i i f sunt

    declarate ca externe n funcia functie din al doilea fiier surs. Cele

    dou fiiere surs care pot fi scrise n momente i de persoane diferite se

    pot asambla ntr-un singur program cu ajutorul directivei de preprocesare

    include.

    2.2. VARIABILE LOCALE

    Variabilele locale nu sunt valabile n tot programul. Ele au o

    utilizare local n dou feluri:

    ca i variabile automatice (alocate pe stiv) la nivelul unei

    funcii;

    ca i variabile statice (alocate n zona programului) la nivel de

    fiier (eventual i la nivelul unei funcii).

    Variabilele declarate n interiorul unei funcii i care nu sunt

    declarate ca externe sunt variabile locale. Lor li se aloc memorie pe

    stiv la intrarea n funcia n care sunt declarate. La ieirea din

    funcie, stiva se reface la coninutul dinaintea apelului i variabilele

    locale pierd alocarea. Deci ori de cte ori se apeleaz o funcie,

    variabilele locale acesteia (denumite i variabile automatice) se aloc

    (primesc memorie) pe stiv i la ieirea din funcie variabilele locale

    sunt terse din stiv.

    Variabilele locale pot s nu fie alocate pe stiv, ci ntr-o

    zon de memorie destinat acestui scop. O astfel de variabil local se

    numete variabil static. O variabil local static se declar printr-o

    declaraie obinuit, precedat de cuvntul cheie static. O variabil

    static poate fi declarat att n corpul unei funcii ct i n afara

    oricrei funcii. n cazul unei variabile statice declarat n interiorul

    unei funcii alocarea nu se face pe stiv ci ntr-o zon de memorie

    destinat acestui scop, aceasta fiind deosebirea esenial fa de

    variabilele automatice. 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 nu poate fi declarat

    ca extern i deci nu poate fi utilizat n funciile din alte fiiere

    surs diferite de cel n care a fost declarat.

    Se recomand ca tablourile mari s fie declarate statice, deoarece

    dac sunt automatice pot depi capacitatea stivei (care are implicit 4K

    octei).

    Exemple:

  • Fiierul fisier1.c este un fiier surs care conine 2 variabile

    globale i i d , o variabil static x i dou funcii f i main. Funcia

    main conine variabila static a iar funcia f conine variabila static b.

    int i; // definiia variabilei globale i double d; // definiia variabilei globale d static int x; // definiia variabilei statice x, locala fisierului fisier1.c void main (void) { static char a; // definiia variabilei statice a, locala funciei main float c; // definiia variabilei automatice c, locala funciei main /* in acest moment se pot folosi variabilele i,d,x,a si c */ . . . }

    { int p; // definiia variabilei automatice p, locala funciei f

    static float b; // definiia variabilei statice b, locala funciei f /* in acest moment se pot folosi variabilele i,d,x, p si b */ . . . } Variabilele a i c fiind locale funciei main nu pot fi

    utilizate n funcia f. Analog, variabilele p i b sunt locale n funcia

    f, nu pot fi utilizate n funcia main.

    Fiierul fisier2.c conine funciile f1 i f2 care intr n

    componena aceluiai program ca i funciile main i f din fiierul

    fisier1.c

    static unsigned t; // definitia variabilei statice t, locala fisierului fisier2.c void f1(...) { extern int i; // declaratie externa pentru i extern double d; // declaratie externa pentru d static int k; // definitia variabilei statice k, locala functiei f1 /* in acest moment se pot folosi varibilele i,d, k si t */ . . . } void f2(...) { extern int i; // declaratie externa pentru i static double s; // definitia variabilei statice s, locala functiei f2 /* se pot folosi variabilele i, s si t */ . . . } Variabila static x definit n fiierul fisier1.c nu poate fi

    utilizat n fiierul fisier2.c. De asemenea, variabila static t nu poate

    fi utilizat n fiierul fisier1.c. Variabila global d nu poate fi

    utilizat n funcia f2, ea nefiind declarat ca i extern.

    Observaii:

    1o. Variabilele globale constituie un mijloc simplu de interfa

    ntre funciile unui program. Se recomand a fi folosite cnd dorim

    transferuri de valori ntre dou sau mai multe funcii n aa fel nct

    modificrile realizate de o funcie s fie accesibile pentru toate

    funciile programului. Nu trebuie s se fac abuz n utilizarea

    variabilelor globale deoarece constituie i o surs potenial de erori,

    pentru c accesul unui mare numr de funcii la anumite date globale

    conduce deseori la modificri nedorite i greu evideniabile.

    2o. Funciile sunt considerate cu atributul implicit extern. Dac

    ntr-un program exist mai multe fiiere surs atunci o funcie poate fi

    apelat oriunde, bine neles respectnd convenia definirii ei sau a

    prototipului ei nainte de a fi folosit. Putem s limitm definind

    funciile cu atributul static precednd antetul funciei prin cuvntul

  • cheie static. Astfel funcia respectiv devine local i deci apelabil

    doar n fiierul n care este definit.

    2.3. VARIABILE REGISTRU

    Limbajul C ofer posibilitatea de a aloca anumite variabile n

    regitri microprocesorului. Deoarece regitri constituie un tip de memorie

    ultrarapid n anumite cazuri se poate economisi att timp de execuie ct

    i memorie. Se pot aloca n regitri numai parametrii funciilor i

    variabilele automatice de tip int, char i de tip pointer. O variabil

    registru se declar n mod obinuit, precednd declaraia ei prin cuvntul

    rezervat register.

    Alocarea ntr-un registru a unei variabile se face numai dac

    exist un registru disponibil. n caz contrar, variabila registru se aloc

    pe stiv exact ca o variabil automatic. Alocarea se face n ordinea

    declarrii variabilelor registru.

    Exemplu:

    void f (register int i) { register char c; register int j; . . . } Mai nti se aloc parametrul i ntr-un registru, apoi se aloc

    c i j n ali doi regitri.

    Se recomand alocarea n regitri a variabilelor care au o

    utilizare mare, de exemplu a indicilor de tablouri.

    2.4. INIIALIZARE

    Variabilelor li se pot atribui valori iniiale. Pentru

    variabilele globale valorile iniiale se atribuie prin definiiile lor, iar

    n cazul celorlalte variabile se pot atribui valori prin declaraiile lor.

    Pentru c de multe ori am folosit cuvintele definiia variabilelor sau

    declaraiile varibilelor precizm c ele au neles distinct n anumite

    contexte. O variabil global se definete o singur dat i se poate

    declara ori de cte ori e necesar utilizarea ei n alte fiiere (evident

    declarat extern). n cazul celorlalte tipuri de variabile definiiile i

    declaraiile coincid. Totodat definiia i declaraia (prototipul) unei

    funcii nu coincid.

    O variabil simpl se poate iniializa printr-o declaraie de

    forma:

    tip nume=expresie;

    Variabilelor globale i statice li se atribuie valori iniiale

    la lansarea programului. Expresia utilizat n cazul acestor variabile

    trebuie s fie o expresie constant care s poat fi evaluat de compilator

    la ntlnirea ei. Aceasta, 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 expresiei de iniializare.

    Exemplu:

    void f(int n) { int i=10; int k=i+n; . . . } La ntlnirea expresiei i+n sunt deja definii ambii operanzi:

  • i a fost n prealabil iniializat cu valoarea 10;

    n are o valoare care e transferat la apel.

    Variabilele globale i statice neiniializate au implicit valoarea

    egal cu zero, iar varibilele 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 }

    La iniializarea tablourilor se pot utiliza numai expresii

    constante. Numrul expresiilor poate fi mai mic dect numrul elementelor

    tabloului. Elementele neiniializate au valoarea zero n cazul tablourilor

    globale i statice. Dac se iniializeaz fiecare element al tabloului

    atunci numrul n al elementelor acestuia nu mai este obligatoriu n

    declaraia tabloului respectiv. Deci se poate scrie astfel:

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

    Numrul elementelor tabloului se consider c este egal cu cel al

    expresiilor care realizeaz iniializarea lor.

    Pentru un tablou bidimensional vom folosi urmtoarea structur:

    tip nume [n][m] = { {exp11, exp12, . . . exp1m}, // pentru linia

    nti

    {exp21, exp22, . . . exp2m}, // pentru linia a doua

    . . .

    {expn1, expn2, . . . expnm}, // pentru ultima linie

    };

    Numrul expresiilor poate fi mai mic dect m n oricare din

    acoladele corespunztoare celor n linii ale tabloului bidimensional. n

    acest caz se poate omite doar numrul n (al liniilor tablourilor), m fiind

    obligatoriu. Formatul de iniializare a tablourilor bidimensionale se

    extinde imediat pentru tablouri cu mai multe dimensiuni.

    Tablourile de tip caracter pot fi iniializate folosind un

    format mai simplu dect cel indicat anterior. Astfel. un tablou de tip

    caracter se poate iniializa printr-o declaraie de forma:

    char sir[n] = ir_de_caractere;

    Evident, marginea superioar n poate fi omis i n acest caz.

    Totodat compilatorul pune automat caracterul NUL dup ultimul caracter al

    irului utilizat n iniializare.

    Exemple:

    1) int itab[] = {1,2,3,4,5} // tabloul de tip intreg are 5 elemente itab[0] = 1,. . . itab[4] = 5 2) int m[3][3] = {{-1,0,1},{-1},{0,1}}; // tabloul are 3 linii si 3 coloane.

    Elementele primei linii sunt iniializate astfel:

    m[0][0] = 1;

    m[0][1] = 0;

    m[0][2] = 1;

    n linia a doua se iniializeaz numai m[1][0] = -1; Dac tabloul ar

    fi declarat global sau static atunci m[1][1] i m[1][2] ar avea valoarea

    zero. Altfel ele au o valoare imprevizibil.

    Elementele ultimei linii se iniializeaz astfel:

    m[2][0] = 0;

    m[2][1] = 1;

  • declaraiile de mai jos sunt identice:

    char sir [ ] = {L,I,M,B,A,J,U,L, ,C}; char sir [ ] = {LIMBAJUL C};

    LECIA 3.

    EXPRESII, OPERANZI, OPERATORI

    3.1. EXPRESII

    O expresie n limbajul C este format fie dintr-un operand fie din

    mai muli operanzi legai ntre ei prin operatori. O expresie are o valoare

    i un tip care se determin aplicnd operatorii conform prioritilor i

    asociativitii acestora.

    n limbajul C operatorii se asociaz de la stnga la dreapta,

    exceptnd operatorii unari i de atribuire, care se asociaz de la dreapta

    la stnga.. Totodat pot fi folosite parantezele rotunde pentru a impune o

    anumit ordine n executarea operaiilor.

    3.2. OPERANZI

    Un operand n limbajul C poate fi una din urmtoarele elemente:

    o constant;

    o constant simbolic;

    numele unei variabile simple;

    numele unui tablou;

    numele unei structuri;

    numele unei funcii;

    referirea la elementul unui tablou (variabil cu indici);

    referirea la elementul unei structuri;

    apelul unei funcii;

    o expresie inclus n paranteze rotunde.

    Unele dintre elementele de mai sus nu au fost nc definite, ele se

    vor prezenta n leciile viitoare.

    Exemple: 9876 - constant ntreag;

    x - variabil simpl;

    t[i][3] - variabil cu indici;

    0xabcd - constant hexazecimal;

    t - nume de tablou;

    (expresie) - expresie inclus n paranteze rotunde.

    f1 - numele unei funcii

    3.3. OPERATORI

    Operatorii limbajului C pot fi grupai n mai multe clase, dar oricum

    ei pot fi folosii mpreun ntr-o aceeai expresie. Operatorii au ariti

    diferite: unari, binari, ternari i totodat o anumit prioritate implicit

    care e redat n tabelul de mai jos. Operatorii de aceeai prioritate se

    afl trecui n aceeai linie. Liniile tabelulul conin operatorii

    limbajului C n ordinea descresctoare a prioritilor. Astfel n prima

    linie se afl operatorii de prioritate maxim, iar n ultima linie

    operatorul virgul cu prioritatea cea mai mic. Cu excepia operatorilor

    ., ->,&,*, a parantezelor rotunde (folosite la definiia i apelul

    funciilor) i a parantezelor drepte (folosite la variabilele cu indici)

    ceilali operatori vor fi explicai n aceast lecie.

    ( ) [ ] . ->

    - (unar) +(unar) *(unar) &(unar) ! ~ ++ -- (tip)

    sizeof

    * / %

    + -

    >

    < = >

  • = = !=

    &

    ^

    |

    &&

    | |

    ? : (ternar)

    = op= op poate fi: *(binar) / % +(binar) (binar) > & ^ |

    ,

    3.3.1. Operatori aritmetici

    Lista operatorilor aritmetici este redat mai jos:

    - (minus unar);

    + (plus unar);

    * / % operatori binari multiplicativi; (nmulire, mprire, restul

    mpririi ntregi);

    + - operatori binari aditivi (adunare i scdere).

    Operatorii de pe aceeai linie au aceeai prioritate. Cei unari

    au prioritate mai mare dect cei binari. Operatorii multiplicativi au

    prioritate mai mare dect cei aditivi.

    Exemple:

    int i,j,k; float x,y; double t[10]; // se dau cateva exemple de expresii folosind operatorii aritmetici i*x+t[5]; -y+k; i%j; // daca i=9 si j=4 atunci i%j are valoarea 1 i/j; // daca i=9 si j=4 atunci i/j are valoarea 2 x*-y; // - este operatorul unar deci avem x*(-y)

    3.3.2. Operatori relaionali

    Lista operatorilor relaionali este redat astfel:

    < (mai mic)

    (mai mare)

    >= (mai mare sau egal; cele dou caractere ce compun operatorul

    sunt concatenate)

    Toi operatorii relaionali au aceeai prioritate. Ea este mai

    mic dect prioritatea operatorilor aditivi. Rezultatul aplicrii unui

    operator relaional este 1 sau 0, dup cum operanzii se afl n relaia

    definit de operatorul respectiv sau nu.

    Exemple:

    a= 4 i b= -5

    atunci a>0 are valoarea 1;

    a0 are valoarea 0;

    a>=b are valoarea 1;

    a=b-a are valoarea 1;

    a+b

  • = = (egal; dou semne = concatenate)

    != (diferit; semnele sunt concatenate).

    Operatorii de egalitate au ambii aceeai prioritate i este

    imediat mai mic dect a operatorilor relaionali. Operatorul = =

    testeaz egalitatea a doi operanzi. Dac operanzii sunt egali atunci

    rezultatul operaiei = = este 1, n caz contrar este 0. Operatorul !=

    furnizeaz rezultatul 1 cnd cei doi operanzi sunt diferii i 0 cnd sunt

    egali.

    Exemple:

    a= 2 i b=-1

    atunci

    a= =b are valoarea 0;

    a!=b are valoarea 1;

    a*b!=a+b are valoarea 1;

    3.3.4. Operatori logici

    Lista operatorilor logici este redat mai jos:

    ! (negaia logic - operator unar);

    && (I logic);

    || (SAU logic).

    Operatorul ! are aceeai prioritate cu operatorii unari +

    i -. Operatorul && este mai prioritar dect operatorul ||, dar are 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.

    Dac operatorul ! se aplic la un operand a crui valoare

    este zero, atunci rezultatul este 1. Dac acelai operator se aplic la un

    operand a crui valoare este diferit de zero, atunci rezultatul este 0.

    Dm n continuare tabelele operatorilor logici binari aplicate

    valorilor 0 i 1.

    && 0 1 || 0 1 sau exclusiv 0 1

    0 0 0 0 0 1 0 0 1

    1 0 1 1 1 1 1 1 0

    Chiar dac pentru sau exclusiv nu exist operator el se poate

    realiza prin expresia urmtoare aplicat operanzilor a i b: !a&&b||!b&&a

    sau folosind parantezele rotunde ((!a) &&b)||((!b)&&a).

    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.

    Dac a=0 i b=1 atunci expresia ! a||b are valoarea 1 pentru c !a

    are deja valoarea 1.

    3.3.5. Operatori logici pe bii

    Lista operatorilor logici pe bii este redat mai jos n ordinea

    descrectoare a prioritilor:

    ~ (operator unar; complement fa de 1)

    >>

  • Operatorul >> realizeaz deplasarea la dreapta care este

    echivalent cu o mprire ntreag cu puteri a lui 2; a >> 3 este

    echivalent cu [a/23].

    Operatorul > 6) & ~(~ 0 >6 are valoarea 1111 1110 1010 1110

    Al doilea operand pregtete o masc astfel:

    ~0 1111 1111 1111 1111

    ~0

  • 3.3.6. Operatori de atribuire

    n forma cea mai simpl operatorul de atribuire se noteaz cu

    = i se utilizeaz n construcii de forma:

    v=expresie;

    (v este fie o variabil simpl, fie variabil cu indici sau un

    element de structur).

    Aceast construcie se mai numete expresie de atribuire. Ea este

    considerat ca fiind un caz particular de expresie. Tipul ei coincide cu

    tipul lui v, iar valoarea ntregii expresii este chiar valoarea atribuit

    lui v.

    O expresie de forma:

    v1=(v=expresie);

    este i ea legal i se efectueaz n felul urmtor :

    se evalueaz expresia expresie i valoarea ei se atribuie lui v;

    valoarea lui v se atribuie apoi i lui v1.

    Deoarece operatorii de atribuire se asociaz de la dreapta la stnga,

    expresia de mai sus se poate scrie i fr paranteze:

    v1=v=expresie;

    n general, putem realiza atribuiri multiple printr-o expresie

    de forma:

    vn =. . . =v1=v=expresie

    Dac expresia din dreapta semnului egal are un tip diferit de cel al

    variabilei v, atunci nti valoarea ei se convertete spre tipul variabilei

    v i pe urm se realizeaz atribuirea,

    Pentru operaia de atribuire, n afara semnului egal se mai

    poate folosi i succesiunea :

    op=

    unde prin op se nelege unul din operatorii binari aritmetici sau

    logici pe bii, adic unul din urmtorii:

    % / * - + & ^ | >

    Acest mod de construcie se folosete pentru a compacta un anumit tip

    de atribuire. Astfel expresia:

    v op = expresie;

    este identic cu expresia de atribuire:

    v = op expresie;

    Exemple:

    int i, j; double x, y; int v[10]; i=5; j=10; x=y=10.01; i +=1; // echivalenta cu i=i+1 si cu i++ x*=3; // echivalenta cu x=x*3 j

  • 3.3.7. Operatori de incrementare i decrementare

    Aceti operatori sunt unari i au aceeai prioritate cu

    ceilali operatori unari ai limbajului C. Operatorul de incrementare se

    noteaz prin ++ i mrete valoarea operandului cu unu, iar operatorul de

    decrementare se noteaz prin - - i micoreaz valoarea operandului cu

    unu. Operatorii sunt folosii prefixat i postfixat. Astfel operatorii

    prefixai au notaia:

    ++operand;

    - - operand;

    Ei se aplic mai nti i apoi se folosete valoarea lor.

    Astfel operatorii postfixai au notaia:

    operand++;

    operand - -;

    Se folosete valoarea operanzilor i apoi se aplic incrementarea sau

    decrementarea.

    Menionm c aceti operatori se pot aplica numai la urmtorii

    operanzi:

    variabil simpl;

    variabil cu indici;

    referire la elementul unei structuri.

    Exemple:

    int i,j; double x,y; int vector [5]; j=i++; // este echivalent cu j=i si i=i+1; y=--x; // este echivalent cu x=x-1 si y=x; i=++vector[j] // este echivalent cu vector[j]=vector[j]+1 si i=vector[j]

    3.3.8. Operatorul de conversie explicit (expresie cast)

    Pentru forarea tipului unui operand se folosete o construcie de

    forma:

    (tip) operand

    Prin aceasta valoarea operandului se convertete spre tipul indicat

    n paranteze.

    Exemplu:

    int i,j; double y; i=8; j=5; y=i/j; // y are valoarea 1, pentru ca se face impartirea intreaga i/j

    Dac vom converti operanzii i i j spre tipul double se va obine

    rezultatul corect adic 1.6.

    Deci:

    int i,j; double y; i=8; j=5; y=(double) i / (double) j; // y are valoarea 1.6,

    Construcia (tip) este un operator unar prin care se expliciteaz

    conversia dorit. Are aceeai prioritate ca restul operatorilor unari.

    3.3.9. Operatorul dimensiune (sizeof)

    Pentru a determina lungimea n octei a unei date se poate

    folosi construcia:

  • sizeof (data)

    unde data poate fi:

    numele unei variabile simple;

    numele unui tablou;

    numele unei structuri;

    numele unui tip;

    referirea la elementul unui tablou sau structur.

    Exemple:

    int i; long l; float f; double d; char c; int itablou[5]; double dtablou[5]; sizeof (i) // are valoarea 2; sizeof (l) // are valoarea 4; sizeof (f) // are valoarea 4; sizeof (d) // are valoarea 8; sizeof (c) // are valoarea 1; sizeof (itablou[1]) // are valoarea 2; sizeof (dtablou[1]) // are valoarea 8; sizeof (itablou) // are valoarea 10; sizeof (dtablou) // are valoarea 40;

    Regula conversiilor implicite

    n general o expresie C conine operanzi de tipuri diferite.

    Pentru operatorii binari exist situaii cnd operanzii nu sunt de acelai

    tip i trebuie executate conversii astfel nct operatorii s se aplice

    pentru operanzi de acelai tip. Aceste conversii le face automat

    compilatorul. Exist o regul a conversiilor implicite care are urmtorii

    pai:

    fiecare operand de tip char se convertete spre tipul int i fiecare

    operand de tipul float se convertete spre double;

    dac unul dintre operanzi este de tip double atunci i cellalt se

    convertete spre tipul double i rezultatul va avea tipul double;

    dac unul dintre operanzi este de tip long, atunci i cellalt se

    convertete spre tipul long i rezultatul va avea tipul long;

    dac unul dintre operanzi este de tip unsigned, atunci i cellalt se

    convertete spre tipul unsigned i rezultatul va fi de tipul unsigned;

    la acest pas se ajunge numai dac ambii operanzi sunt de tip int i

    deci operaia se execut cu operanzii respectivi, iar rezultatul va fi de

    tip int.

    Aplicnd regula de mai sus pas cu pas (la fiecare operator n

    momentul efecturii lui), se ajunge n final la evaluarea ntregii expresii

    i prin acesta se determin tipul expresiei. Regula conversiilor implicite

    nu se aplic pentru operatorul de atribuire (valoarea expresiei din partea

    dreapt a semnului de atribuire se convertete spre tipul variabilei din

    stnga semnului egal).

    Exemple:

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

  • char c; expresii conversii tipul expresiei i-j/k nu int a/b a spre double b spre double double x+y nu double i+a a spre double i spre double double i-3.14 i spre double double i+3 nu int i+x i spre double double i-c c spre int int x+10 10 spre double double p-10 10 spre unsigned unsigned r*5 5 spre long long (double)(i/j) se realizeaz mprirea ntreag ntre i i j i rezultatul se convertete spre double double

    Dac rezultatul unei operaii depete domeniul de valori ce

    corespunde tipului rezultatului, valoarea respectiv se trunchiaz i

    rezultatul este eronat.

    3.3.11. Operatori condiionali

    Operatorii condiionali sunt ? i : i se folosesc mpreun n

    construcii de forma:

    exp1 ? exp2 : exp3 Evaluarea se face astfel:

    se evalueaz expresia exp1; dac exp1 este diferit de zero, atunci valoarea i tipul expresiei

    condiionale sunt egale cu valoarea i tipul expresiei exp2; altfel cu

    expresia exp3.

    Exemplu: procesul de determinare a maximului a dou numere a i b

    este:

    dac a>b atunci max=a

    altfel max=b

    sfdac

    n limbajul C se poate realiza acest proces cu ajutorul

    operatorilor condiionali astfel:

    max= a>b ? a : b

    Dac a>b atunci expresia condiional are valoarea i tipul lui a

    altfel expresia condiional are valoarea i tipul lui b.

    Operatorul virgul

    Operatorul , este folosit pentru gruparea mai multor expresii ntr-

    una singur.

    Cu ajutorul acestui operator (care are prioritatea cea mai mic) se

    construiesc expresii de forma:

    exp1, exp2,. . ., expn

    Aceast expresie are valoarea i tipul ultimei expresii (deci a lui

    expn).

    Exemplu:

    k= (i=10, j=j+5; i+j)

    Se execut pe rnd cele dou atribuiri de la stnga la dreapta din

    parantezele rotunde apoi se face suma i+j i n final se atribuie aceast

    sum lui k,

  • LECIA 4.

    INTRRI / IEIRI STANDARD

    Limbajul C nu posed instruciuni de intrare / ieire. Aceste

    operaii se realizeaz prin apeluri de funcii din bibliotecile standard

    ale mediului de programare. De obicei astfel de funcii asigur interfaa

    programului cu terminalul de la care s-a lansat, cu imprimanta, etc. Se

    numesc intrri standard i ieiri standard intrrile respectiv ieirile de

    la terminalul de la care s-a lansat programul. Totodat se presupune c

    datele de intrare / ieire sunt organizate n fiiere.

    Unui program C i se ataeaz n mod implicit urmtoarele

    fiiere:

    - stdin intrare standard;

    - stdout ieire standard;

    - stderr ieire standard pentru erori;

    - stdprn ieire pe imprimant;

    - stdaux intrare / ieire serial.

    4.1. FUNCIA STANDARD printf

    Funcia printf realizeaz ieiri cu format la ieirea standard

    stdout, deci afiare la terminalul la care care s-a lansat programul.

    Funcia printf se apeleaz printr-o instruciune cu formatul:

    int printf (control, lista_expresii);

    unde control este un ir de caractere care conine:

    texte de scris;

    specificatori de format pentru datele care se scriu din

    lista_expresii.

    lista_expresii conine expresii; valoarea fiecrei expresii se scrie

    conform unui specificator de format corespondent din parametrul control.

    Parametrul control este inclus ntre ghilimele, iar numrul

    specificatorilor de format coincide cu numrul expresiilor din

    lista_expresii. Dac dorim s scriem numai un text atunci parametrul de

    control nu conine nici un specificator de format iar lista_expresii este

    vid (practic este absent).

    Un specificator de format are formatul BNF urmtor:

    %[-][d..d][.d..d][l1]l2

    Dup cum se observ un specificator de format ncepe ntotdeauna cu

    caracterul procent (%). Dup acest caracter poate urma una din

    construciile urmtoare:

    - un caracter - opional; prezena acestui caracter indic cadrarea

    la stnga a datei n cmpul n care se scrie (implicit data se scrie

    cadrat la dreapta);

    -un ir de cifre zecimale opional, care definete lungimea minim a

    cmpului n care se scrie data corespunztoare din lista_expresii; data se

    scrie astfel:

    n cazul n care necesit o lungime mai mic se scrie cadrat la

    dreapta sau stnga (n funcie de absena sau prezena semnului -)

    n cazul n care necesit o lungime mai mare se va scrie pe attea

    poziii cte i sunt necesare;

    -un punct urmat de un ir de cifre zecimale (dup cum se observ

    opional); acest element indic precizia datei care se scrie:

    dac data se scrie n virgul flotant, precizia definete numrul de

    cifre aflate dup marca zecimal (deci cte zecimale);

    dac data este un ir de caractere atunci indic cte caractere se

    scriu.

  • -una sau dou litere, care definesc tipul de conversie din formatul

    intern n formatul extern:

    prima litera poate fi l, ceea ce semnific conversia din formatul

    intern long n formatul extern definit de specificator;

    a doua liter este obligatorie ntotdeauna i are semnificaiile de

    mai jos:

    litera tipul de conversie realizat

    d - din int intern n zecimal extern

    o - din int intern n octal extern

    x - din int intern n hexazecimal extern (litere mici

    pentru cifrele mai mari ca 9 deci a,b,c,d,e,f,)

    X - din int intern n hexazecimal extern (litere mici

    pentru cifrele mai mari ca 9 deci A,B,C,D,E,F)

    u - din unsigned intern n zecimal extern fr semn

    c - din binar intern (cod ASCII) n caracterul

    corespunztor

    s - din ir de coduri ASCII ntr-un ir de caractere (atenie

    ultimul cod este NUL (adic \0)

    f - din float sau double intern n d...d.d...d (implicit 6 cifre

    zecimale la partea fracionar dac nu e prezent precizia)

    e - din float sau double intern n d.d...deddd (implicit 6

    cifre zecimale la partea fracionar dac nu e prezent

    precizia)

    E - din float sau double intern n d.d...dEddd (implicit 6

    cifre zecimale la partea fracionar dac nu e prezent

    precizia)

    g - se aplic una din conversiile definite de literele f i e

    alegndu-se aceea care are un numr minim de poziii

    G - se aplic una din conversiile definite de literele f i E

    alegndu-se aceea care are un numr minim de poziii

    Literele d, o, x, u pot fi precedate de litera l conversia

    realizndu-se din formatul intern long n loc de int.

    Observaie.

    1o. Dac caracterul % nu este urmat de una din construciile de mai

    sus atunci nu reprezint un specificator de format.

    Funcia printf ntoarce lungimea total n octei a datelor

    scrise la terminal sau valoarea simbolic EOF n caz de eroare. Precizm c

    EOF este definit n fiierul header stdio.h astfel:

    #define EOF 1.

    Totodat funcia printf poate fi testat i astfel:

    EOF= = printf (control, lista_expresii)

    Dac are valoarea adevrat atunci la scrierea datelor s-a

    produs o eroare.

    Exemple:

    1)

    #include #include void main(void) { int i=10; long j=11; float a=1.2, b=1.3; double A=1.4; B=1.5; clrscr(); // inceputul instructiunilor executabile; se sterge

    ecranul printf ("\ni*j = %d",i*j); // incep afisarile printf ("\ni*j = %5d",i*j); printf ("\ni*j = %-5d",i*j);

  • printf ("\ni*j = %5.5d",i*j); printf ("\ni*j = %05d",i*j); printf ("\na*b = %10.1f",a*b); printf ("\nA*B = %10.5lf",A*B); printf ("\nradical(a*b) = %lf",sqrt((double) a*b)); printf ("\nradical(A*B) = %15.10lf",sqrt(A*B)); printf ("\nradical(A*B) = %25.17lf",sqrt(A*B)); printf ("\nradical(A*B) = %25.19lf",sqrt(A*B)); getche(); // asteapta citirea unui caracter de la terminal }

    Rezultatele execuiei programului sunt: i*j = 110 i*j = 110 i*j = 110 i*j = 00110 i*j = 00110 a*b = 1.6 A*B = 2.10000 radical(a*b) = 1.249000 radical(A*B) = 1.4491376746 radical(A*B) = 1.44913767461894372 radical(A*B) = 1.4491376746189437200 2) #define sir PC WORLD void main (void) { printf(*%10s*,sir); printf(*%-10s*,sir); printf(*%10.5s*,sir); printf(*%-10.5s*,sir); } Rezultatele execuiei programului sunt:

    * PC WORLD* *PC WORLD * * PC WO* *PC WO *

    4.2. FUNCIA STANDARD scanf

    Funcia de bibliotec scanf realizeaz intrri cu format de la

    intrarea standard stdin (intrare de la terminalul de la care s-a lansat

    programul) i poate fi apelat printr-o instruciune de apel de forma:

    scanf (control, lista_adrese);

    Ca i n cazul funciei printf, parametrul control este

    delimitat de ghilimele i poate conine texte i specificatori de format.

    Caracterele albe din parametrul control sunt neglijate. Celelalte caractere

    care nu fac parte dintr-un specificator de format, trebuie s existe la

    intrare n poziii corespunztoare. Ele se folosesc n scopul realizrii

    unor verificri asupra datelor care se citesc.

    Un specificator de format ncepe i n acest caz prin

    caracterul procent, apoi:

    un caracter * opional;

    un ir de cifre, opional, care definete lungimea maxim a cmpului

    din care se citete data de sub controlul specificatorului de format;

    una sau dou litere care definesc tipul conversiei din formatul

    extern n formatul intern.

    Cmpul controlat de un specificator de format ncepe cu primul

    caracter care nu este alb i se termin:

    fie la caracterul dup care urmeaz un caracter alb;

    fie la caracterul dup care urmeaz un caracter care nu corespunde

    specificatorului de format care controleaz acel cmp;

    fie la caracterul prin care se ajunge la lungimea maxim indicat n

    specificatorul de format.

  • Condiia c) este absent n definirea cmpului dac n specificatorul

    de format nu este indicat lungimea maxim a cmpului.

    Literele care termin un specificator de format sunt

    asemntoare cu cele utilizate la funcia printf. n acest caz este

    realizat conversia invers fa de cea realizat de funcia printf.

    Litera Tipul conversiei realizate

    d - data din cmpul de intrare este un ir de cifre zecimale,

    precedat eventual de un semn i se convertete din zecimal extern n binar

    de tip int

    o - ca i n cazul literei d, dar din octal extern n binar de tip

    int.

    x - ca i n cazul literei d, dar din hexazecimal extern n binar

    de tip int; se utilizeaz literele mici a-f sau mari A-F pentru cifrele mai

    mari ca 9.

    X - ca i n cazul literei x;

    u - data este un ir de cifre zecimale care formeaz un numr

    ntreg fr semn i se convertete din zecimal extern n binar tipul

    unsigned.

    c - data se consider format din caracterul curent de la intrare

    i parametrului corespunztor i se atribuie codul ASCII al acestui

    caracter; n acest caz nu se face avans peste caracterele albe, ca i n

    cazul celorlali specificatori.

    s - data se consider c este ir de caractere; irul ncepe,

    conform regulii generale, cu primul caracter care nu este alb i se termin

    la caracterul dup care urmeaz un caracter alb sau cnd s-au citit attea

    caractere cte indic dimensiunea maxim din specificatorul de format;

    f - data de intrare reprezint un numr flotant; deci conversie

    din flotant extern n virgul flotant simpl precizie; data care se

    citete conine un punct sau un exponent, sau att punct ct i exponent.

    Literele d, o, x i u pot fi precedate de litera l i n acest caz

    conversia se realizeaz spre long, n loc de int.

    De asemenea, litera f va fi precedat de litera l pentru a face

    conversii spre formatul virgul flotant dubl precizie.

    Lista_adrese conine adresele zonelor receptoare ale datelor citite

    prin intermediul funciei scanf. Fiecare dintre parametri reprezint adresa

    unei zone receptoare sub forma:

    &nume

    Ea determin adresa zonei de memorie rezervat variabilei nume.

    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.

    Exemplu:

    void main (void) { int i; long n; float x; scanf ( %d %ld %f ,&i,&n,&x); // citeste datele din stdin si le atribuie lui i,n,x. scanf( %d %*ld %f , &i,&x); // caracterul * indica faptul ca valoarea pentru

    variabila n // nu se citeste }

    Funcia scanf returneaz numrul de cmpuri citite corect din

    fiierul stdin. Dac apare o eroare la citire (din diverse motive de

    exemplu neconcordan dintre specificatorul de format i datele din

    fiierul stdin) atunci funcia nu va returna numrul total de cmpuri;

    citirea se va ntrerupe n locul detectrii erorii i scanf va returna

    numrul de cmpuri citite pn n acel moment. Deci de multe ori pentru a

  • valida formal intrarea datelor (atenie nu e o validare calitativ) se va

    folosi o construcie de forma:

    nr=scanf(...)

    Prin construcia de mai sus se poate pune n eviden sfritul

    de fiier, deoarece n acest caz scanf returneaz valoarea EOF. Sfritul

    de fiier se poate genera de la tastatur acionnd n acelai timp tastele

    CTRL i Z (deci CTRL / Z). Deorece funcia scanf citete datele de la

    intrarea standard prin intermediul unei zone de memorie intermediare

    (numit zon tampon sau buffer), ea are acces la caracterele din zona

    tampon numai dup acionarea tastei ENTER (RETURN). De aceea dup

    acionarea combinaiei CTRL / Z se va tasta i ENTER. Totodat aceast

    intermediere face posibil eventuale corecturi nainte de a aciona tasta

    ENTER.

    Exemplu:

    Vom citi un ntreg de cinci cifre de la intrarea standard i vom

    afia cifrele respective precedate fiecare de dou spaii.

    void main (void) { int c1,c2,c3,c4,c5; // c1,c2,c3,c4,c5 sunt cifrele intregului citit scanf(%1d %1d %1d %1d %1d, &c1,&c2,&c3,&c4,&c5); // se citesc cifrele intregului in cele 5 variabile cu %1d printf(%3d%3d%3d%3d%3d,c1,c2,c3,c4,c5); }

    Pentru a citi iruri de caractere se va folosi funcia scanf

    fr a mai pune operatorul de adres n faa numelui irului de caractere,

    deoarece numele unui tablou reprezint un pointer (deci conine o adres i

    anume adresa primului element de tablou).

    Exemplu:

    Vom citi numele i prenumele unei persoane i le afim pe

    ecran.

    #define MAX 20 void main(void) { char nume[MAX+1], prenume[MAX+1]; //declararea tablourilor de caractere scanf (%20s %20s,nume, prenume); //nu s-a mai pus operatorul de adresa printf (\nnumele: %s, prenumele: %s,nume,prenume); }

    4.3. FUNCIA STANDARD putchar

    Funcia standard putchar se poate utiliza pentru a scrie un

    caracter n fiierul standard de ieire stdout, n poziia curent a

    cursorului. Ea se apeleaz folosind o instruciune de apel de forma:

    putchar (expresie);

    unde expresie este codul ASCII al caracterului care se scrie la

    ieirea standard.

    Practic putchar nu este o funcie n sensul definiiei ce am

    dat-o n lecia 1, ci este un macrou definit n fiierul header stdio.h,

    care folosete o funcie special destinat prelucrrii fiierelor, funcia

    putc, astfel:

    #define putchar(c) putc(c,stdout)

    Exemplu:

    void main (void)

    { putchar (A); // scrie caracterul A in fisierul de iesire in poziia curenta a cursorului putchar (A+2) // scrie caracterul de cod ASCII A+2=65+2=67, adica litera C putchar (\n); // scrie caracterul newline; deci inceput de linie nou }

  • 4.4. FUNCIA STANDARD getchar

    Aceast funcie citete de la intrarea standard, stdin,

    caracterul curent i returneaz codul ASCII al caracterului citit. Tipul

    valorii returnate este int. La ntlnirea sfritului de fiier (CTRL/Z) se

    returneaz valoarea EOF (adic -1). Ca i putchar, getchar este un macrou

    definit n fiierul header stdio.h, cu ajutorul unei funcii speciale, getc

    destinate prelucrrii fiierelor, astfel:

    #define getchar() getc(stdin)

    De obicei getchar se folosete n expresii de atribuire de

    forma:

    c=getchar();

    Dup citirea caracterului curent de la intrarea standard se atribuie

    variabilei c codul ASCII al caracterului cititi sau EOF la ntlnirea

    sfritului de fiier.

    Exemple:

    1)

    #include void main (void) { putchar(getchar() A + a); // citeste o litera mare si o rescrie ca litera mica } 2) exemplul urmtor testeaz dac s-a citit o liter mare i numai n

    acest caz aplic transformarea ei n liter mic. n cazul n care la

    intrare nu se afl o liter mare se rescrie caracterul respectiv.

    #include void main (void) { intc c; putchar(((c = getchar() )>= A && c

  • Aceast metod de fapt nu este o metod propriu-zis ci este prima

    modalitate de programare odat cu apariia calculatoarelor. Intuiia i

    experiena programatorului joac un rol important. Fiecare programator i

    are propriile reguli de programare. Programele sunt monolitice (un singur

    corp de instruciuni), lungi i greu de neles de alt programator. nsui

    cel ce a elaborat un astfel de program ntmpin dificulti de nelegere

    a propriului program dup un timp oarecare.

    5.1.2. Programare procedural

    Odat cu apariia primelor limbaje de nalt nivel se utilizeaz

    programarea procedural. Necesitatea ca anumite secvene de program s fie

    folosite de mai multe ori duce la organizarea acestora n uniti distincte

    de program numite n diverse limbaje subprograme, subrutine, proceduri,

    etc. De multe ori procedurile trebuie s fie generale deci procesarea s

    fac abstractizare de valorile datelor. De exemplu o procedur de calcul al

    radicalului de ordinul 2 trebuie s calculeze acest lucru din orice numr

    real pozitiv iar pentru cele negative s semnaleze eroare. Procedurile

    trebuie deci parametrizate cu anumite variabile numite parametri formali.

    Valorile de la apel ale parametrilor formali se numesc parametri efectivi.

    Programarea procedural are la baz deci utilizarea procedurilor, iar

    acestea realizeaz o abstractizare prin parametri. La apelare o procedur

    funcioneaz dup principiul cutiei negre (black box): se cunosc intrrile

    i ieirile rezultate din acestea dar nu i modul de transformare care nu e

    important n acest moment.

    n majoritatea limbajelor procedurale de programare se

    consider 2 categorii de proceduri:

    proceduri care definesc o valoare de revenire (denumite i funcii);

    proceduri care nu definesc o valoare de revenire.

    n limbajele C i C++ procedurile de ambele categorii se numesc

    funcii.

    5.1.3. Programarea modular

    Pe msur ce complexitatea aplicaiilor a crescut, a aprut

    ideea de a descompune problemele n subprobleme mai simple care la rndul

    lor pot fi descompuse n altele mai simple i aa mai departe. n felul

    acesta se ajunge la o descompunere arborescent a problemei date n

    subprobleme mai simple. Programarea subproblemelor devine o problem mai

    simpl i fiecare subproblem are o anumit independen fa de celelalte

    subprobleme. De asemenea, interfaa ei cu celelalte subprobleme este

    limitat i bine precizat prin procesul de descompunere a problemei

    iniiale. De obicei, programarea unei subprobleme, component a

    descompunerii arborescente a problemei iniiale, conduce la realizarea unui

    numr relativ mic de proceduri (funcii). Aceste funcii pot prelucra n

    comun anumite date. Unele dintre ele sunt independente de funciile

    realizate pentru alte subprobleme componente ale descompunerii

    arborescente. Altele realizeaz chiar interfaa cu subproblemele

    nvecinate.

    Despre funciile obinute n urma programrii unei subprobleme

    se obinuiete s se spun c sunt nrudite. De obicei, aceste funcii,

    mpreun cu datele pe care le prelucreaz, se pstreaz ntr-un fiier i

    se compileaz independent.

    O colecie de funcii nrudite, mpreun cu datele pe care le

    prelucreaz n comun formeaz un modul. n felul acesta, problema iniial

    se realizeaz printr-un program alctuit din module.

    Programarea modular are la baz elaborarea programelor pe

    module.

    O parte din datele utilizate n comun de funciile modulului,

    sau chiar toate datele modulului, nu sunt necesare i n alte module.

    Aceste date pot fi protejate sau cum se mai spune, ascunse n modul.

    Limbajul C i C++, permite ascunderea datelor n modul folosind

    date care au clasa de memorie static. Mai mult, pot fi declarate i

  • funciile ca statice i atunci ele vor fi ascunse n modul (nu pot fi

    apelate din afara modului). Ascunderea funciilor n modul se face pentru

    acele funcii care nu se utilizeaz la realizarea interfeei modulului cu

    celelalte module. Ascunderea datelor i funciilor n module permite

    protejarea datelor i prentmpin utilizarea eronat a funciilor.

    5.1.4. Programarea structurat

    Descompunerea unei probleme n subprobleme mai simple se poate

    face succesiv n mai multe etape, pn cnd subproblemele sunt direct

    programabile sub forma unor proceduri sau module. Aceast descompunere

    succesiv se mai numete rafinare pas cu pas (stepwise refinement)..

    Evident c se obine o descompunere arborescent. Procedurile se pot

    organiza sau nu n module. n cadrul procedurilor se folosesc anumite

    structuri de control a execuiei. Aceasta impune o anumit disciplin a

    programrii. Structurile de control de sunt:

    secvena;

    iteraia (pretestat, posttestat, cu numr prestabilit de ciclri);

    alternativa (simpl, complet, generalizat).

    Instruciunea de baz (primitiv) n cadrul acestor structuri de

    control este instruciunea de atribuire.

    Aceast abordare a programrii s-a nscut din necesitatea eliminrii

    instruciunii de control GO TO care face saltul necondiionat la o

    instruciune precizat, alta dect instruciunea urmtoare ei. Profesorul

    Dijsktra de la Universitatea din Eindhoven spunea, prin anul 1965,

    calitatea unui programator este invers proporional cu numrul de

    instruciuni GO TO folosite i a impus D-structurile de control:

    secvena;

    iteraia pretestat;

    alternativa simpl.

    D-structurile se regsesc n toate limbajele procedurale.

    Corespondena ar fi:

    secvena este echivalent cu execuia instruciunilor n ordinea

    scrierii lor n programul surs;

    b) iteraia pretestat echivalent cu WHILE ... DO;

    c) alternativa simpl echivalent cu IF ... THEN.

    O ilustrare grafic a celor trei D-structuri se d n

    continuare.

    da

    S1 C

    nu da

    S2 S C

    S nu

    .

    Sn

    S-a demonstrat ulterior (Bohm i Jacopini) c orice algoritm se poate

    descrie doar cu D-structurile dar pentru o mai bun lizibilitate i

    nelegere a programelor surs s-au adugat i iteraia postestat (REPEAT

    ... UNTIL), iteraia cu numr prestabilit de ciclri (FOR ... DO),

    alternativa complet (IF ... THEN ... ELSE) i alternativa generalizat

    (CASE ... OF).

    n unele limbaje se folosesc i alte structuri pe lng cele de mai

    sus pentru o ct mai fidel reflectare a algoritmului.

  • 5.1.5. Programarea prin abstractizarea datelor

    n toate aceste tehnologii anterioare se urmrete mai mult

    organizarea programului i mai puin rezolvarea ct mai natural a

    problemei. Programarea prin abstractizarea datelor i programarea orientat

    spre obiecte propun metodologii n care conceptele deduse din analiza

    problemei s poat fi reflectate ct mai fidel n program i s se poat

    manevra cu instanieri ale acestor concepte ct mai natural. Se realizeaz

    o mai mare fidelitate a programului fa de problem. De exemplu dac ntr-

    o problem n care se proceseaz numere complexe e nevoie s se lucreze

    ntr-o form ct mai apropiat cu forma matematic se poate introduce tipul

    COMPLEX (tip care nu exist n limbajele de programare) i apoi se pot

    declara variabile de acest tip. Mai mult ar trebui s se poat face toate

    operaiile matematice asupra datelor de tip COMPLEX. n general un TAD (Tip

    Abstract de Date) are dou componente fundamentale:

    datele membru (reflect reprezentarea tipului);

    funciile membru (reflect comportamentul tipului).

    5.1.6. Programarea orientat spre obiecte

    Un neajuns al programrii prin abstractizarea datelor este

    faptul c nu permite exprimarea legturilor dintre diferite concepte (TAD-

    uri). Singura legtur dintre concepte care se poate exprima, este aceea c

    datele membru ale unei clase pot fi obiecte ale unei alte clase. Acest

    lucru nu este suficient n cazul n care conceptele sunt strns dependente

    ntre ele formnd structuri ierarhice. Exprimarea ierarhiilor conduce la

    atribute suplimentare cum sunt cele de motenire. Aceste atribute conduc la

    un nou model de programare pe care l numim programare orientat obiect.

    n vrful unei ierarhii se afl fenomenul sau forma de

    existen care are trsturi comune pentru toate celelalte componente ale

    ierarhiei respective. Pe nivelul urmtor al ierarhiei se afl componentele

    care pe lng trsturile comune de pe nivelul superior, mai au i

    trsturi suplimentare, specifice. O ierarhie, de obicei, are mai multe

    nivele, iar situarea unui element pe un nivel sau altul al ierarhiei este

    uneori o problem deosebit de complex. Dm n exemplul urmtor o ierarhie

    arborescent pentru conceptele de paralelogram, dreptunghi, romb i ptrat.

    Paralelogram

    Dreptunghi Romb

    Ptrat

    Dac paralelogramul se afl n vrful ierarhiei atunci pe nivelul

    imediat inferior se aeaz dreptunghiul (paralelogramul cu un unghi drept)

    dar i rombul (paralelgramul cu 2 laturi alturate congruente). Apoi

    ptratul se poate defini fie ca un dreptunghi cu laturile congruente fie ca

    un romb cu un unghi drept. Conceptul de pe fiecare nivel se observ c

    motenete proprietile conceptului imediat superior din care este

    derivat.

    La ora actual, toate ramurile cunoaterii tiinfice sunt

    pline de ierarhii rezultate n urma clasificrii cunotinelor acumulate n

    perioada lung de observare a fenomenelor i formelor de existen a lumii

    materiale i spirituale. Clasificrile ierarhice ale cunotinelor pot fi

  • ntlnite att n domeniile care pleac de la cele mai concrete forme ale

    lumii materiale, cum sunt botanica, zoologia, biologia, etc ct i n

    domenii care studiaz concepte dintre cele mai abstracte, cum ar fi

    matematica sau filozofia.

    Aceste ierarhii sunt rezultatul definirii conceptelor dup regula

    includerii genul proxim i diferena specific.

    Limbajul C dispune de un set bogat de instruciuni care permit

    scrierea de:

    programe structurate,

    programe flexibile,

    programe compacte.

    Totodat limbajul C permite aplicarea metodelor de programare

    procedural, programare modular i programare structurat. Pe lng aceste

    metodologii limbajul C++ permite i programarea prin abstractizarea datelor

    i programarea orientat spre obiecte.

    Vom descrie n continuare instruciunile limbajului C. Ca o

    caracteristic sintactic toate instruciunile limbajului se termin prin

    caracterul ;, excepie fcnd instruciunile care se termin cu acolada

    nchis.

    Limbajul C dispune de un set bogat de instruciuni care permit

    scrierea de:

    programe structurate,

    programe flexibile,

    programe compacte.

    Totodat limbajul C permite aplicarea metodelor de programare

    procedural, programare modular i programare structurat. Pe lng aceste

    metodologii limbajul C++ permite i programarea prin abstractizarea datelor

    i programarea orientat spre obiecte.

    Vom descrie n continuare instruciunile limbajului C. Ca o

    caracteristic sintactic toate instruciunile limbajului se termin prin

    caracterul ;, excepie fcnd instruciunile care se termin cu acolada

    nchis.

    5.2. INSTRUCIUNEA VID

    Instruciunea vid se reduce la caracterul ;. Ea nu are nici un

    efect. Adesea este nevoie de ea la construcii n care se cere prezena

    unei instruciuni, dar nu este necesar s se execute nimic n punctul

    respectiv.

    5.3. INSTRUCIUNEA EXPRESIE

    Instruciunea expresie se obine scriind punct i virgul dup

    o expresie, deci:

    expresie;

    Exist cazuri particulare ale instruciunii expresie:

    expresia de atribuire, care de altfel este cel mai important caz

    particular al instruciunii expresie:

    expresie;

    apelul unei funcii:

    nume_funcie (par1, par2, . . . parn);

    incrementrile i decrementrile pre i post fixate:

    variabil++; ++variabil;

    variabil- -; - - variabil;

    Exemplu:

    void main (void)

  • { int i; float f; double d; i=10; // instructiune de atribuire i++; // i se mareste cu 1 f=i; // instructiune de atribuire (valoarea lui i se converteste in float) d=++f; // incrementare lui f si atribuirea valorii lui d putchar(a); // instructiune de apel } 5.4. INSTRUCIUNEA COMPUS

    Instruciunea compus este o succesiune de declaraii urmate de

    instruciuni, succesiune inclus ntre acolade:

    {

    declaraii

    instruciuni

    }

    Pot lipsi declaraiile sau instruciunle dar nu n acelai timp. Dac

    delaraiile sunt prezente, atunci ele definesc variabile care sunt valabile

    numai n instruciunea compus respectiv.

    Exemplu:

    . . . { int i=100; // variabila i este definita in aceasta instructiune compusa i++; // i are valabilitate doar intre acolade; dupa acolada inchisa i isi printf (i=%d\n,i); // pierde valabilitatea }

    Observaii:

    1o. Dup acolada inchis a unei instruciuni compuse nu se pune ;.

    2o. Corpul unei funcii are aceeai structur ca i instruciunea

    compus, deci o funcie are formatul:

    antetul funciei

    instruciune compus

    5.5. INSTRUCIUNEA if

    Instruciunea if permite s realizm o ramificare a execuiei n

    funcie de valoarea unei expresii. Ea are dou formate ce permit aplicarea

    structurii de alternativ simpl i compus.

    Formatul 1:

    if (expresie) instructiune;

    Efectul:

    se evalueaz expresia din paranteze;

    dac valoarea expresiei este diferit de zero (deci conform

    conveniei are valoarea adevrat), atunci se execut instructiune, altfel

    se trece la instruciunea urmtoare.

    Formatul 2:

    if (expresie) instructiune_1;

    else instructiune_2;

    Efectul:

    se evalueaz expresia din paranteze;

    dac valoarea expresiei este diferit de zero (deci conform

    conveniei are valoarea adevrat), atunci se execut instructiune_1, altfel

    se execut instructiune_2; apoi n ambele cazuri se trece la instruciunea

    urmtoare.

    Observaii:

  • 1o. Se pot folosi instruciuni if imbricate, nivelul de imbricare

    fiind oarecare (deci nu exist o limitare a numrului de imbricri).

    2o. Pentru mai multe imbricri se folosete regula asocierii if-lui

    cu else astfel:

    un else se pune n coresponden cu primul if care se afl naintea

    lui n textul surs i nu este inclus n instruciunea care l precede pe

    el i nici nu i corespunde deja un else.

    Exemple

    void main (void) { float x,y,a; x=-5; y=10; if (x

  • Citeste n

    f=1

    i=2

    CtTimp i

  • }

    Invers, o instruciune while de forma: while (exp) instructiune este

    echivalent cu urmtoarea instruciune for:

    for(; exp; ) instructiune.

    Autorii limbajului C propun ca instruciunea for s se foloseasc cu

    prioritate pentru ciclurile care au pas.

    Exemple:

    Vom da o secven de instruciuni care nsumeaz elementele unui

    tablou:

    s=0;

    for(i=0; i

  • clrscr(); // sterge ecranul printf(\ndati un numar real pozitiv a=); if (scanf(%lf,&a) !=1 || a= EPS); printf (radacina patrata din:%g este: %.2lf\n,a,x2); // 2 zecimale } //sfirsit else }

    5.9. INSTRUCTIUNEA switch

    Instruciunea switch permite realizarea structurii alternativa

    generalizat. Ea este echivalent cu o imbricare de structuri de

    alternativ simple. Utilizarea instruciunii switch face n schimb

    programul mult mai clar.

    Formatul instruciunii switch este urmtorul:

    switch (exp)

    { case c1: sir1

    break;

    case c2: sir2

    break;

    . . .

    case cn: sirn

    break;

    default: sir

    }

    unde: c1,. . . cn sunt constante sau constante simbolice;

    sir1, . . . ,sirn, sir sunt iruri de instruciuni.

    Efectul:

    se evalueaz expresia din parantez;

    se compar pe rnd valoarea expresiei cu valorile constantelor c1, .

    . . , cn;

    dac valoarea expresiei coincide cu valoarea lui ck, se execut

    secvena de instruciuni definit prin sirk; n cazul n care valoarea

    expresiei nu coincide cu nici una din constantele c1, . . . , cn, se execut

    secvena de instruciuni definit prin sir;

    dup execuia secvenei sirk sau sir se trece la instruciunea

    urmtoare instruciunii switch, adic la prima instruciune aflat dup

    acolada nchis care termin instruciunea switch respectiv; evident,

    acest lucru are loc dac irul care se execut nu impune, el insui, un alt

    mod de continuare a execuiei, de exemplu o revenire din funcia

    respectiv, un salt la o anumit instruciune, etc.

    Observaii:

    1o. Ramura default nu este obligatorie. n lipsa ei, dac valoarea

    expresiei nu coincide cu nici una din constantele c1,. . . , cn,

    instruciunea switch respectiv nu are nici un efect.

    2o.Construcia break reprezint o instruciune. Ea termin fiecare

    ramur de instruciuni sir1, . . . , sirn, provocnd saltul la instruciunea

    urmtoare instruciunii switch sau, cum se mai spune, realizeaz ieirea

    din instruciunea switch.

    3o. Instruciunea break nu este obligatorie. n cazul n care este

    absent, se execut secvenial urmtoarea ramur. De exemplu dac avem

    secvena:

    switch (exp)

    { case c1: sir1

    case c2: sir2 }

  • ea se execut n felul urmtor:

    dac valoarea expresiei este egal cu c1 se execut sir1 i apoi sir2;

    dac valoarea expresiei este egal cu c2 se execut sir2;

    daca valoarea expresiei difera de valorile c1 i c2 instruciunea

    switch de mai sus nu este efectiv, se trece la instruciunea urmtoare

    care urmeaz dup switch.

    secvena de mai sus se putea realiza i astfel:

    if (exp = = c1)

    { sir1

    sir2

    }else if (exp = = c2) sir2

    Exemplu:

    Vom citi din fiierul de intrare construcii de forma: op1 operator

    op2, unde op1 i op2 sunt numere ntregi (operanzi ntregi) iar operator

    este un operator aritmetic {+, -, *, /}. La ieire se va scrie

    valoarea expresiei citite. De exemplu dac se citete secvena 100/3 se va

    afia rezultatul 33. Programul permite citirea i evaluarea mai multor

    astfel de expresii, pn la ntlnirea sfritului de fiier.

    #include void main (void) { int op1,op2,operator,rezultat,i; while (( i=scanf(%d %c %d, &op1,&operator, &op2)) != EOF) if (i = = 3 ) // ramura adevarat inseamna ca s-au citit 3 campuri corecte { switch (operator) { case +: rezultat = op1 + op2 ; // avem adunare break; case - : rezultat = op1 op2; // avem scadere break; case * : rezultat = op1 * op2; // avem inmultire break; case / : // avem impartire intreaga if (op2 = = 0) { printf (divizor nul\n); rezultat = 0; } else rezultat = op1 / op2; break; default : printf (operator eronat\n); rezultat = 0; } // sfarsit switch printf (%d %c %d %d\n, op1, operator, op2, rezultat); } else

    printf (expresie eronat\n); // sfarsit if si while }

    5.10. INSTRUCIUNEA break

    Formatul instruciunii este urmtorul:

    break;

    De obicei instruciunea break se folosete pentru a iei dintr-un

    ciclu. Dac exist mai multe cicluri imbricate instruciunea break va trece

    controlul la ciclul de nivel imediat superior (deci imbricarea rmne, nu

    se iese din toate ciclurile). O alt utilizare este n instruciunea

    switch, dup cum am observat n paragraful anterior.

    Un alt exemplu de utilizare frecvent este ieirea dintr-un

    ciclu infinit de forma:

    for ( ; ; )

    {. . .

    if (exp) break;

    . . .

  • }

    5.11. INSTRUCIUNEA continue

    Formatul instruciunii este urmtorul:

    continue;

    Efectul:

    n ciclurile while i do-while ea realizeaz saltul la evaluarea

    expresiei care decide asupra continurii ciclului;

    n ciclul for ea realizeaz saltul la pasul de reiniializare.

    Observaie:

    1o. Instruciunea continue se utilizeaz numai n corpul unui ciclu,

    permind, dup caz, s se treac la pasul urmtor al ciclului sau s se

    ias din ciclu.

    5.12. INSTRUCIUNEA goto

    Conform principiilor programrii structurate instruciunea goto

    nu ar fi necesar. Dar ea a fost introdus n limbaj, deoarece, n anumite

    cazuri, se dovedete a fi util, asigurnd o flexibilitate mai mare n

    programare. De multe ori ieirea dintr-un ciclu imbricat n alte cicluri se

    realizeaz mai simplu cu ajutorul instruciunii goto. n lipsa ei ar trebui

    s folosim mai muli indicatori i teste asupra valorilor acestora pentru

    ieirea din ciclu. Saltul fcut de goto se face la o instruciune care este

    prefixat de o etichet.

    Prin etichet vom nelege un nume urmat de caracterul :.

    Etichetele sunt locale unei funcii.

    Instruciunea goto are urmtorul format:

    goto eticheta;

    Efectul:

    se realizeaz saltul la instruciunea prefixat de eticheta al crei

    nume se afl scris dup cuvntul cheie goto.

    5.13. APELUL I REVENIREA DINTR-O FUNCIE

    5.13.1. Apelul unei funcii

    n limbajul C funciile sunt de dou tipuri:

    funcii care returneaz o valoare la revenirea din ele;

    funcii care nu returneaz nici o valoare la revenirea din ele.

    O funcie care nu returneaz nici o valoare la revenirea din ea se

    apeleaz printr-o instruciune de apel. Ea are urmtorul format:

    nume (lista_parametrilor_efectivi); (*)

    unde:

    nume este numele funciei;

    lista_parametrilor_efectivi este fie vid, fie se compune din una sau

    mai multe expresii separate prin virgul.

    Instruciunea de apel este un caz particular al instruciunii

    expresie. Parametrii efectivi (de la apel) trebuie s corespund cu cei

    formali (de la definirea funciei) prin ordine, tip i numr.

    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.

    Observaii:

    1o. Dac nu dorim s utilizm valoarea returnat de funcia

    respectiv, apelul se face printr-o instruciune de apel.

  • 2o. Dac dorim s utilizm valoarea returnat de funcie, vom folosi

    apelul funciei drept operand ntr-o expresie, operandul avnd formatul

    (*).

    Exemple de apeluri de funcii folosite pn acum sunt apelurile

    funciilor standard printf, scanf, getchar i putchar. Funciile printf i

    putchar au fost apelate prin instruciuni de apel, valorile returnate de

    ele nefiind utilizate. n schimb funciile scanf i getchar au fost apelate

    n ambele moduri, att prin instruciuni d