Limbajul_C_in_2h

download Limbajul_C_in_2h

of 11

Transcript of Limbajul_C_in_2h

  • 8/7/2019 Limbajul_C_in_2h

    1/11

    Limbajul C n dou ore

    Vom face aici o prezentare general a limbajului C (cu cteva elemente de C++) plecnd

    de la rezolvarea urmtoareiprobleme de programare:

    Scriei un program care afieaz pe monitor mesajul Voi scrie C de n ori, dup

    care apare mesajul n= i ateapt ca utilizatorul s tasteze valoarea lui n, numr ntreg.

    Dac n e strict pozitiv programul scrie Ok i afieaz de n ori litera C, altfel apare

    mesajul Nu pot afisa ceva de ### ori unde, pe monitor, n locul marcat cu

    ### trebuie s apar valoarea lui n.

    Iat cum ar trebui s arate monitorul la finalul execuiei n fiecare caz n parte:

    cazul n>0

    i cazul n

  • 8/7/2019 Limbajul_C_in_2h

    2/11

    Incepem editarea fiierului surs al programului, s l numim primul.cpp, cu urmtoarea

    linie:

    /* Primul program ilustrativ */

    care conine un comentariu n stilulC. Compilarea textului surs se execut linie cu linie, de sus

    n jos, fiecare linie fiind citit de la stnga la dreapta. Compilatorul ignor toate caracterele dintre

    perechile /* i */ (inclusiv pe acestea), aa c avem la dispoziie un spaiu n care putem scrie ce

    vrem. Un astfel de comentariu se poate ntinde pe mai multe linii. Comentariile nu fac parte din

    program, ele au rolul de a da unele lmuriri celui ce citete textul surs i, n cazul programelor

    complexe, sunt foarte utile pentru nelegerea diverselor secvene de cod. Exist istilulC++ de

    comentariu, acestea ncep cu dou slash-uri, //, i se termin la captul liniei, ele sunt utilizate

    pentru a da scurte indicaii asupra coninutului liniei de cod curente. Prezena comentariilor este

    facultativ, dar recomandabil.

    Urmtoarea linie este obligatorie:# include

    Aceast linie conine o directiv de preprocesare i nu face nici ea parte din program. Dup ce

    lansm comanda Compile compilatorul, nainte de a ncepe compilarea propriu-zis a

    fiierului, lanseaz n execuie preprocesorul un program specializat n prelucrarea automat a

    textelor (prin substituii) - care citete toate directivele de preprocesare i le execut. In cazul

    directivei include linia directivei este nlocuit cu ntreg coninutul fiierului iostream, fiier

    care conine tot ce este necesar programului pentru executarea operaiilor de citire/scriere

    (sinonime: intrare/ieire, input/output). Printre altele, prin acest mecanism ajung n fiierul

    nostru surs definiiile obiectelor cout i cin (ca instane ale unor clase de fluxuri de date,

    stream-uri).Identificatorulcout desemneaz consola de ieire (output console), adic monitorul,iarcin desemneaz consola de intrare (input console), adic tastatura. Fr aceast directiv de

    includere a bibliotecii iostream compilatorul ar da, la prima apariie a cuvntului cout, mesajul

    de eroare 'cout' : undeclared identifier. Alte biblioteci des utilizate:

    pentru funcii matematice (exponeniale, logaritmi, funcii trigonometrice, etc) i

    pentru operaii cu iruri de caractere (string-uri).

    Subliniem de la bun nceput c textul surs trebuie editat(scris) numai cu un set restrns

    de caractere: literele a,b,c, ... , z, A,B,C, ... , Z, cifrele 0,1, ..., 9, i simbolurile direct imprimabile

    de la tastatur:

    obinem la compilare eroarea: invalid preprocessor command 'INCLUDE'.

    De remacat i faptul c, pentru o scriere mai lizibil, se pot insera oricte blancuri (cu

    tastele space sau tab) ntre atomii lexicali (tokens) ai directivei. E corect i aa

    2

  • 8/7/2019 Limbajul_C_in_2h

    3/11

    # include < iostream >

    dar s nu exagerm. Aceast facilitate trebuie folosit pentru aezarea n pagin, ntr-un mod ct

    mai clar, a textului surs. In faza de preprocesare compilatorul terge toate spaiile care nu sunt

    neaparat necesare pentru pstrarea sensului directivelor i al instruciunilor.

    Directivele de preprocesare nu fac parte din limbajul C (nici din C++), ele sunt specifice

    fiecrui compilator n parte. Ca regul general, ele ncep cu simbolul # i se termin n

    aer, fr un simbol terminator (cum este ; pentru instruciunile C). Ca exemplificare, dintre

    directivele de preprocesare ale mediului de dezvoltare MS Visual C++ 9.0 mai menionm pe

    #define i #using (vezi http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx).

    Urmeaz acum nc o linie de cod care va fi prezent n toate programele noastre:

    using namespace std;

    i care deseori este numit directiva using dei ea este o instruciune C++. Denumirea poate

    crea confunzii, mai ales c exit chiar o directiv de preprocesare #using, dar este folosit

    pentru a sugera asemnarea dintre efectul acestei instruciuni i o substituie de texte efectuat lapreprocesare: ca i cum, de exemplu, identificatorul cout ar fi nlocuit cu std::cout peste tot

    unde apare n textul surs.

    Ca urmare a creterii complexitii programelor i a utilizrii unor biblioteci de funcii i

    de clase tot mai bogate, pentru a evita coliziunile tot mai frecvente dintre nume (utilizarea

    aceluiai identificator pentru obiecte diferite) n C++ a fost introdus mecanismul spaiilor de

    nume: programatorul poate prefixa identificatorii utilizai, cu sintaxa

    prefix::identificator

    prefixul desemnnd un anumit spaiu de nume, namespace. Instruciunea noastr using declar

    c vom utiliza spaiul de nume std (standard) i este necesar pentru a simplifica referirea

    fluxurilor standard cin i cout. Fr aceasta ar trebui s scriem std::cin n loc de cin, deexemplu.

    Instruciunea using namespace std;este compus din patru atomi lexicali: cuvintele

    cheie using i namespace (aparinnd limbajului C++), identificatorul std (care denumete

    spaiul de nume standard cel mai des folosit) i terminatorul de instruciuni ;. Identificatorul

    std este definit undeva n codul inclus n programul nostru prin directiva #include,

    ca dovad, dac schimbm ordinea acestor dou linii obinem la compilare eroarea: 'std' : a

    namespace with this name does not exist.

    Instruciunile limbajului C se termin, cele mai multe, cu simbolul ;, dac sfritul unei

    instruciuni coincide cu sfritul unui bloc { } terminatorul ; nu mai este necesar (cu excepia

    cazului cnd este cerut expres de sintaxa instruciunii. Simbolul ; nu este separator ci

    terminator de instruciuni: el face parte integrant din instruciunea pe care o finalizeaz. De

    exemplu, pe linia

    a=1; b=2; c=a+b;

    am scris, cu ajutorul a 14 caractere, trei instruciuni, prima instruciune este scris cu 4 caractere,

    a doua tot cu 4, a treia cu 6 caractere, iar ntre instruciuni nu se afl nimic. Regula este

    3

    http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspxhttp://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx
  • 8/7/2019 Limbajul_C_in_2h

    4/11

    urmtoarea: n textul surs, o instruciune ncepe imediat dup ce se termin cea dinaintea ei.

    Reamintim c blancurile sunt eliminate la preprocesare, aa c pentru a face programul ct mai

    lizibil, instruciunile se scriu cte una pe linie i ct mai aerisit.

    Iat acum i codul sursal programului nostru:

    char litera='C';

    int citeste(void){

    int n;

    coutn;

    return n;

    }

    void afiseaza(int nr){

    int i;

    for(i=0; i

  • 8/7/2019 Limbajul_C_in_2h

    5/11

    declarat n mod explicit de programator astfel nct compilatorul s tie, n principal, cum s

    organizeze memoria alocat acelei date.

    Cu instruciunea declaraie:

    char litera='C';

    declarm variabila litera ca fiind o dat de tip char i o iniializm cu valoarea 'C'. Cuvntul

    litera este identificatorulcare d numele variabilei, i a fost ales de noi, spre deosebire de

    char care este un cuvnt cheie al limbajului (un identificator rezervat) i care poate fi folosit

    numai pentru a desemna tipul de dat caracter pe un octet. Identificatorii pot fi formai numai

    din litere, cifre i caracterul _ (underscore), cu restricia c primul caracter nu poate fi o cifr.

    Lungimea maxim a unui identificator depinde de compilator (pentru MS Visual C++ 9.0 vezi

    http://msdn.microsoft.com/en-us/library/565w213d.aspx).

    Variabila litera fiind declarat de tip char, la ntlnirea instruciunii de mai sus

    compilatorul rezerv un octet de memorie pentru variabila litera i scrie n acest octet codul

    ASCII al literei C (i anume 43 hexa).

    Tipurile uzuale pentru variabile simple sunt: char pentru caractere, int pentru numerentregi i double pentru numere reale n dubl precizie (fa de float simpl precizie).

    Variabila litera este global deoarece a fost declarat n exteriorul oricrei funcii.

    Valorile ei pot fi utilizate direct de ctre toate funciile care sunt definite dup declararea ei,

    altfel spus, numele ei este vizibildin orice punct al fiierului surs de dup linia n care a fost

    declarat. Spre deosebire de ea, variabilele declarate n interiorul unei funcii sunt variabile

    locale, ele pot fi referite numai n interiorul corpului funciei n care sunt declarate.

    Declaraiile pot fi fcute i fr iniializarea variabilei declarate, n felul urmtor:

    char litera;

    dar n acest caz trebuie s avem grij ca, nainte de a o folosi, s i atribuim variabilei litera o

    valoare iniial, printr-o instruciune expresie, de exemplu,litera='C';

    Atenie, spre deosebire de instruciunile declaraii, care pot apare oriunde n textul surs,

    instruciunile expresie pot s apar numai n interiorul corpului unei funcii.

    S analizm acum definiia funciei citeste

    int citeste(void){

    int n;

    coutn;

    return n;

    }

    O funcie este format dintr-osecven de instruciuni care prelucreaz datele de intrare

    n funcie (valorile actuale ale argumentelor funciei), mpreun cu alte date proprii, i care

    returneaz ctre funcia apelant, o dat de ieire, rezultatulfunciei. Exist i funcii fr date de

    intrare, precum i funcii care nu returneaz nimic.

    5

    http://msdn.microsoft.com/en-us/library/565w213d.aspxhttp://msdn.microsoft.com/en-us/library/565w213d.aspx
  • 8/7/2019 Limbajul_C_in_2h

    6/11

    Din prima linie a definiiei funciei citeste deducem c aceasta nu are date de intrare

    (acolo unde ar trebui s fie lista parametrilor este scris cuvntul cheie void - vacant) iar

    rezultatul ei este de tip int (adic va returna un numr ntreg).

    In general, definiia unei funcii are forma:

    tip_returnat nume_funcie (lista_parametrilor_funciei) {

    corpul_funciei

    }

    Dac este nevoie, putem numai s declarm funcia (fr s o i definim), scriind numai

    prototipul funciei (adic antetul funciei urmat de terminatorul de instruciune ;) astfel

    tip_returnat nume_funcie (lista_parametrilor_funciei);

    dar tot va trebui s definim, undeva mai jos, nainte de sfritul fiierului surs, funcia.

    Corpul funciei se scrie ntotdeauna ntre dou acolade pereche, {}, i este format dintr-o

    secven de instruciuni. Nu este permis imbricarea funciilor, adic definirea unei funcii n

    interiorul corpului alteia.

    In corpul funciei citeste declarm variabila n, scriem pe monitor mesajul "n=", citim dela tastatur valoarea variabilei n i returnm, ca rezultat al funciei, valoarea citit.

    Pentru afiarea valorii unei variabile oarecare, x de exemplu, utilizm operatorul de

    scriere ,

  • 8/7/2019 Limbajul_C_in_2h

    7/11

    cnd vrem s citim mai multe valori, este mai sigur s scriem pentru fiecare citire cte o

    instruciune n parte sau chiar cte o pereche de instruciuni (prima pentru afiarea unui mesaj

    explicativ i a doua pentru citirea propriu-zis), aa cum am ntlnit deja

    coutn;

    Execuia unei funcii se ncheie cnd fluxul de control ajunge la execuia unei instructiuni

    return, sau, dac funcia nu trebue s ntoarc nici un rezultat, la atingerea acoladei care incheie

    corpul funciei. Funcia citeste se ncheie cu instruciunea

    return n;

    care depune n registrul EAX al microprocesorului valoarea variabilei n, de unde estepreluat de

    funcia apelant. In exemplul nostru, citeste este apelat o singur dat, n funcia main, de

    instruciunea

    k=citeste();

    care atribuie variabilei kvaloarea citit de funcie de la tastatur. Observai c la apelarea unei

    funcii fr argumente nu se folosete cuvntul cheie void.Funcia afiseaza

    void afiseaza(int nr){

    int i;

    for(i=0; i

  • 8/7/2019 Limbajul_C_in_2h

    8/11

    Dac trebuie s executm mai multe aciuni n corpul for-ului, vom folosi o instruciune

    compus, grupnd n interiorul unei perechi de acolade, {}, mai multe instruciuni simple (aa

    cum avem de exemplu ramura else a instruciunii ifdin funcia main).

    S analizm acum funcia principal:

    int main(void){

    int k;

    cout

  • 8/7/2019 Limbajul_C_in_2h

    9/11

    if (expresie_test)instructiune_corp

    i care, dac testul este ndeplinit, insereaz n fluxul de control al execuiei instruciunea corp,

    altfel nu face nimic.

    In mod obinuit, expresiile test sunt comparaii de forma ab. De reinut c expresia a==b testeaz dac a este egal cu b, n timp ce expresia a=b

    atribuie lui a valoarea lui b (operatorul == este operatorul de comparaie, iar operatorul =

    este operatorul de atribuire). Deoarece n limbajul natural semnul egal este folosit n ambele

    sensuri (i comparaie i atribuire), n limbajul C se produc adesea erori prin utilizarea unui

    singur semn de egalitate acolo unde ar trebui dou semne. O astfel de eroare este greu de

    depistat, ea nu iese la compilare (compilatorul accept i atribuirea a=b ca expresie test n if

    sau for - vom vedea mai trziu de ce), iar la rulare programul d rezultate haotice. Pentru

    evitarea acestei situaii unele compilatoare de C, cnd ntlnesc atribuiri n expresii condiionale,

    avertizeaz utilizatorul asupra posibilei confuzii. Mai mult, unele limbaje de programare

    provenite din C, cum ar fi Java sau C#, au introdus tipuri logice de date astfel nct s fac

    imposibil aceast eroare de editare. MS Visual C++ 9.0 nu d nici un avertisment, aa c trebuies fim ateni la comparaii.

    S urmrim acum evoluia mijloacelor de calcul prin prisma creterii complexitii:

    primile maini mecanice de calcul efectuau doar calcule cu cte o singur operaie (cum fac

    acum cele mai simple calculatoarele de buzunar). Au aprut apoi calculatoare electronice

    capabile s efectueze mai multe operaii la o singur comand, s evalueze o ntreag expresie

    aritmetic (exist i astzi calculatoare de buzunar care pot evalua formule). Urmtoarea etap:

    calculatoare capabile s evalueze mai multe expresii la o singur comand, prin rularea unui

    program format dintr-o secven de instruciuni executate ntr-o ordine dictat de rezultatele

    expresiilor evaluate. Iniial calculatoarele programabile dispuneau de puin memorie intern, deordinul kiloocteilor, aa c programele trebuiau s fie scurte, cu cteva instruciuni; pentru

    prelucrri complexe ele au fost organizate ca sub-programe (funcii, proceduri, subrutine, etc.) i

    ncrcate n memorie doar atunci cnd erau apelate. Dup cum am vzut deja, un program C este

    o colecie de astfel de sub-programe.

    Evoluia a continuat: pentru utilizarea mai multor programe C n acelai timp, acestora

    li s-au scos funciile principale i au fost transformate n clase, variabilele globale devenind

    variabile membru iar funciile rmase devenind funcii membru ale claselor. Incrcarea lor n

    memorie a fost transformat n instanierea claselor, iar lansrile n execuie au fost nlocuite cu

    apeluri ctre funciile membru, apeluri fcute prin intermediul instanelor (obiectelor) clasei. Pe

    scurt, n C++ a fost introdus tipul class, programatorul avnd posibilitatea s-i defineasc

    propriile clase sau s foloseasc unele deja existente, prin definirea unei clase se definete un nou

    tip de dat, de complexitatea unui vechi program C, pentru utilizarea unei clase trebuie s

    declarm i s iniializm o variabil de tipul dat de acea clas, adic s instaniem un obiectal

    clasei.

    De exemplu, n fiierul iostream din directorul \include al compilatorului MS Visual C+

    + 9.0 gsim urmtoarea declaraie:

    9

  • 8/7/2019 Limbajul_C_in_2h

    10/11

    extern ostream &cout;

    Aceast instruciune declar cout ca fiind o referin (iniializat ntr-un fiier extern) ctre un

    obiect din clasa ostream, care este o clas specializat n operaii de ieire (output stream). Tot

    n fiierul iostream gsim directiva #include, iar n fiierul istream gsim

    #include. Noi am inclus n fisierul nostru surs fiierul iostream i astfel, prin

    includeri succesive, definiia clasei ostream i declaraia lui cout ajung n fiierul surs al

    programului nostru, transformndu-l ntr-un program C++, dei n liniile de cod scrise de noi este

    definit nici o clas.

    In final, deoarece programele noastre C sunt de fapt programe C++, trebuie s precizm

    urmtoarele: limbajul C++ este o extensie a limbajului C realizat prin adugarea tipului de dat

    class, un program C++ este format din declaraii de variabile globale i din definiii de clase i

    de funcii care manipuleaz obiecte din aceste clase, dintre funcii una se numete main i cu ea

    ncepe execuia programului. Aceast extindere a limbajului a fost iniiat n 1979 de ctre

    Bjarne Stroustrup, cercettor la AT&T Bell Laboratories (tot acolo unde a fost creat i limbajul

    C), care iniial a numit noul limbaj "C with Classes" i apoi, n 1983, i-a dat denumireadefinitiv de C++. Manualul fundamental a fost scris de Bjarne Stroustrup n 1985, The C++

    Programming Language. Pentru mai multe amnunte, vezi pagina personal a autorului,

    http://www.research.att.com/~bs/.

    Pentru a ilustra cele spuse mai sus despre noiunea de clas, prezentm n final varianta

    C++ a programului nostru, obinut prin schimbri minimale, n care programul nostru C devine

    o clas C++:

    #include

    usingnamespace std;

    class scriitor{

    public: char litera;

    int citeste(void){

    int n;

    coutn;

    return n;

    }

    void afiseaza(int nr){

    int i;

    for(i=0; i

  • 8/7/2019 Limbajul_C_in_2h

    11/11

    cout