ipc hatz

Embed Size (px)

Citation preview

  • 8/18/2019 ipc hatz

    1/61

    1

    CURS 2.. Ettapelle realliiz!r iiii unuii program.. Insttructtiiunii preprocesor ..Af f iisarea lla ecran sii ciittiire de lla ttasttattura

    2.1. Etapele realiz!rii unui programRealizarea unui program presupune implicarea mai multor etape. Aceste etape suntindependente de limbajul de programare utilizat "i implic! existen#! c.torva restric#ii cu privire la computerul/limbajulutilizat.Etapelerealiz!rii unui program sunt:1. Studierea detaliat! a cerin#elor aplica#iei. Este foarte important ca cerin#ele impuse deaplica#ie s! fie foarte bine explicitate. Adic! .nainte de a trece la realizarea unui program pentru o anumit! aplica#ie trebuie ca ceaaplica#ie sa fie foarte bine analizat! "i cerin#ele pe care aceasta le impune trebuie s! fie

    complete "i consistente.De exemplu o cerin#! de genul “scrie un program care sa rezolve ecua#iile” este evidentc! este incomplet! "i seimpun .ntreb!ri de genul “ce tip de ecua#ii”, “c.te ecua#ii”, “care este precizia”, etc.2. Analiza problemei "i determinarea rezolv!rii acesteia. In aceast! etap! se decide asupraunei metode derezolvare a problemei (algoritm).3. Traducerea algoritmului realizat la etapa anterioar ! .ntr-un limbaj de programareevoluat corespunz!tor. Formascris! a acestui program este denumit! program surs! (PS, source program sau sourcecode). .n aceast! etap! 

     programul trebuie citit "i verificat pentru a i se stabili corectitudinea. Aceasta se face prinintroducerea unui setde valori "i verificarea dac! programul furnizeaz! valorile corespunz!toare corecte. Odat! verificat programuleste scris .ntr-un anumit limbaj prin intermediul unui Editor.24. Compilarea programului .n limbaj ma"in!. Astfel programul ob#inut .n limbaj ma"in! se nume"te cod obiect(object code). .n aceast! etap! compilatorul poate determina erori de sintax! ale programului. O eroare desintax! este o gre"eal! .n gramatica limbajului. De exemplu .n C trebuie ca fiecare linie s! se termine cu ;Dac! se uit! plasarea ; atunci compilatorul va semnala eroarea de sintax!. Astfel se repet! compilarea p.n! laeliminarea tuturor erorilor de sintax!.5. Programul ob#inut .n urma compil!rii, object code, este apoi corelat (linked) cu o seriede biblioteci de func#ii(function libraries) care sunt furnizate de sistem. Toate acestea se petrec cu ajutorul unui program numit linkeditor(linker) iar apoi programul linked object codeeste .nc!rcat .n memoria computerului dec!tre un programnumit loader.6. Rularea programului compilat, link-editat "i .nc!rcat cu un set de date pentru testare.

    Astfel se vor pune .neviden#! erorile de logic! ale programului. Erorile de logic! sunt erori care sunt produse

  • 8/18/2019 ipc hatz

    2/61

    de metoda derezolvare a problemei. Astfel de"i programul este scris corect din punct de vedere alsintaxei acesta poateexecuta ceva ce este incorect .n contextul aplica#iei. Poate fi ceva simplu, de exemplurealizarea unei opera#ii

    de sc!dere .n loc de adunare. O form! particular ! a erorilor de logic! este apari#ia erorilorde rulare (run-timeerror). O eroare de rulare va produce o oprire a programului .n timpul execu#iei pentru c! nu anumiteinstruc#iuni nu pot fi realizate. De exemplu o .mp!r #ire la zero sau .ncercarea de accesarea datelor dintr-unfi"ier inexistent.Astfel se impune ca .n aceast! etap! programul s! fie reverificat "i apoi erorile s! fierecorectate prinintermediul editorului ceea ce impune ca etapele 3,4, "i 5 s! fie repetate p.n! la ob#inerearezultatelor

    satisf !c!toare.7. Programul poate fi pus .n execu#ie pentru rezolvarea problemei pentru care a fostconceput. Este posibil ca pe parcursul execu#iei sale s! se mai depisteze anumite erori de logic!. Astfel se impunereformularea algoritmului"i reluarea etapelor de realizare a programului.Programul poate fi rulat in mod debug – adic! pas-cu-pas pentru a putea verifica execu$ia punctual! a fiec!reivariabile. In acest sens, in mod debug, putem insera breakpoints, iar programul va rula pana la intalnirea acestora,sau putem executa programul pana la linia unde se afla cursorul.Pentru executia pas cu pas, avem 2 optiuni:- Step-in – care permite intrarea si execu$ia pas-cu-pas in func$iile din linia curent! - Step-over – care permite executia intr-un singur pas (totul o sigura data) a func $iilor dinlinia curent! decod.La executia in mod debug avem activat! fereastra Watch in care putem solicita afisareavalorilor pentru variabileledin program.Prezent!m mai jos schema unui compilator.3.n procesul de comunicare om-calculator intervine un program intermediar, translatorul,care asigur ! 

    traducerea programelor scrise de utilizator din cod surs! .ntr-un alt limbaj mai apropiat decalculator.Dac! limbajul #int! este codul ma"in!, translatorul se nume"te compilator.Astfel, execu#ia unui program surs! se realizeaz!, .n cadrul limbajelor compilative, seface .n 2 faze:- compilare, care traduce codul surs! .n program obiect- execu#ie, care ruleaz! codul obiect pe calculator, folosind datele ini#iale ale programului"i produce rezultateConceptual, compilatorul realizeaz! dou! mari clase de opera$ii: analiza textului surs! %isinteza codului obiect.Compilatorul unui limbaj de asamblare se nume"te asamblor.

    .n practic!, pe l.ng! compilatoarele obi"nuite, exist! "i alte tipuri de compilatoare.Astfel, preprocesoarele sunt translatoare care traduc dintr-un limbaj de nivel .nalt .n alt

  • 8/18/2019 ipc hatz

    3/61

    limbaj de nivel .nalt.2.2.Func#ii de intrare/ie"ireFunc#ia printfconverte"te, formateaz! "i tip!re"te argumentele sale la ie"irea standard sub controlul"irului de control. Este o

    func$ie de bibliotec! care realizeaz! ie%iri cu format ( in stdio.h).Formatul general al acestei instruc#iuni este: printf(control,param1, param2, ..., paramn);control este un "ir de caractere ce con#ine 2 tipuri de obiecte:1)caractere ordinare care sunt simplu copiate .n "irul de ie"ire2)semnifica#ii de conversie care cauzeaz! conversia "i tip!rirea urm!toarelor argumentesuccesive ale lui printf. param1, param2, …, paramn sunt expresii ale c!ror valori se scriu conformspecificatorilor de format prezenti in parametrul de control.Un specificator de format .ncepe prin caracterul % "i se .ncheie prin caracterul de

    conversie. .ntre caracterul % "icaracterul de conversie pot ap!rea:o semnul minus care specific! cadrarea la st.nga .n c.mp a argumentului convertitAnalizalexical! Analizasintactic! Analizasemantic! Optimizarede codGenerare decod

    TratareaerorilorGestiuneatabelelorProgramsurs! Sir de atomilexicaliArboresintacticCodintermediarCod intermediaroptimizat

    Programobiect

    Analiza Sinteza4o un "ir de cifre zecimale optional, care specific! dimensiunea minim! a c.mpului .n carese editeaz! data.Dac! data necesit! mai pu#ine pozi#ii dec.t c.mpul descris de acest "ir atunci el va ficompletat la st.nga cucaractere nesemnificative (sau la dreapta dac! s-a folosit semnul minus .n specificatorulde formatrespectiv). Caracterele nesemnificative implicite sunt spa#iile. Dac! "irul de cifre .ncepe

    cu un zeronesemnificativ, caracterele nesemnificative vor fi zerouri.

  • 8/18/2019 ipc hatz

    4/61

    o Un punct op$ional separ ! "irul de cifre ce define"te dimensiunea minim! a c.mpului de"irul urm!tor decifre ce semnific! preciziao un "ir de cifre ce define"te precizia care specific! num!rul maxim de caractere acceptatedintr-un "ir de

    caractere sau num!rul de zecimale care se vor scrie .n cazul numerelor reale.Deci semnifica#iile de conversie au structura:%[-][sir_de_cifre][.][sir_de_cifre]cCaracterul de conversie c poate avea urm!toarele valori:Car Semnifica#ied Data se converte%te din int .n .ntreg zecimal cu semni .ntreg zecimal cu semno Data se converte%te din int .n .ntreg octal f !r ! semnx Data se converte%te din int .n .ntreg hexagesimal f !r ! semn (cu litere mici)X Data se converte%te din int .n .ntreg hexagesimal f !r ! semn (cu litere mari)u Data de converte%te din unsigned .n .ntreg zecimal f !r ! semn

    c caracters "ir de caracteree num!r .n virgul! flotant! sau flotant dubl! precizie "i e convertit .n zecimal sub forma:[-]m.nnnnnn e [Å}]xx.Implicit num!rul de zecimale este 6 iar dac! se specific! precizia, num!rul de zecimale vafiindicat de aceasta.E analog dar se folose"te Ef num!r .n virgul! mobil! simpl! sau dubl! precizie iar argumentul va fi convertit .nnota#iezecimal! g .n acest caz se va folosi forma cea mai scurt! dintre %e "i respectiv %fG forma cea mai scurt! dintre %E "i respectiv %f p afi"eaz! un pointer (o adres!)n plaseaz! .n argumentul asociat num!rul de caractere afi"at p.n! .n acel moment defunc#ia printfExemple:"%5f" arat! ca num!rul are o lungime de cel pu#in 5 caractere“%05d” determin! umplerea cu zerouri a unui num!r mai mic de 5 cifre, astfel .nc.tlungimea total! s! fie 5"%.2f" solicit! dou! pozi#ii dup! punctul zecimal, dar lungimea lui nu este supus! 

    restric#iilor“%-5.2f” determin! afi"area pe cel pu#in 5 pozi#ii din care exact 2 zecimale aliniat last.nga (datorit! prezenteisemnului ‘-‘)“%.0f” suprim! tip!rirea p!r #ii frac#ionare“%5.10s” determin! afi"area unui "ir pe cel pu#in 5 pozi#ii dar nu mai mult de 10caractere“%%” determin! afi"area caracterului % printf(“Folosim%n caracterul %%n”,&p); //determin! .nc!rcarea .n variabila//pointat! de pointerul p a valorii 7 (‘Folosim’ are 7 litere)5

    Exist! posibilitatea de a utiliza doi modelatori de format pentru a afi "a .ntregi de tip short"i long. Ace"ti doi

  • 8/18/2019 ipc hatz

    5/61

    modelatori sunt h "i l. Se folose"te %hd pentru a tip!ri un short int "i %ld pentru a tip!riun long int.Modelatorul L se aplic! numerelor .n virgul! mobil! permi#.nd afi"area unui long double.Astfel, se folose"te L .nfa#a caracterului de conversie e, f sau g.

    Prezen#a modelatorului # .n fa#a caracterului de conversie g, G, f, e sau E determin! afi"area unui punct zecimalchiar dac! nu exist! cifre zecimale.Func#ia scanfCite"te date de la intrarea standard pe care le converte"te .n format intern conformspecificatorilor. Prototipulfunc#iei scanf se g!se"te .n headerul stdio.h "i are forma:scanf(control,param1, param2, ..., paramn);Func#ia scanf returneaz! num!rul c.mpurilor citite sau EOF dac! se .nt.lne"te prematurmarca de sf.r "it de fi"ier(detalii despre EOF la capitolul despre fisiere).

    &irul de control poate con#ine 3 tipuri de obiecte: specificatori de format, caractere albesau alte caractere.Specificatorul de format este precedat de caracterul % "i specific! tipul valorii ce urmeaz! a fi citite. Ace"tia suntidentici cu cei prezenta#i la func#ia printf.Un caracter alb .n "irul de control determin! neglijarea unuia sau mai multor caracterealbe din intrare. Un caractercare nu este alb determin! ca scanf s! citeasc! "i s! neglijeze caracterul respectiv dinintrare.Exemplu:scanf(“%d,%d”,&a,&b);//determin! citirea unui .ntreg, apoi caracterul virgul! care seneglijeaz! "i .n finalcitirea unui alt .ntregDac! caracterul specificat nu se g!se"te .n intrare, se termin! execu#ia func#iei scanf.Toate variabilele a c!rorvalori se citesc cu func#ia scanf trebuie transmise prin adres!. Astfel, pentru variabilelesimple se folose"teoperatorul &.Pentru un "ir de caractere citit cu %s se poate scrie doar numele "irului. Un element detablou precum a[i] se poateciti folosind &a[i] sau simplu folosind a+i.Datele din intrare trebuie separate prin caractere albe. Caracterele de punctua#ie punct,virgul! "i punct "i virgul! 

    nu sunt considerate separatori. Caracterele albe sunt folosite ca "i separatori dar pot ficitite "i ca orice caracterefolosind codul de format %c.Caracterul * plasat dup! % "i .nainte de litera de format determin! citirea datei de tipulrespectiv dar nu seasigneaz! nici unei variabile.Exemplu:scanf(“%d%*c%d”,&x,&y);-dac! .n intrare vom avea 10/20 va determina citirea .n variabila x a valorii 10, citireacaracterului / care nuse aloc! nici unei variabile dup! care variabilei y i se atribuie valoarea 20.

    .n specificatorul de format poate fi indicat! lungimea maxim! a c.mpului care poate ficitit.

  • 8/18/2019 ipc hatz

    6/61

  • 8/18/2019 ipc hatz

    7/61

    }Exemplu: Se testeaza daca s-a citit o litera mare si numai in acest caz se aplicatransformarea in litera mica. Incazul in care la intrare nu se afla o litera mare, se rescrie caracterul respectiv.#include

    int main(){7int c; putchar(((c=getchar())>=‘A’&&c

  • 8/18/2019 ipc hatz

    8/61

    Acestea au .ntotdeauna ca "i prim caracter simbolul # "i permit efectuarea de manipul!ri.n textul programuluisurs! .naintea compil!rii sale.Liniile care .ncep cu simbolul # au o sintax! independent! de restul limbajului, pot ap!reaoriunde .n cadrul

     programului surs! (dar se recomand! plasarea la .nceputul lui) "i au efecte cu remanen#!  p.n! la sf.r "itul execu#iei programului sau p.n! c.nd o nou! directiv! anuleaz! acest lucru. Fiecare din directivele preprocesor trebuie s! seg!seasc! pe o linie separat!.8Substitu#ia lexical! se face prin directiva:#define identificator [text]Dac! identificatorul este recunoscut ca element lexical .n analiza programului surs!, preprocesorul va .nlocui toateapari#iile ulterioare ale identificatorului cu secven#a text precizat!. Dac! textul trebuie s! 

    se extind! pe mai multelinii, liniile intermediare vor fi precedate de un caracter ‘Ä’. Textul poate fi "i vid ceea ceva avea ca "i efectsuprimarea din textul surs! a tuturor apari#iilor identificatorului. Pentru a distinge maiu"or identificatorulsubstituit, se recomand! folosirea majusculelor.Exemple:#define void //suprimarea din textul surs! a tuturor apari#iilor identificatorului void#define then //suprimarea tututor apari#iilor identificatorului then#define begin { //.nlocuirea identificatorului begin cu {#define end } // .nlocuirea identificatorului end cu }#define N 100 //.nlocuie"te identificatorul N cu valoarea 100O dat! f !cut! o substitu#ie lexical!, ea poate fi folosit! ca parte a unei alte substitu#iilexicale. Astfel, av.nd ultimasubstitu#ie lexical! din exemplul precedent, este corect s! scriem:#define NPATRAT N*NUn identificator care a apare deja .ntr-o linie #define poate fi ulterior redefinit ulterior .n program cu o alt! linie#define. Preprocesorul va substitui .n continuare identificatorul cu noua defini#ie a lui.Substituirea nu se face .n cazul .n care identificatorul apare .ntre ghilimele, .n acest caz elnejuc.nd practic rolulunui identificator.Exemplu:

    #define PI 3.14… printf(“valoarea lui PI are un numar infinit de zecimale!\n”);….n acest caz, nu se face expandarea.Macroinstruc#iuniSunt substitu#ii cu parametri formali "i se realizeaz! cu ajutorul directivei:#define identificator(lista_param_formali) textParametri formali sunt .nlocui#i de cei din lista parametrilor reali. Nu trebuie s! existe niciun spa#iu .ntreidentificator "i lista_param_formali.

    Exemple:#define max(a,b) (a)>(b)?(a):(b)

  • 8/18/2019 ipc hatz

    9/61

    #define abs(a) (a)

  • 8/18/2019 ipc hatz

    10/61

    .n momentul .ncare am lansat mediul de programare).10.n loc ca programatorul s! foloseasc! propriile sale declara#ii pentru func#iile de bibliotec!, se recomand! 

    includerea .n cadrul programului surs! a unor fi"iere antet (header), care con#indeclara#iile func#iilor de bibliotec! apelate. Aceste fi"iere au .n general extensia .h "i se g!sesc .n directorul INCLUDE.Fisierele include vor contine doar DECLARATII si nu definitii de func$ii. Declaratiile sidefinitiile pot fi de functiisau variabile globale. Daca un fisier include contine definitii, este dincolo de controlul programatorului ca acestefisiere sa apara incluse de 2 ori intr-un proiect, ceea ce genereaza eroare de linkeditare insensul ca o definitie estegasita (la linkeditare) ca si duplicata.,Includerea fi"ierelor se folose"te pentru gestionarea corect! a unui proiect, .n general de

    mari dimensiuni, care secompune din mai multe module. Pentru .ncorporarea la .nceputul fiec!rui modul de defi"iere de descriere se potcrea:-fi"iere con#in.nd defini#ii generale ale proiectului: declara#ii de tip "i directive ale preprocesorului, .n particulardirective define-fi"iere con#in.nd declara#ii de variabile externe .n cazul .n care definirea lor a fostregrupat! .ntr-un modul special.Programele C mari pot fi structurate pe mai multe fi"iere, care pot fi compilate distinct.Aceasta prezint! mai multeavantaje:-.n cazul erorilor sintactice "i semantice, doar fi"ierul eronat trebuie recompilat, dup! modific!rile sau corec#iileaduse. Programatorul poate profita de faptul c! unitatea de compilare este fi"ierul,repartiz.nd func#iile programului s!u .n mai multe fi"iere. .n acest fel, modificarea unei func#ii va fi urmat! derecompilarea doar afi"ierului care o con#ine "i a fi"ierelor care depind de el, nu a .ntregului program,ob#in.ndu-se astfel un c."tig detimp .nsemnat.-structurarea programelor pe mai multe fi"iere permite simularea mecanismului de.ncapsulare a datelor.

    Variabilele "i func#iile av.nd clasa de memorare static pot fi accesate doar .n cadrulfi"ierului .n care au fostdefinite. Variabilele "i func#iile declarate cu clasa de memorare extern sunt definite .n altfi"ier dec.t cel curent, darele pot fi accesate .n fi"ierul curent.Observa#ie: Dac! se modific! un fi"ier care este inclus printr-o directiv! #include, atuncitoate fi"ierele caredepind de el trebuie recompilate.

    Curs 3 : Introducere in programarea calculatoarelor1

    CURS 3.

  • 8/18/2019 ipc hatz

    11/61

    Constructii de baz!. Tipuri. Instruc#iuni C5.1 Construc$ii de baz! în CCaractereleLa scrierea programelor C se folose"te un subset al setului de caractere al codului

    ASCII. Caracterele dinacest set se codific! .n intervalul [0,127]. Un astfel de .ntreg poate fi p!strat .n binar pe un octet ( 8 bi$i ).Se .mpart .n trei grupe:• caractere grafice .n intervalul (32,127), aici intr.nd literele mari av.nd codul ASCII.n intervalul[65,96], literele mici [97,122], cifrele [48,57] "i caracterele speciale• caractere negrafice (de control); au coduri .n intervalul [0,32) cu excep$iacaracterului Del av.ndcodul ASCII 127.• caracterul spa#iu av.nd codul ASCII 32

    Codul ASCII de valoare 0 define"te caracterul nul; este un caracter impropriu, nu poate fi generat de latastatur ! "i nu are efect .n ie"ire. Este utilizat pentru a determina un %ir arbitrar decaractere deoarece niciun caracter de la intrare nu poate coincide cu el.Codul ASCII 10 deplaseaz! cursorul .n coloana 1 din linia urm!toare. .n C referirea laacest cod se face cucombina#ia ‘Än’.

     Nume (identificatori)Un identificator este o succesiune de litere, cifre si caracterul de subliniere (_) care.ncepe cu o liter ! (mic!,mare) sau cu caracterul de subliniere. Sunt semnificative primele 32 de caractere.Literele mici se consider ! distincte de cele mari.Exemplu: x, a5b9, p_i_c, _cifraContraex: 9a$, a+b, a%w, a_salut!Identificatorii sunt folosi$i pentru a identifica sau denumi func$ii %i variabile.Cuvinte cheieSunt identificatori rezerva#i ai limbajului, av.nd o semnifica#ie bine determinat!.Acestea nu pot fi utilizatedec.t conform sintaxei limbajului. Au fost definite 32 de cuvinte cheie:

    auto double int struct break else long switchcase enum register typedefchar extern return unionconst float short unsignedcontinue for signed voiddefault goto sizeof volatiledo if static whileUnele compilatoare de C mai adaug! la aceste liste .nc! c.teva cuvinte cheie.Curs 3 : Introducere in programarea calculatoarelor25.2. Tipurile de baz! din limbajul C

    Un tip de date reprezint! mul#imea valorilor pe care le pot lua datele de tipulrespectiv, modul de

  • 8/18/2019 ipc hatz

    12/61

    reprezentare a acestora .n memorie precum %i opera$iile care se pot efectua cu datelerespective.Tipurile de baza definite .n limbajul C sunt: .ntreg, real %i caracter. Unele dintre acestetipuri difer ! de la oimplementare la alta a limbajului.

    Un tip de date reprezint!:- modul de reprezentare a datei respective in memoria calculatorului. Astfel, se

     precizeaz! cum seconvertesc bi$ii din memoria calculatorului pentru a produce data reprezentat! devaloare cu tipulrespectiv- dimensiunea pe care o ocup! in memorie o dat! de tipul respectiv- multimea de valori admisibile pentru datele de tipul respectiv..n tabelul urm!tor sunt prezentate tipurile fundamentale, memoria necesar ! stoc!riivalorilor de acel tip %ilimita valorilor ce pot fi memorate .ntr-o variabil! de acel tip.

    Tipul DimensiunememorieLimita valorilorchar 1 byte (octet) -27 … 27-1int depinde deimplementare(uzual 4 bytes)short int 2 bytesunsigned char 1 byte 0..255unsigned int depinde deimplementarelong int 4 bytesunsigned longint4 bytesfloat 4 bytesdouble 8 byteslong double 8 bytesPrimul tip este tipul caracter. O variabil! de acest tip va avea ca valoare codul ASCIIasociat caracteruluirespectiv.

    De exemplu, dac! unei variabile i se atribuie caracterul ’a’, variabila va con$inevaloarea 97 (num!rul deordine al caracterului ‘a’ .n codul ASCII).Curs 3 : Introducere in programarea calculatoarelor3Tipul .ntreg cel mai des utilizat .n programe este int, dar num!rul de bytes pe care sememoreaz! valorilede acest tip difer ! de la o implementare la alta. Num!rul de bytes al unei valori de tipint reprezint! cuvantulcalculatorului respectiv. Astfel, tipul int este echivalent cu short int sau long int, infunctie de

    implementare.Celelalte tipuri intregi sunt ob$inute prin folosirea prefixului signed sau unsigned,

  • 8/18/2019 ipc hatz

    13/61

    indic.nd dac! valorilerespective sunt cu semn (con$in %i valori negative), respectiv f !r ! semn ( valorinaturale).Ultimele trei tipuri din tabel sunt tipuri reale, diferen$a dintre ele const.nd .n cantitateade memorie

    utilizat!, intervalul de valori %i precizia memorarii valorilor (numarul de zecimaleretinute).Valorile reale se reprezint! conform nota$iei din standardul IEEE (folosind semnul,mantisa %i exponentul).De exemplu, pentru tipul float se utilizeaza reprezentarea in simpla precizie, folosindun bit de semn, 7 biti

     pentru exponent si 24 de biti pentru mantisa. Aceasta reprezentare are un exponent inlimita a 10-37 si 1038cu pina la 7 zecimale precizie. Valoarea maxim! a unui float este de 1.701411 E38.Din tabel se observ! ca nu exist! un tip logic, asa cum este el definit .n alte limbaje de

     programare. In

    limbajul C nu s-a definit acest tip dar se folose%te urm!toarea conven$ie: o expresieeste considerat! adevarat! daca valoarea obtinuta la evaluarea ei este nenula si falsa in caz contrar.Variabilele care se vor folosi ca variabile logice vor fi declarate de tip intregO alta caracteristica aparte o constituie introducerea tipului void, pentru a desemna“nimic”. Se maifolose"te la declararea explicit! a func#iilor care nu au parametrii.Pentru a putea utiliza o variabil! .ntr-un program C, este obligatorie declarareaacesteia, astfel:TIP_DE_DATE lista_variabile;unde:• TIP_DE_DATE este orice tip predefinit sau derivat;• lista_variabile con$ine lista variabilelor de acel tip, desp!r $ite prin virgul!;Curs 3 : Introducere in programarea calculatoarelor4Exemple:int a,b,c;char ch;float x,y;long int z;int g=7;

    Observatie: La declararea variabilei intregi g s-a realizat si initializarea acesteia(=stabilirea unei valoriinitiale).Variabilele care sunt declarate in interiorul corpului unei functii se numesc variabilelocale, iar celedeclarate in afara oricarei functii din program se numesc variabile globale. Variabileleglobale vor putea fiutilizate in toate functiile ce compun programul, iar variabilele locale doar .n cadrulfunc$iei .n care au fostdefinite.

    .n cadrul tipurilor derivate avem:o tipuri structurate –tablouri, structuri, uniuni, c.mpuri de bi#i, enumer !ri

  • 8/18/2019 ipc hatz

    14/61

    o tipuri func#ie –caracterizate at.t prin tipul rezultatului furnizat c.t "i prin num!rul "itipulargumentelor necesare pentru ob#inerea rezultatului.o tipuri pointer –permit adres!ri indirecte la entit!#i de diverse tipuriUn tip specific limbajului C este tipul void. Acesta se folose"te la declararea explicit! 

    a func#iilor care nureturneaz! nici o valoare sau a func#iilor care nu au parametri.Tipul de date intValorile acestui tip sunt numere .ntregi, cuprinse .n intervalul [-32767,32767]reprezentate .n memorie pe2 octe$i, .n cod complementar. Tipul de date int suport! modificatorii de tip unsigned (datele sunt numerenormale ) %i long ( modific! dimensiunea reprezent!rii). Se ob$in astfel urm!toareletipuri de date .ntregi:Tip Reprezentare Valoriint 2 octeti cu semn [-32768, 32767]unsigned int 2 octeti fara semn [0, 65.535]long int 4 octeti cu semn [-2.147.483.647, 2.147.483.647]unsigned long int 4 octeti fara semn [0, 4.294.967.295]Atunci c.nd un tip de date nu este precizat implicit este considerat int. Prin urmare

     putem specifica numaimodificatorul long sau unsigned sau unsigned long, tipul fiind implicit int.Constantele .ntregi sunt numere .ntregi din intervalul corespunz!tor tipului. Ele pot fi

     precizate .n baza 10folosind nota$ia uzual!, .n baza 8 constanta fiind precedat! de un 0 nesemnificativ %i.n baza 16 constantaav.nd prefixul 0x sau 0X.Exemple:123-12345678012340x1a00XFFFFFExplicitarea tipului de constant! numeric! se poate face utiliz.nd un sufix. Pentru tipul.ntreg, utilizareasufixului U determin! alocarea tipului unsigned. Analog, folosim sufixul L pentrutratarea unui .ntreg

    ca long. Dac! utiliz!m sufixul F pentru tipul virgul! mobil!, num!rul va fi tratat cafloat iar dac! folosimsufixul L num!rul va fi de tip long double.Curs 3 : Introducere in programarea calculatoarelor5Exemple:100U unsigned-1234L long int123.45F float123456.789 long doubleTipul de date char

    Tipul caracter .n C se reprezint! pe un octet "i are ca valoare codul ASCII alcaracterului respectiv.

  • 8/18/2019 ipc hatz

    15/61

    Constanta caracter grafic se scrie incluz.nd caracterul respectiv .ntre caracterulapostrof.Exemplu: ‘A’

     _ intern vom avea o reprezentare pe un octet ce con#ine valoarea 65 (codul ASCII alliterei A).

    Tip Reprezentare Valorichar 1 octet cu semn [-128, 127]unsigned char 1 octet fara semn [0, 255]Contsantele de tip char ( unsigned char ) pot fi numere .ntregi din intervalul specificatcare au codurileASCII .n intervalul specificat. Valorile de tip char par a avea o natur ! dual!, caractereASCII %i numere.ntregi. Caracterul A %i codul 65 au aceasi semnifica$ie.Caracterele grafice ( coduri ASCII de la 32 la 127 ) se pot specifica .ncadr.ndcaracterul respectiv .ntreapostrofuri.

    Exemplu:‘a’, ‘9’, ‘*’Caracterele negrafice se pot specifica .ncadr.nd .ntre apostrofuri o secven$! de evitare( secven$! escape).Secven$ele escape sunt formate din caracterul Ä ( backslash) urmat de codul ASCII alcaracterului exprimat.n baza 8 sau .n baza 16 precedat de un x.Exemplu:Secven$! escape Caracter‘Ä65’ ‘5’‘Äx35’ ‘5’ (exprimat in baza 16)‘Ä5’ Caracterul ' ‘Ä356’ Caracterul ( Unele caractere negrafice au asociate secvente escape speciale:Secven#a Semnifica#iaÄa allert (bell)Äb backspaceÄf form feedÄn new lineÄr carriage returnÄt horizontal tab

    Äv vertical tabConstantele %ir de caractere sunt constituite dintr-o succesiune de caractere .ncadrat! .ntre ghilimele.Exemple:”Acesta este un %ir””Prima linie Än A doua linie”Curs 3 : Introducere in programarea calculatoarelor6Tipuri realeTipurile reale sunt float %i double. Tipul double accept! %i modificatorul long.Tipul Reprezentare

    float 4 octeti in virgul! mobil! double 8 octeti in virgul! mobil! 

  • 8/18/2019 ipc hatz

    16/61

    long double 10 octeti in virgul! mobil! Un num!r flotant este un num!r ra#ional care se compune din semn (dac! e cazul), o

     parte .ntreag! (care poate fi vid!), o parte frac#ionar ! (care "i ea poate fi vid!) litera e sau E "i un exponent(care "i ele pot lipsi).

     Nu pot fi vide toate componentele. Partea .ntreag! este o succesiune de cifrehexagesimale. Parteafrac#ionar ! se compune dintr-un punct urmat de o succesiune de cifre zecimale,succesiune care poate fivid!.Se reprezint! .n forma uzual! sau %tiin$ific! ca exponent a lui 10, urmat de e.Exemple:-15e-52.e-412.4

    -2.67e-10-2.67E+85.3. InstructiuniInstruc#iunile C implementeaz! structurile de baz! ale program!rii structurate,

     prezentate .n cursul 1 %iidentificabile in schemele logice %i pseudocod astfel:-structura secven#ial! (instruc#iunea compus!) ;-structura alternativ! (instruc#iunea if) ;-structura repetitiv! condi#ionat! anterior (instruc#iunea while) "i condi#ionat! 

     posterior (instruc#iunea

    do while)Toate instruc#iunile limbajului C se termin! cu ‘;’ excep#ie f !c.nd instruc#iunile carese termin! cu }(instruc#iunea compus! "i instruc#iunea switch) dup! care nu se pune ‘;’.Instruc#iunea vid! Instruc$iunea vid! are formatul:;%i este folosit! pentru a .nlocui o instruc$iune care practic nu este, dar contextul(sintaxa) o cere.Una din situa$ii o constituie instruc$iunile de ciclare while %i for a c!ror sintax! impune corp al

    instruc$iunii. Dac! acesta lipse%te, atunci instruc$iunea vid! va $ine loc de corp alinstruc$iunii.Exemplu1. . . . . . .for (i=0;(i+1)*(i+1)

  • 8/18/2019 ipc hatz

    17/61

    locul acestuia se pune instruc$iunea vid! ;.Instruc#iunea compus! Forma general!:{

    declaratii_si_definitii;instructiune1;instructiune2;…instructiune n;}Se folose"te .n situa#iile .n care sintaxa impune o singur ! instruc#iune, dar codificareaimpune prezen#a uneisecven#e de instruc#iuni. Blocul de instruc#iuni conteaz! ca o singur ! instruc#iune.Observa#ii:1. Dup! acolad! .nchis! nu se pune ;.

    2. Corpul unei func#ii are aceea"i structur ! ca "i instruc#iunea compus!.3. O instruc#iune compus! permite folosirea mai multor instruc#iuni acolo undesintaxa cere o instruc#iune,aceasta fiind echivalent! sintactic cu o singur ! instruc#iune.4. instruc$iunea compus! reprezint! un domeniu de vizibilitate. Astfel, declara$iile %idefini$iile dininteriorul unei instruc$iuni compuse au valabilitate doar in interiorul acesteia.Instruc#iunea if.n limbajul C, instruc#iunea condi#ional! de baz! este instruc#iunea if.Forma general!:if (expresie)

    instructiune1;elseinstructiune2;Se evalueaz! expresia; dac! este diferit! de 0 se execut! instruc#iune1 altfelinstruc#iune2O form! simplificat! are instruc#iune2 vid!:if (expresie)instructiune;.n problemele de clasificare se .nt.lnesc decizii de forma:if (expr1)instr1;

    else if (expr2)instr2;…elseinstrn;Exemplu2: dorim s! contoriz!m caracterele citite pe categorii: litere mari, litere mici,cifre, linii "i altele:if (c == ‘Än’)linii++;Curs 3 : Introducere in programarea calculatoarelor8else if (c>=’a’ && c=’A’ && c

  • 8/18/2019 ipc hatz

    18/61

    lmari++;else if (c>=’0’ && c

  • 8/18/2019 ipc hatz

    19/61

    Exemplu5: Programul care num!r ! caracterele unui text. Introducerea se .ncheie cuenter.#include int main (){

    Curs 3 : Introducere in programarea calculatoarelor9int i=0;

     printf("Scrieti un text : Än");while (getch()!='Är') /*se citeste textul fara afisare in consola */i++;

     printf("Numarul de caractere este %dÄn",i);return 0;}Exemplu6: Program care calculeaz! factorialul:#include

    int main(){long n, fact;

     printf("n="); scanf("%ld", &n);fact=1;while (n>1){fact = fact * n;n--;}

     printf("Factorialul este : %ldÄn", fact);}Instruc#iunea do whileInstruc#iunea do while implementeaz! structura repetitiv! condi#ionat! posterior.Forma instructiunii do while este :doinstructiune;while (expresie);Instruc$iunea este asem!n!toare cu instructiunea while cu deosebirea c!, aici, testul seface la sf.r %itul

     buclei. Bucla se va executa cel pu$in o dat!, chiar dac! testul nu este .ndeplinit de la

    .nceput. Instruc$iunease execut! c.t timp expresia este diferit! de 0.Observa#ie: Spre deosebire de instruc#iunea while, .n cazul acestei instruc#iuni, corpulei se execut! cel

     pu#in o dat!, indiferent de valoarea ini#ial! de adev!r a expresiei.Prefer !m s! utiliz!m instruc$iunea while c.nd este necesar s! test!m o condi$ie .naintede efectuarea unor

     prelucr !ri.Prefer !m s! utiliz!m do – while c.nd condi$ia depinde de la .nceput de prelucr !rile dinciclu, prinurmare este necesar s! o test!m dup! executarea intruc$iunii.

    Exemplu8: S! se numere cifrele num!rului natural memorat .n variabila n. Corpul buclei se scrie ca mai

  • 8/18/2019 ipc hatz

    20/61

     jos.#includeint main(){int n, nr;

     printf("introduceti un numar intreg: "); scanf("%d", &n);nr=0;do{n/=10;Curs 3 : Introducere in programarea calculatoarelor10nr++;} while(n);

     printf("numarul de cifre este %dÄn", nr);return 0;

    }Instruc#iunea for.n cazul .n care se cunoa"te num!rul de itera#ii ale unui ciclu repetitiv, se poate u"orutiliza instruc#iuneafor. Formatul general al acestei instruc#iuni este urm!torul:for(exp1;exp2;exp3) instruc#iune;Efectul acestei instruc#iuni este urm!torul: se evalueaz! exp1 dup! care se testeaz! valoarea de adev!r aexp2. Dac! exp2 are valoarea 0, se termin! execu#ia instruc#iunii for, "i se continu! cuurm!toarea

    instruc#iune de dup! instruc#iunea for. Dac! exp2 are valoarea diferit! de 0, se execut! instruc#iune dup! care se evalueaz! exp3. Se revine la evaluarea lui exp2 "i se continu! ciclic p.n! c.ndexp2 va deveni, caz.n care se continu! cu urm!toarea instruc#iune de dup! instruc#iunea for.Instruc#iunea for este echivalent! cu urm!toarea secven#! de instruc#iuni:exp1;while(exp2){instruc#iune;exp3;

    }Observa#ie: Oricare din cele 3 expresii pot s! lipseasc!. De asemenea instruc#iunea poate lipsi. Dac! lipsesctoate cele 3 expresii se ob#ine un ciclu infinit:for(;;) instruc#iune;Exemplu9 :#include int main(){int i;for( i = 1; i

  • 8/18/2019 ipc hatz

    21/61

    return 0;}Exemplu10: S! se scrie programul C care calculeaz! n! unde %tim c! n!=n*(n-1)! iar0!=1.#include

    int main(){int n=6, fact=1, i;for(i=1;i

  • 8/18/2019 ipc hatz

    22/61

    int max(int x, int y){if(x>y) return x;else return y;}

    Instruc#iunea switchPermite realizarea unei structuri selective. Ea este o generalizare a instruc$iunii if care

     poate fi realizata prin structuri alternative imbricate.Aceast! instruc#iune determin! transferul controlului unei instruc#iuni sau unui blocde instruc#iuni .nfunc#ie de valoarea unei expresii "i are urm!torul format general:switch (expresie) {case c1: instr1;[case c2: instr2;]…[default: instr_default;]}Efectul acestei instruc#iuni este urm!torul: se evalueaz! expresia dintre paranteze.Dac! valoarea expresieieste egal! cu ci atunci se execut! instruc#iunea corespunz!toare constantei ci. Dac! valoarea expresiei estediferit! de orice ci indicat, atunci se execut! instruc#iunea corespunz!toare clauzeidefault, dac! exist! aceast! clauz! dup! care se trece la urm!toarea instruc#iune de dup! instruc#iuneaswitch.

    Curs 3 : Introducere in programarea calculatoarelor12Dup! ce se execut! instruc#iunea corespunz!toare unei constante indicate, dac! nuexist! instruc#iunea

     break atunci necondi#ionat se execut! toate instruc#iunile de mai jos celeicorespunz!toare constantei ci,eventual p.n! la prima instruc#iune break .nt.lnit!.Instruc#iunea switch este deseori folosit! pentru a prelucra anumite comenzi de latastatur !, cum ar fiselec#ia unei op#iuni dintr-un meniu.Observa#ii:

    1. Valoarea expresiei dintre paranteze trebuie s! fie de un tip compatibil cu int (char,enum sau oricevariant! de int). Nu se pot utiliza numere reale, "iruri, pointeri sau structuri dar se potfolosi elemente detip compatibil cu int din cadrul "irurilor sau structurilor. Este interzis! apari#ia a dou! constante pentru case.n aceea"i instruc#iune switch cu aceea"i valoare.2. Standardul ANSI C prevede c! instruc#iunea switch poate s! aib! cel pu#in 257 deinstruc#iuni tip case.Exist! posibilitatea de a imbrica mai multe instruc#iuni switch una .n alta, f !r ! s! apar ! conflicte chiar dac! 

    unele constante case dintr-un switch interior "i unul exterior con#in valori comune.Exemplu 20:

  • 8/18/2019 ipc hatz

    23/61

    …switch (luna) {// februariecase 2: zile=28; break;// aprilie, iunie,..., noiembrie

    case 4: case 6: case 9: case 11: zile =30; break;// ianuarie, martie, mai,.. decembriedefault: zile=31; break;}...Instruc#iunea breakInstruc#iunea break este utilizat! pentru ie"irea for #at! dintr-o bucl!, .nainte de sf.r "itulacesteia. .n general,aceste instruc#iuni de ie"ire for #at! se aplic! unor algoritmi nestructura#i. Serecomand! evitarea acestora,

    "tiind fiind faptul c! orice algoritm nestructurat poate fi transformat .ntr-un algoritmstructurat.Dac! este necesar, corpul unei instruc#iuni de ciclare poate s! con#in! mai multeinstruc#iuni break,corespunz!toare mai multor condi#ii de ie"ire for #at!. Bine.n#eles, pot exista "i ie"irinormale din aceste

     bucle, chiar dac! au fost prev!zute mai multe instruc#iuni break.Instruc$iunea permite ie%irea dintr-un singur ciclu, nu %i din eventualele cicluri care arcon$ine instruc$iunearepetitiv! .n care s-a executat instruc$iunea break.Exemplu15:

    #include #define PROMPT ':'int main(){float a, b, result;char oper, eroare;while (putchar(PROMPT),(scanf("%f%c%f",&a, &oper, &b)!=EOF)){eroare=0;switch(oper){case '+': result=a+b; break;case '-': result=a-b; break;case '*': result=a*b; break;

    case '/': if(b)result=a/b;elseCurs 3 : Introducere in programarea calculatoarelor13{

     puts("*** Impartire la 0 ***");eroare=1;}

     break;default : printf("*** Operator ilegal %c ***Än", oper);eroare=1;

    }//switchif(!eroare) printf("rezultatul e %fÄn", result);

  • 8/18/2019 ipc hatz

    24/61

    }//while}//mainExemplu16:char c; int a, b, r;

     printf("Scrieti o operatie intre doi intregi: ");

    if (scanf("%d %c %d", &a, &c, &b) == 3) { /* toate 3 corect */switch (c) {case '+': r = a + b; break; //iese din corpul switchcase '-': r = a - b; break; // idemdefault: c = 'Ä0'; break; // fanion caracter eronatcase 'x': c = '*'; //'x' e tot ?nmultire, continuacase '*': r = a * b; break; //ca si pt. apoi iesecase '/': r = a / b; //la sfarsit nu trebuie break}if (c)

     printf("Rezultatul: %d %c %d = %dÄn", a, c, b, r);

    else printf("Operatie necunoscutaÄn");}else printf("Format eronatÄn");Instruc#iunea continueSe utilizeaz! .n interiorul ciclurilor "i permite saltul la .nceputul secven#ei deinstruc#iuni care formeaz! corpul ciclului respectiv continu.nd cu urm!toarea itera#ie a ciclului, deci nu se

     p!r !se"te bucla. Ea seaseam!n! cu instruc#iunea break, dar .n loc s! for #eze .ncheierea bucl!rii,instruc#iunea continue for #eaz! trecerea la urm!toarea itera#ie a buclei.Pentru bucla for, instruc#iunea continue determin! execu#ia secven#ei de incrementare"i a testului decondi#ionare, iar pentru buclele while "i do-while controlul programului este trecuttestului de condi#ionare.Exemplu17:while (1){scanf("%lf", &x);if (x < 0.0)

     break; //iesim din while cand x este negativ printf("%lfÄn", sqrt(x));}while (contor < n){scanf("%lf", &x);if (x > -0.01 && x < =0.01)continue; //valorile mici nu se iau in considerare++contor;Curs 3 : Introducere in programarea calculatoarelor14

    suma += x;}

  • 8/18/2019 ipc hatz

    25/61

    5.12.Instruc#iunea gotoInstruc#iunea de salt goto permite saltul la o anumit! instruc#iune din cadrul func#iei,instruc#iune precedat! de o etichet!. Formal, instruc#iunea goto nu este necesar ! niciodat!, .n cazul

     program!rii structurate. Nu se

    recomanda utilizarea acestei instructiuni; programarea care utilizeaza salturineconditionate se numeste

     programare in stil “spaghetti”.Formatul instruc#iunii goto este:goto etichet!;unde etichet! este un nume care identific!, sub forma:etichet!: instruc#iune;instruc#iunea cu care se continu! execu#ia programului.Aceea"i etichet! poate fi referit! de mai multe instruc#iuni goto, dar o etichet! nu

     poate identifica dec.t osingur ! instruc#iune. Unicul scop pentru care se define"te o etichet! este de a fireferit! de o instruc#iunegoto.

    Curs 4 : Introducere in programarea calculatoarelor1

    CURS 4.Expresii. Variabile4.1. ExpresiiUn operator este un simbol care indic! compilatorului necesitatea execu#iei uneiopera#ii matematice saulogice.O expresie este compus! dintr-un operator si unul sau doi operanzi. Expresiile seevalueaz! .n func$ie deregula de evaluare a operatorului implicat in expresie. Rezultatul evalu!rii uneiexpresii este o valoare(rezultat al expresiei). In plus, evaluarea expresiei poate s! aib! efect %i asupraoperanzilor, in sensulmodific!rii valorii acestora.In func$ie de tipul operatorilor, ace%tia sunt- Operatori unari – se aplic! asupra unui singur operand

    - Operatori binari – se aplic! asupra a 2 operanzi.Expresiile se evalueaz! fie de la dreapta la st.nga, fie de la st.nga la dreapta, in func$iede operatorulimplicat in expresie.Expresiile pot fi compuse, in sensul in care rezultatul evalu!rii unei expresiireprezint! un operand intr-oexpresie nou!. In acest sens, operatorii sunt evalua$i in func$ie de tabela de preceden$! a operatorilor,descris! mai jos. Expresiile pot con$ine () care schimb! prioritatea de evaluare incadrul expresiilorcompuse, adic! expresia dintre () se evalueaz! prioritar.

    Preceden$! Operator Descriere Asociativitate1

  • 8/18/2019 ipc hatz

    26/61

    ++ -- Incrementare / decrementare form! postfixat! De la st.nga ladreapta() Apel de func$ie[] Referirea unui element dintr-un %ir. Acces la membrii unei structuri sau uniuni

    )> Acces la membrii unei structure sau uniuni prin pointer2++ -- Incrementare / decrementare prefixat! De la dreapta la+ ) Plus / minus unar st.nga! ~ NOT logic %i NOT pe bi$i(type) Conversie de tip* Dereferen$ierea unui pointer& Adresa (unei variabile)sizeof M!rimea (in octe$i a unei variabile / valori)3 * / % Inmul$ire, imp!r $ire, rest De la st.nga ladreapta

    4 + ) Adunare %i sc!dere (operatori binari)5 > Deplasare la st.nga/dreapta pe bi$i6< >=7 == != Operatori rela$ionali pentru egalitate %i diferit8 & AND pe bi$i9 ^ XOR pe bi$i (or exclusiv)10 | OR pe bi$i11 && AND logicCurs 4 : Introducere in programarea calculatoarelor212 || OR logic13 ?:Operatorul ternar condi$ional (singurul operator cu 3operanzi)De la dreapta lastânga14= Operatorul de atribuire simplu+= )= Atribuire cu sum! %i diferen$! 

    *= /= %= Atribuire cu inmul$ire, imp!r $ire %i rest= Atribuire cu opera$ii de deplasare pe bi$i&= ^= |= Atribuire cu opera$ii pe bi$i AND , OR sau XOR15 , Operatorul virgul! De la stânga ladreaptaDescriem mai jos operatorii uzuali utiliza$i in programele noastre.Operatori aritmetici:Operator Semnifica#ie-* / %

    + -Minus unar (semn)

  • 8/18/2019 ipc hatz

    27/61

    .nmul#ire, .mp!r #ire, restul .mp!r #irii întregiAdunare, sc!derePrioritatea operatorilor scade de sus în josOperatorul ‘%’ nu se poate aplica asupra variabilelor de tip float "i double.Operatorul ‘/’ dac! se aplic! la 2 variabile sau constante întregi se va face o .mp!r #ire

    întreag! f !r ! a se luaîn considerare restul!Exemplu:float a=5;a=a + 1/2; //variabila float a va con#ine în continuare valoarea 5.0a=a + 1./2; //în acest caz valoarea variabilei a va fi 5.5Operatori rela#ionali "i logiciOperator Semnifica#ie!> >= < 1+12 _ fals (0)10>8&&!(158 are valoarea deadev!r 1 iar 1&&1conduce spre valoarea de adev!r 1. Evaluarea se opre"te aici deoarece 1||x=1 oricarear fi x. Deci valoareade adev!r a întregii expresii este adev!rat (1).Operatori logici pe bi#iOperator Semnifica#ie

    &|

  • 8/18/2019 ipc hatz

    28/61

    ^~>> 1 (adev!rat "i adev!rat _ adev!rat).Observa#ie: Operatorii rela#ionali "i logici genereaz! întotdeauna un rezultat deadev!rat sau fals (1 sau 0)în timp ce operatorii pe bi#i genereaz! o valoare ce poate fi diferit! de 0 sau 1 înfunc#ie de opera#iile

     prev!zute.Operatorii de decalare mut! to#i bi#ii unei variabile spre stânga sau spre dreapta cu unnum!r de pozi#iispecificat.var>>nr_pozitii decalare la dreapta cu num!rul de pozi#ii specificatvar

  • 8/18/2019 ipc hatz

    29/61

    unsigned int n=5,p=1;n|=1

  • 8/18/2019 ipc hatz

    30/61

    op= unde opeste un operator care face parte din mul#imea { %, /, *, -, +, &, |, ^, }. Folosindaceast! construc#ie

     putem ob#ine programe C mai scurte, prin comprimarea instruc#iunilor de atribuire.Astfel expresia de

    atribuire:v=v op expresie este echivalent! cu v op = expresie.Construc#ie cu operator = Exemplu Forma echivalent! = v=10 v=10;+= v+=2 v=v+2-= v-=a v=v-a*= v*=5 v=v*5/= v/=3 v=v/3%= v%=2 v=v%2&= v&=b v=v&b|= v|=b v=v|b

    ^= v^=a v=v^apozOperatorii de incrementare / decrementare ++ / --Operatorii de incrementare/decrementare pot s! apar ! în form! prefixat! sau

     postfixat!. În forma prefixat!  putem avea ++v sau --v iar în forma postfixat! putem avea v++ sau v--.Operatorul postfixat (v++) presupune ca expresia s! fie evaluat! la valoarea (lui v)dinainte de incrementareiar apoi s! se realizeze incrementarea operandului.

    Operatorul prefixat (de exemplu ++v) presupune ca mai intâi s! se realizezeincrementarea lui v iar apoivaloarea incrementat! se returneaz! ca %i valoare a expresiei.Astfel, instruc#iunea a=++v este echivalent! cu secven#a:v=v+1 (mai intai se face incrementarea)a=vInstruc#iunea a=v++ este echivalent! cu secven#a:a=v (prima data se face evaluarea expresiei si abia apoi incrementarea)v=v+1.Exemplu:int a,v=0;

    a=++v; //dup! executarea instruc#iunii v=1 "i a=1a=v++; //a=1 "i v=2a=v--; //a=2 "i v=1a=--v; //a=1 "i v=0;Codul obiect produs de majoritatea compilatoarelor C este mai eficient în cazulutiliz!rii operatorilor deincrementare/decrementare decât cel ob#inut prin utilizarea instruc#iunii de atribuireechivalente.Curs 4 : Introducere in programarea calculatoarelor6Operatorul de conversie explicit! (cast)

    Operatorul de conversie explicit! este un operator prefixat care se utilizeaz! înconstruc#ii de forma:

  • 8/18/2019 ipc hatz

    31/61

    (tip) operandDe multe ori, este necesar ! for #area tipului unui operand sau al unei expresii. Prinaceasta, tipuloperandului ("i implicit valoarea lui) se converte"te spre tipul indicat între paranteze.Conversiile explicite

    sunt utile în cazurile în care se dore"te ca rezultatul unei opera#ii s! fie de alt tip decâtcel determinatimplicit, pe baza tipurilor operanzilor.Exemplu: Dac! se dore"te ob#inerea rezultatului real, netrunchiat, al .mp!r #irii a 2numere întregi, cel pu#inunul dintre operanzi trebuie convertit explicit la tipul double.int a=10, b=4;double c;c=a/b; //de"i c este de tip double, el va con#ine valoarea 2c=(float)a/b //în acest caz c va con#ine valoarea 2.5Operatorul dimensiune (sizeof)

    Operatorul dimensiune returneaz! num!rul de octe#i ai reprezent!rii interne a uneidate. Acestoperator prelucreaz! tipuri, spre deosebire de ceilal#i operatori care prelucreaz! valori.Operatoruldimensiune se utilizeaz! în construc#ii de forma:sizeof(data)unde data poate s! fie variabil! simpl!, nume de tablou, tip, element de tablou sauelement destructur !.Deoarece tipul operanzilor este determinat înc! din faza de compilare, sizeof este unoperator cuefect la compilare, adic! operandul asupra c!ruia se aplic! sizeof nu este evaluat,chiar dac! este reprezentatde o expresie.Operatorul condi#ionalOperatorul condi#ional se utilizeaz! în expresii de forma: exp1?exp2:exp3;Aceast! construc#ie are urm!torul efect: Se evalueaz! valoarea expresiei exp1. Dac! ea are valoareaadev!rat, atunci se evalueaz! exp2, valoarea acesteia fiind "i valoarea întregiiexpresii. Dac! exp1 arevaloarea fals, atunci se evalueaz! exp3 iar valoarea lui exp3 va fi "i valoarea întregii

    expresii.Exemplu:int a=5, b=3,c;c=a>b?b:a;Se evalueaz! a>b , adev!rat deci c=3.Construc#ia de mai sus este echivalent! cu a scrie:if(a>b) c=b;else c=a;Exemple:S! se scrie programul C care comparând valorile a 2 variabile o afi"eaz! pe cea maimare.

    Curs 4 : Introducere in programarea calculatoarelor7

  • 8/18/2019 ipc hatz

    32/61

    #includeint main(){ int a=7,b=3;

     printf(“maxim=%dÄn”,a>b?a:b);}

    S! se scrie programul C care comparând valorile a 3 variabile o afi"eaz! pe cea maimare.#includeint main(){int a=7,b=3,c=9;

     printf(“maxim=%dÄn”,a>b?(a>c?a:c):(b>c?b:c));}Operatorul virgul! Se utilizeaz! când se dore"te evaluarea mai multor expresii, acestea fiind evaluate dela stânga la

    dreapta, întreaga expresie luând valoarea ultimei evalu!ri.Operatorul virgul! se folose"te în expresii de forma:expr1, expr2, … exprnObserva#ie: Putem utiliza operatorul virgul! pentru a putea permite o serie deinstruc#iuni de atribuire,sc! pând astfel de necesitatea unei instruc#iuni compuse acolo unde instruc#iunilesolicit! acest lucru.Întreaga expresie care cuprinde mai multe instruc#iuni de atribuire este considerat! osingur ! instruc#iune.4.2. Regula conversiilor implicite

    O expresie poate con#ine operanzi de tipuri diferite. În aceste cazuri, C aplic! unsistem de conversiidenumit promovarea tipului. Astfel se aplic! urm!toarele reguli:

     _ Oricare operand de tipul char sau short va fi convertit în int. De asemenea fiecarefloat este extinsspre double prin introducere de zeroruri în partea sa frac#ionar !. Când un double esteconvertit sprefloat, de exemplu printr-o asignare, double-ul este rotunjit înainte de trunchiere pelungimea unuifloat.

     _ Dac! unul dintre operanzi este de tipul double, atunci "i cel!lalt se converte"te spre

    tipul double "irezultatul va fi de tipul double. _ Dac! un operand este long, cel!lalt este convertit în long "i acesta va fi tipulrezultatului. Dac! unoperand este unsigned, cel!lalt este convertit în unsigned "i acesta va fi tipulrezultatului.4.3.VariabilePentru tratarea corect! a entit!#ilor identificabile prin nume simbolice (variabile,func#ii, constantesimbolice), tipul lor trebuie precizat anterior primei utiliz!ri printr-o declara#ie saudefini#ie

    corespunz!toare. În C toate variabilele trebuie declarate înainte de a fi folosite.Exemple:

  • 8/18/2019 ipc hatz

    33/61

    char a,b,c;int d;double d;float f;Curs 4 : Introducere in programarea calculatoarelor

    8Variabilele se pot defini în 3 locuri:• în interiorul func#iilor ( locale) ;• în cadrul defini#iei parametrilor func#iilor ( parametri formali) ;• înafara oric!rei func#ii (globale).În consecin#!, vorbim de variabile locale, parametri formali "i variabile globale.Variabilele locale (denumite "i automatice) sunt accesibile doar instruc#iunilor care seg!sesc în interiorul

     blocului în care au fost declarate.În C, obligatoriu toate variabilele locale trebui definite la începutul blocului în caresunt definite, înainte

    de orice instruc#iune a programului.Exemplu:void functie(){ int a;a=1;int b; //incorect în C

     b=2;}Dac! o func#ie urmeaz! s! foloseasc! argumente, ea trebuie s! declare variabilele pecare le accept! cavalori ale argumentelor. Aceste variabile sunt denumite parametri formali ai func#iei.

    Parametri formali pot fi utiliza#i ca variabilele locale obi"nuite. La ie"irea din func#ie, acestea suntdistruse la rândul lor.Exemplu: S! se scrie un program C care calculeaz! 3! "i n!, unde n se cite"te de latastatur !.#includeint factorial(int n) //n este parametru formal "i este declarat de tip .ntreg{ int i,fact=1;for(i=2;i

  • 8/18/2019 ipc hatz

    34/61

    int fact=1; //se defineste variabila global! fact de tip .ntreg "i se da val 1void factorial(int n){ int i;fact=1;for(i=2;i

  • 8/18/2019 ipc hatz

    35/61

     programului. Pentru ca o variabil! global! s! poat! fi utilizat! (de exemplu intr-un altfisier decât in celunde a fost definit!) se utilizeaz! cuvântul cheie extern inainte de defini$ie.Defini#ia unei variabile poate fi completat! prin specificarea unei valori ini#iale %iatunci se spune c! am

    initia$izat variabila respectiv!.Momentul efectu!rii ini#ializ!rii precum "i eventualele ini#ializ!ri implicite suntcondi#ionate de clasa dememorare în care este inclus! variabila respectiv!.

     _ Variabilele alocate in zona global! de date a programului se ini#ializeaz! o singur ! dat!, înainteaînceperii execu#iei programului, cu valoarea declarat!, sau, în absen#a acesteia cuvaloarea implicit! zero.

     _ Variabilele din clasa automatic (locale func#iilor) sunt ini#ializate numai dac! s-acerut explicit,

    ini#ializarea fiind reluat! la fiecare apel al func#iei în care au fost definite.Variabilele automatice sunt locale fiec!rei apel!ri a unui bloc sau unei func#ii "i suntdeclasate (î"i pierddeclara#ia) la ie"irea din blocul respectiv.Curs 4 : Introducere in programarea calculatoarelor10Dac! nu sunt ini#ializate, aceste variabile con#in valori reziduale. Nici o func#ie nu areacces la variabileledin alt! func#ie. În func#ii diferite, pot exista variabile locale f !r ! ca acestea s! aib! vreo leg!tur ! între ele.În absen#a ini#ializ!rii explicite, variabilele globale sunt ini#ializate implicit cuvaloarea 0 în timp cevariabilele locale au valori ini#iale nedefinite (reziduale).O caracteristic! a limbajului C este c! o declara#ie se poate referi la tipuri diferite,derivate din acela"i tipde baz!. Astfel, declara#ia:char c, *p, sir[10];se refer ! la trei variabile de tipuri diferite: caracterul c, pointerul la caracter p "i "irulde caractere sir pentrucare se rezerv! 10 octe#i.4.4. Comentarii

    Un comentariu începe cu succesiunea de caractere /* "i se termin! */ în cadrulcomentariului neavând voies! apar ! aceste construc#ii (deci comentariile nu pot fi imbricate). Comentariile pot fi

     plasate oriunde în program, atât timp cât ele nu apar în mijlocul unui cuvânt cheie sau identificator.ÎSe poate introduce un comentariu linie folosind succesiunea de caractere ‘//’.Datorit! simplit!#ii celei dea doua forme, în exemplele prezentate am folosit comentarii linie, cu men#iunea c! acestea sunt specificelimbajului C++.Exemple:/* Acesta esteun comentariu in C*/

  • 8/18/2019 ipc hatz

    36/61

    int tablou[10][10]; //acesta e un comentariu linie C++; se declar ! un tablou//bidimensional

    1

    CURS 5

    Tipuri structurate de date. Tipul enumerare.5.1. StructuriFrecvent, în practic!, se dore%te prelucrarea unor informa$ii structurate, compuse din maimulte valori primitive.O structur ! este o colec#ie de valori eterogene stocat! într-o zon! de memorie compact!.O structur ! este compus! din una sau mai multe elemente, numite câmpuri, în care fiecare câmp are propriul s!unume "i tip. Memoriaalocat! unei structuri este o secven#! continu! de loca#ii, câte o loca#ie pentru fiecarecâmp. Câmpurile sunt numite"i membri ai structurii sau elemente ale structurii. Ordinea de memorare a câmpurilor

    corespunde cu ordinea dedescriere a acestora în cadrul structurii.Structurile permit organizarea datelor complexe, permi#.nd ca un grup de variabile legates! fie tratate ca o singur ! entitate. O structur ! are urm!torul format general:struct nume_structura {tip1 camp1;tip2 camp2;...tipN campN;} variabila1, ..., variabilaN;

    Observa#ii:1. O declara#ie de structur ! se termin! cu ‘;’, deoarece reprezint! defini$ia unor variabile.2. O declara#ie de structur ! neurmat! de o list! de variabile define"te doar un tip structur !,un "ablon pe bazac!ruia se pot declara variabile de tipul structurii astfel definite.Exemplu1:struct punct {int x;int y;} p;int main ()

    {struct punct alt_punct; printf ("Introduceti cele doua coordonate: ");scanf ("%d %d", &p.x, &p.y); p.x = p.x + 21; p.y = p.y + 10;//între structuri se pot face atribuiri, se copiaza TOATE câmpurilealt_punct = p ; printf ("Coordonatele sunt: (%d %d) \n", alt_punct.x, alt_punct.y);return 0;}2Exemplul anterior declar ! o structura numit! punct, alc!tuit! din dou! c.mpuri: x si y, precum %i variabila p de

  • 8/18/2019 ipc hatz

    37/61

    acest tip. Orice variabil! de tip struct punct va putea memora coordonatele plane ale unui punct (exemplu variabilaalt_punct). Membrii unei variabile structurate se acceseaza cu operatorul .(punct).

     p.x = p.x + 21; p.y = p.y + 10;

    Exemplu2:struct data_calendaristica { //definim structura cu numele data_calendaristicaint zi;int luna;int an;int secol;int mileniu;} d; //variabila d va fi de tip structura data_calendaristicastruct data_calendaristica data_angajarii, data_nasterii;//definim variabilele data_angajarii, data_nasterii de tip// structura data_calendaristica Numele complet al unui câmp se ob#ine din numele structurii urmat de caracterul “.”(denumit operatorul punct)"i numele câmpului referit. Astfel pentru a referi câmpurile din structur ! (numite "ielemente sau membrii aistructurii) vom folosi d.zi, d.luna "i d.an. Câmpul selectat se comport! ca o variabil! "i ise pot aplica toateopera#iile care se pot aplica variabilelor de acel tip.Un membru al unei structuri poate avea acela"i nume cu o structur ! sau cu o variabil! oarecare, nemembru,deoarece nu se vor genera conflicte datorit! faptului c! numele de structuri se afl! într-unspa#iu de memorieseparat de cel al numelor de variabile iar referirea unui membru al unei structuri respectiv

    referirea unei variabilese face diferit în cadrul unui program.Exemplu tipic de structur ! este înregistrarea unui salariat. Aceasta poate con#ine atribute precum marcasalariatului, numele, prenumele, adresa, salarul brut, data na"terii, locul na"terii, dataangaj!rii etc. Se observ! c! structurile pot fi imbricate, adic! membrii unei structuri pot fi la rândul lor structuri (estecazul datei angaj!rii saual datei na"terii, care sunt la rândul lor structuri):struct angajat {int id;

    char nume[25];char prenume[25];struct data_calendaristica data_nasterii;struct data_calendaristica data_angajarii;…} ang;Referirea în acest caz se face sub forma ang.data_nasterii.zi sau pentru un alt membruang.data_angajarii.an.Standardul ANSI C specific! faptul c! structurile trebuie s! permit! imbricarea pe celmult 15 niveluri.Atunci când o structur ! este folosit! ca argument al unei func#ii, întreaga structur ! este

    transmis! folosind metodastandard de apelare prin valoare. Aceasta înseamn! c! orice modificare a con#inutului

  • 8/18/2019 ipc hatz

    38/61

    structurii în interiorulfunc#iei c!reia i se transmite ca parametru nu afecteaz! structura utilizat! ca argument.Dac! se dore"te adresa3unui membru individual al unei structuri, se folose"te operatorul ‘&’ înaintea numelui

    structurii. Operatorul ‘&’ precede numele structurii, nu pe cel al membrului individual.Exemplu:functie(&ang.id, ang.nume); //în cazul numelui nu este necesar ! utilizarea//operatorului ’&’ având în vedere c! nume este deja o adres! Se poate ca informa#ia con#inut! într-o structur ! s! fie atribuit! unei alte structuri deacela"i tip folosind o singur ! instruc#iune de atribuire (deci nu trebuie atribuit! valoarea fiec!rui membru separat).Exemplu:struct angajat ang1, ang2; //definim variabilele ang1 "i ang2 de tipul struct angajatang2=ang1; //atribuim valorile câmpurilor variabilei ang1 câmpurilor

    //corespondente din variabila ang2Se pot defini masive de structuri.struct angajat salariati[300]; //definim un masiv de 300 elemente, fiecare elementfiind de tip structur ! Referirea unui element din acest masiv se face astfel:int ln;ln=salariati[5].data_nasterii.luna; //variabila ln va con#ine câmpul//data_nasterii.luna din al 6-lea element al structurii5.2 Asignari de nume pentru tipuri de dateTipurile de baza ale limbajului C, numite si tipuri predefinite se identifica printrun cuvantcheie ( int, char,float). Tipurile structurate se definesc printr-o declaratie struct nume {};Programatorul poate sa atribuie un nume unui tip, indiferent de faptul ca acesta este predefinit sau definit deutilizator. Aceasta se realizeaza prin intermediul constructiei typedef care are urmatorulformattypedef definitie_tip identificator;Dupa ce s-a atribuit un nume unui tip, numele rspectiv poate fi utilizat pentru a declaradate de acel tip, exact lafel cum se utilizeaza in declaratii cuvintele cheie int, char, float, etc.Exemple:1. Definitia: typedef unsigned short USHORT;atribuie numele USHORT definitiei de tip unsigned short.

    Deasemenea, daca dorim sa lucram cu siruri de lungime 40 sub numele str40 folosimdefinitia:typedef char str40[41];In contextul acestei definitii declaratiastr40 a,b;4defineste doua stringuri de lungime 41 de caractere. Astfel instructiunea printf("Änsizeof(a) = %dÄn",sizeof(a));va tipari urmatoarelesizeof(a) = 412. Declaratiile

    typedef int INTREG;typedef float REAL;

  • 8/18/2019 ipc hatz

    39/61

     pot fi folosite ca si cuvintele cheie int si float. Astfel declaratia:INTREG x,y,a[100];este identica cu int x,y,a[100];typedef struct data_calend { int zi;char luna[11];int an;

    } Dc;Prin aceasta declaratie se atribuie denumirea DC tipului structurat data_calend. Incontinuare putemdeclara date de tip DC:DC data_angajarii, data_nasterii;DC data_crt={20,”septembrie”,1991};6.3.UniuniO uniune este o loca$ie de memorie care este partajat! de dou! sau mai multe variabile, îngeneral, de tipuridiferite. Sintaxa declaratiei unei uniuni este similara cu cea a structurii:union nume_generic {

    tip nume_variabil!;tip nume_variabil!;…} variabile_uniune;unde identificatorii declara$i ca membrii reprezint! nume cu care sunt referite obiectele detipuri diferite careutilizeaz! în comun zona de memorie.Spa$iul de memorie alocat corespunde tipului de dimensiune maxim!. De exemplu, însecven$a:Tipurile uniune ofer ! posibilitatea unor conversii interesante, deoarece aceeasi zona dememorie poate con$ineinforma$ii organizate în moduri diferite, corespunz!toare tipurilor membrilor.Exemplu:union exemplu_uniune {int i;char ch;};union exemplu_uniune eu; //declar !m variabila eu de tipul uniune definit mai sus5Când este declarat! o variabil! de tip uniune, compilatorul aloc! automat memoriesuficient! pentru a p!stra celmai mare membru al acesteia. Eviden#a dimensiunilor "i a aliniamentului o va #inecompilatorul.

    În variabila eu atât întregul i cât "i caracterul ch împart aceea"i loca#ie de memorie, încare i ocup! 2 octe#i iar chdoar unul. Ne putem referi la datele stocate în variabila uniune definit! atât ca la uncaracter, cât "i ca la un întreg,din orice parte a programului. Sintactic, membri unei uniuni sunt accesibili princonstruc#ii de forma:nume_uniune.membru sau pointer_la_uniune->membru.Exemplu:eu.i=10;eu.ch=’a’;M!rimea unei structuri sau a unei uniuni poate fi egal! sau mai mare decât suma

    m!rimilor membrilor s!i. Deaceea, când este necesar ! cunoa"terea m!rimii unei structuri sau uniuni, se va folosi

  • 8/18/2019 ipc hatz

    40/61

    operatorul sizeof.Uniunile pot ap!rea în structuri "i masive "i invers. Sintaxa pentru a apela un membru alunor astfel de structuriimbricate este aceea"i (deci se folose"te operatorul “.” sau “-> “ în cazul în care referirease face folosind un

     pointer).Observa#ie: Este ilegal a declara o structur ! sau o uniune care face apel la ea .ns!"i, dar ostructur ! sau uniune poate con#ine un pointer la un apel spre ea .ns!"i.6.4. C.mpuri de bi#iLimbajul C ofera posibilitatea de a structura datele la nivel de bit. Astfel, unor membri destructuri sau uniuni,li se pot aloca, dintr-un octet, bi$i individuali sau grupuri de bi$i. In felul acesta, sedefinesc câmpuri de bi$i care pot fi accesate fiecare, separate de restul octetului, pentru evaluare %i/sau modificare.Forma general! de definire a unei structuri cu membri de tip câmp de bi$i este:

    struct nume_generic {tip nume1:lungime;tip nume2: lungime;…tip numen: lungime;} lista_variabile;Pentru campurile de bi$i exist! urm!toarele restric$ii:- tipul poate fi int, signed sau unsigned;- lungime este o constant! întreag! cu valori între 0 %i 15;- nu se poate evalua adresa unui camp de biti;- nu se pot organiza tablouri de campuri de biti;- nu se poate %tii cum sunt rulate câmpurile (de la dreapta la stânga sau invers, func$ie deechipament).Câmpurile de biti pot fi utile atunci cand informatia furnizata de anumite echipamenteeste transmisa prin octetsau atunci cand se doreste accesul la bitii unui octet sau atunci cand memoria este limitatasi anumite informatiii pot fi stocate intr-un singur octet.6C.mpurile de bi#i permit accesul la nivel de bit pentru elementele acestui tip de structur !.Deoarece în C nu exist! tipul boolean, astfel se pot stoca mai multe variabile booleene (adev!rat sau fals, 1 sau 0)utilizând un singur octet.

    De fapt, un câmp de bi#i este un tip special de structur !, care precizeaz! cât de lungtrebuie s! fie fiecare câmp,lungime exprimat! în bi#i.Exemplu:struct angajat {struct date_pers datep;float salar;unsigned activ:1;unsigned orar:1;} ang;Se observ! c! este corect s! amestec!m membri obi"nui#i ai unei structuri cu câmpuri de

     bi#i. Astfel, vom definio înregistrare care în loc s! utilizeze 2 octe#i pentru a p!stra informa#iile activ (angajat

  • 8/18/2019 ipc hatz

    41/61

    activ sau inactiv) "i orar(retribu#ie lunar ! sau orar !) va folosi doar 2 bi#i pentru re#inerea celor 2 informa#ii.Rezult! de aici o economie dememorie de 14 bi#i (pentru acest caz) pentru fiecare element de structur ! de acest tip. Nu este obligatorie numirea fiec!rui element dintr-o structur ! de tip câmp de bi#i. Dac! 

    dorim utilizarea doar aultimilor 2 bi#i dintr-un octet, putem defini câmpul de biti astfel:struct cb {unsigned: 6;unsigned bit7: 1;unsigned bit8: 1;} Nu se poate ob#ine adresa unui câmp de bi#i, deoarece nu se "tie dac! aceste câmpuri vorfi rulate de la dreaptaspre stânga sau invers, depinzând de compilator.6.5. Enumer !ri

    O enumerare este un set de constante care specific! toate valorile permise pe care le poateavea o variabil! deacel tip. Permite utilizatorului s! foloseasc! în program nume sugestive în locul unorvalori numerice. De exempluîn locul num!rului unei luni calendaristice se poate folosi denumirea ei sau în loc de 0 %i 1se poate folosiADEV+RAT sau FALS.Formatul general de declarare a unei enumer !ri este:enum nume_generic {lista enumer !rilor} lista_variabile_enumerare; – constantele pot avea specificate valori (%i o valoare se poate repeta)enum luni_curs {ian=1, feb, mar, apr, mai, iun, oct=10, nov, dec}; – implicit, %irul valorilor e cresc!tor cu pasul 1, iar prima valoare e 0 – un nume de constant! nu poate fi folosit în mai multe enumer !ri – tipurile enumerare sunt tipuri întregi, variabilele enumerare se pot folosi la fel cavariabilele întregi – cod mai lizibil decât prin declararea separat! de constante7enum {D, L, Ma, Mc, J, V, S} zi; // tip anonim; declar ! doar variabil! zi// tipul nu are nume , nu mai putem declara altundeva variabileleint nr_ore_lucru[7]; // num!r de ore pe zifor (zi = L; zi

  • 8/18/2019 ipc hatz

    42/61

    culoare semafor;semafor=galben;......switch(semafor){case verde:libera_trecere();break;

    case galben: asteapta();break;case rosu: oprire_motor();break;default: semafor_inactiv()}Exemplu2:#include enum culori {ROSU, GALBEN, VERDE, ALBASTRU, VIOLET, NUMAR_CULORI};typedef enum culori TCuloare;int main (){TCuloare cer, padure;

     printf("In enum sunt %d culoriÄn",NUMAR_CULORI);cer=ALBASTRU; padure=VERDE; printf("cer=%dÄn",(int)cer); printf("padure=%dÄn",(int)padure);return 0;8}In mod natural, diferitele tipuri definite de utilizator pot fi combinate, astfel încât putemavea de exemplu tablouride structuri sau invers, tablouri ale caror elemente sunt enumer !ri. Pentru a evitadeclara$ii de genul structnode x,y,z sau enum boolean s,b; limbajul C furnizeaz! mecanismul de definire a numeluide tipuri cuajutorul lui typedef. Acesta creeaz! tipuri sinonime cu cele denumite %i care pot fiutilizate în declara$ii devariabile, m!rind claritatea programului. Este sugestiv! definirea în programul anterior atipului TCuloare %iutilizarea lui în programul principal în locul tipului enum culori.

    1

    Curs 6. POINTERIUn pointer este o variabil! care con$ine o adres! de memorie.Pointerii sunt foarte mult utiliza$i în C pe de o parte pentru c! uneori sunt singura cale derezolvare a unei anumite probleme, iar pe de alt! parte pentru c! folosirea lor duce la alc!tuirea unui cod maicompact %i mai eficient.Ca metod!, pointerii se utilizeaz! pentru un plus de simplitate.6.1. Pointeri %i adreseUn pointer fiind o variabil! ce con$ine o adres! de memorie, in particular, ea poate referiadresa unei variabile din program.Deci este posibil! adresarea acestei variabile "indirect" prin intermediul pointerului.Variabilele de tip pointer se declar ! prin construc#ii de forma:tip *nume;Fie x o variabil!, de tipint %i px este un pointer la acea variabil!.Operatorul & d! adresa unei variabile, astfel încât instruc#iunea :

  • 8/18/2019 ipc hatz

    43/61

     px=&xd! variabilei px adresa lui x, px înseamn! "pointeaz! pe x". Operatorul & poate fi aplicatnumai variabilelor %i elementelorunui tablou.Invers, dac! avem un pointer px, prin *px se face referire la valoarea care se g!seste

    memorat! la adresa pointat! de px.Exemple.int *p, n=5, m; //declar !m p ca pointer la întreg "i n "i m întregi p=&n; //p va con#ine adresa variabilei n deci p va pointa (indica) spre nm=*p; //lui m i se d! valoarea care se g!se"te la adresa indicat! de p//deci m va con#ine valoarea lui n; în consecin#! m=5m=*p+1; //m va con#ine valoarea 6Construc$ii ca &(x+1) %i &3 sunt interzise. Este de asemenea interzis! p!strarea adreseiunei variabile registru.Operatorul unar * trateaz! operandul s!u ca o adres!, acceseaz! aceast! adres! %i îi ob$inecon$inutul.

    Astfel, dac! y este tot un inty = *pxasigneaz! lui y, ori de câte ori este cazul, con$inutul loca$iei unde pointeaz! px.Astfel secven$a px = &x;y = *px;asigneaz! lui y aceia"i valoare ca %iy = xTotodat! este necesar ! declararea variabilelor care apar în secven$a:int x, y;int *px;2Declararea lui x %i y este deja cunoscut!. *px este un int, adic! în momentul în care pxapare în context sub forma *px,este echivalent! cu a întâlni o variabil! de tip int. De fapt, sintaxa declararii unei variabileimit! sintaxa expresiilor în carear putea s! apar ! respectiva variabil!. Acest ra$ionament este util în toate cazurile careimplic! declara#ii complicate.Exemple:double atof(), *dp; //atof() %i *dp au valoare de tip double.De notat declara$ia implicit!, ceea ce vrea s! însemne c! un pointer este constrâns s!  pointeze o anumit! categorie deobiecte (func$ie de tipul obiectului pointat).

    Pointerii pot apare în expresii.De exemplu, dac! px pointeaz! pe întregul x atunci *px poate apare în orice context încare ar putea apare x.y = *px + 1d! lui y o valoare egal! cu x plus 1. printf("%d\n", *px)imprim! o valoare curent! a lui x %i d = sqrt((double) *px)face ca d = radical din x, careeste for $at de tipuldouble înainte de a fi transmis lui sqrt.În expresii cay = *px + 1

    operatorii unari * %i & au prioritate mai mare decât cei aritmetici, astfel aceast! expresie,ori de câte ori pointerul px

  • 8/18/2019 ipc hatz

    44/61

    avanseaz!, adun! 1 %i asigneaz! valoarea lui y.Referiri prin pointer pot apare %i în partea stâng! a asign!rilor. Daca px pointeaz! pe xatunci*px = 0îl pune pe x pe zero %i

    *px += 1îl incrementeaz! pe x, ca %i(*px)++In acest ultim exemplu parantezele sunt necesare; f !r ! ele, expresia va incrementa pe pxîn loc s! incrementeze ceea ce pointeaz! px deoarece operatorii unari * %i + sunt evalua$i de la dreapta la stânga.Dac! pointerii sunt variabile, ei pot fi manipula$i ca orice alt! variabil!. Daca py este unalt pointer pe int, atunci py = pxcopiaz! con$inutul lui px în py f !când astfel ca py s! se modifice odat! cu px.O mare aten#ie trebuie acordat! tipului variabilei spre care pointeaz! un pointer.

    Urm!torul exemplu este sugestiv în acestsens:int *p;double x=1.23, y; p=&x;y=*p; //valoarea lui y va fi total eronat! datorit! tipului pointerului p//p este pointer spre întreg; *p va lua din x doar primii 4 octeti si apoi ii va converti la int// valoarea *p va fi convertita la double si salvata in y//atentie : nu rezulta eroare de compilare, se da doar un warning36.2. Aritmetica adreselorPentru salvarea datelor, un program scris în C poate folosi 3 tipuri de memorie – care partajaz! o zon! comun! %i anumezona de date a programului. Astfel, zona de date se imparte in urm !toarele: memoriastatic!, stiva %i memoria dinamic! (heap).Codul aferent func$iilor care sunt necesare pentru execu$ia programului (func$ia main precum si toate celelalte func$ii caresunt apelate în program) este salvat într-o alt! zon! de memorie denumit! zona de cod.Zona de date împreun! cu zona de cod reprezint! spa$iul de memorie alocat de sistemulde operare pentru execu$ia unui program.In cele ce urmeaz!, ne vom referi la zona de date. Pointerii obisnui $i din program refer ! 

    adrese din aceast! zon!.1. Memoria global! sau statica g!zduie%te variabile definite globale sau variabileledefinite cu static (în fi%iere, func$ii...).Caracteristica esen$ial! a acestei zone este c! ea este alocat! %i ini$ializat! de compilatorînainte ca execu$ia programuluis! intre în func$ia main, %i exist! pân! dup! ce aceast! func$ie principal! se încheie.M!rimea zonei globale este determinatela compilare si este dat! de m!rimea variabilelor globale %i statice din program. M!rimeaacestei zone este fix!, pe toat! durata execu$iei programului. Dac! nu se specific altfel, toate variabilele din zona global! sunt initializate cu valoarea 0.

    2. Stiva este o zon! de memorie unde compilatorul aloc! spa$ii conform principiului stivei(LIFO). Aceste spa$ii sunt

  • 8/18/2019 ipc hatz

    45/61

    legate strict de func$ii, de variabilele definite în cadrul func$iilor. În aceast! zon! sedefinesc de c!tre compilator variabilelelocale (func$iilor sau domeniilor de vizibilitate) Aici intr ! parametrii cu care func$ia esteapelat! %i variabilele localeobi%nuite - NU %i cele precedate de static. Deci, func$ia main are zona de stiva A, la

    intrare în func$ie. Dac! în main exist! un apel la func$ia f(), la apelul acesteia, în stiv! se adaug! zona B care con$ine variabileledefinite în f. O zon! pe stiv! exist! cât timp execu$ia se afl! în respectiva func$ie sau în func$ii apelate mai departe dinaceasta. Odat! ce func$iareturneaz!, zona aferent! de stiv! este dezalocat!, %i zona de stiv! curent! va fi ceaaferent! a func$iei apelante.3. În memoria dinamic! sau heap aloc!m variabilele dinamic, adic! în timpul rul!rii programului (cu func$ia malloc).Aceast! zon! de memorie st! la dispozi$ia programului, care face aloc!ri în func$ie decele petrecute în timpul execu$iei.

    Pe parcursul execu$iei programului, zona de stiv! respectiv heap cre%te si descre%te, dup! cum programul intr ! sau iese dinfunc$ii, sau dup! cum programatorul aloc! / dezaloc! variabile dinamice.Pentru primele 2 tipuri de memorie (zona global! %i zona de stiv!), programatorul %tie lamomentul scrierii programuluicantitatea de memorie necesar ! la un anume punct in execu$ia programului, si anumevariabilele disponibile intr-un punctde execu$ie, îns! pe heap se aloc! variabile în func$ie de necesarul la rulare. Spreexemplu, un editor text va aloca %irul decaractere pe heap, cât! vreme nu %tie dac! utilizatorul va introduce 10, 100 sau mai multecaractere.Dac! p este un pointer, atunci p++ incrementeaz! pe p în a%a fel încât acesta s! pointeze pe elementul urm!tor indiferentde tipul variabilei pointate, iar p+=i incrementeaz! pe p pentru a pointa peste i elementedin locul unde p pointeaz! curent.Dac! p %i q sunt pointeri, relatii ca , ==, !=, func$ioneaz!. p < qeste adevarata, de ex, în cazul în care adresa lui p este mai mica (logic) decât adresa lui q.dac! p %i q pointeaz! c!tre 2elemente ale aceluia%i tablou, atunci p < p înseamn! faptul c! p arat! c!tre un element cuindice mai mic decât q.Dac! se testeaz! cu < > pointeri care sunt adrese efective, rezultatul (din punct de vedereal variabilelor din program) nu

    are sens. Ins! acest lucru este permis de c!tre compilator.Relatiile == %i != sunt %i ele permise, intre 2 pointeri. De asemenea, orice pointer poate fitestat cu NULL. Dac! un pointereste == NULL inseamn! c! adresa de memorie spre care pointeaz! este adresa 0, ceea cee un non-sens.4Instructiunea p + ndesemneaza al n-lea obiect din memorie dupa cel pointat curent de p. Acest lucru esteadevarat indiferent de tipul obiectelor pe care p a fost declarat ca pointer. Compilatorul atunci cind il intilneste pe n, il decaleaza

    în functie de lungimea obiectelor pe care pointeaza p, lungime determinata prin declaratia lui p (sizeof(*p)).

  • 8/18/2019 ipc hatz

    46/61

    Este valid! %i sc!derea pointerilor: dac! p %i q pointeaz! pe elementele aceluia"i tablou, p-q este num!rul de elementedintre p %i q. Acest fapt poate fi utilizat pentru a scrie o nou! versiune a lui strlen.int strlen(char *s)//returneazã lungimea sirului{

    char *p = s;while (*p != '\0') p++;return(p-s);}Prin declarare, p este initializat pe s, adic! s! pointeze pe primul caracter din s. In cadrul buclei while este examinat fiecarecaracter pân! se întâlne"te \0 care semnific! sfir "itul sirului de caractere iar apoi se scadcele 2 adrese.Este posibila omiterea testului expilcit iar astfel de bucle sint scrise adeseawhile (*p)

     p++;Deoarece p pointeaza pe caractere, p++ face ca p sa avanseze de fiecare data pe caracterulurmator, iar p-v da numarul decaractere parcurse, adica lungimea sirului. Aritmetica pointerilor este consistenta: dacaam fi lucrat cu float care ocupamai multa memorie decit char, %i daca p ar fi un pointer pe float, p++ ar avansa peurmatorul float.Toate manipularile de pointeri iau automat în considerare lungimea obiectului pointat înasa fel încât trebuie s! nu fiealterat.Opera$ii permise : adunarea sau scaderea unui pointer cu un intreg, scaderea saucompararea a doi pointeri. Nu este permisa adunarea, impartirea, deplasarea logica, sau adunarea unui float saudouble la pointer.6.3. Transmiterea argumentelor la apelurile de func$iiLa apelul unei func#ii argumentele se transmit prin stiv!, in ordinea în care apar în lista deargumente a func$iilor.Aceasta înseamn! c! pentru fiecare argument al func$iei, pe stiv! se creaz! o variabil! local! (func$iei) cu numeleargumentului, iar valoarea transmis! este utilizat! la ini$ializarea acestei variabile locale.Evident, la sfâr %itul execu$ieifunc$iei, aceste variabile locale fiind salvate pe stiv! se pierd, si valorile din ele nu maisunt disponibile dup! terminarea

    apelului func$iei. Spunem c! parametrii s-au transmis func$iei prin valoare.Practic, la transmiterea prin valoare, se creeaz! copii temporare ale parametrilor care setransmit. Func#ia apelat! lucreaz! cu aceste copii iar la revenire valorile variabilelor parametru vor fi nemodificate. Decieste imposibil ca func#ia apelat! s! modifice unul din argumentele reale din apelant.Exemplu:5#includevoid schimbare(int x, int y) //se vor crea copii ale variabilelor x "i y{ int tmp;

    tmp=x;x=y;y=tmp; //.n cadrul copiilor variabilelor se face inversarea

  • 8/18/2019 ipc hatz

    47/61

    } //la revenire copiile variabilelor x "i y se distrugint main(){ int x=5, y=7;schimbare(x,y); //transmitere prin valoare

     printf(“%d %dÄn”,x,y);//valorile r !m.n nemodificate adic! se va afi"a 5 7}

    In acest fel, se transmit doar argumentele de tipul input pentru func$ii.Dac! dorim ca func$ia s! modifice valorile variabilelor primite ca %i argument iar valoriles! se reg!seasc! modificate înfunc$ia apelant! dup! finalizarea apelului func$iei apelate, trebuie s! facem disponibilefunc$iei apelate adresele variabilelortransmise ca si argumente. In acest caz, spunem c! facem transmitere prin adres! saureferin$!.La transmiterea prin adres!, se transmite adresa variabilelor parametru. Toate opera#iile încadrul func#iei apelate se facasupra zonei originale. Dac! se dore"te alterarea efectiv! a unui argument al func#ieiapelante, trebuie furnizat! adresa

    variabilei ce se dore"te a se modifica (un pointer la aceast! variabil!). Func#ia apelat! trebuie s! declare argumentulcorespunz!tor ca fiind un pointer.Exemplu:#includevoid schimbare(int *x, int *y){int tmp;tmp=*x;*x=*y;*y=tmp; //se face inversarea asupra zonei originale}

    int main(){ int x=5, y=7;schimbare(&x,&y); //transmitere prin adres! 

     printf(“%d %dÄn”,x,y);//valorile sunt inversate adic! se va afi"a 7 5}Pentru o func$ie, argumentele care sunt de tipul Input-output sau doar output trebuiesctransmise (obligatoriu) prinadres!.În cazul în care apar masive, având în vedere c! numele tabloului este un pointer constantspre primul element al lui, sefolose"te numele masivului ca adres! de început. Elementele masivului nu vor fi copiateiar opera#iile se vor face astfelasupra zonei originale.O utilizare comun! a argumentelor de tip pointer (transmitere prin adres!) se întâlne%te încadrul func$iilor care trebuie s! returneze mai mult decât o singur ! valoare. De exemplu, constat!m faptul c! func$ia scanfutilizeaz! transmiterea prinadres!, datorit! faptului c!, in argumentele sale, trebuie s! reg!sim valorile care se citesc.66.4. Pointeri %i tablouriIn C, exist! o relatie strâns! între pointeri %i tablouri, încât pointerii %i tablourile pot fitratate simultan. Orice opera$iecare poate fi rezolvat! prin indici în tablouri, poate fi rezolvat! %i cu ajutorul pointerilor.Versiunea cu pointeri va fi îngeneral, mai rapid!.

  • 8/18/2019 ipc hatz

    48/61

    Declara$iaint a[10]define%te un tablou de dimensiunea 10, care este un bloc de 10 variabile de tip int salvatela adrese consecutive numitea[0], a[1], ..., a[9] nota$ia a[i] desemneaza elementul deci pozi#iile in tablou, num!rate de

    la începutul acestuia.Daca pa este un pointer pe un întreg, declarat caint *paatunci asignarea pa = &a[0]face ca pa s! pointeze pe al "zero-ulea" (primul) element al tabloului a; aceasta inseamnaca pa con#ine adresa lui a[0].A%adar asignarea x = *pa va copia con$inutul lui a[0] în x.Daca pa pointeaz! pe un element oarecare al lui a atunci prin defini#ie pa+1 pointeaza peelementul urmator %i în general pa-i pointeaza cu i elemente inaintea elementului pointat de pa iar pa+i pointeaza cu i

    elemente dupa elementul pointat de pa.Astfel, dac! pa pointeaz! pe a[0]*(pa + 1)refera con#inutul lui a[1], pa + i este adresa lui a[i] %i *(pa+i) este con#inutul lui a[i].Aceste observa$ii sunt adev!rate indiferent de tipul variabilelor din tabloul a. Defini$ia"adun!rii unit!$ii la un pointer " %i prin extensie, toat! aritmetica pointerilor este de fapt calcularea prin lungimea în memoriea variabilei pointat. Astfel, în pa+i, i este .nmul#it cu lungimea variabilei pe care pointeaz! pa (sizeof(*pa)) înainte de afi adunate la pa.Coresponden$a între indexare %i aritmetica pointerilor este evident foarte strâns!. De fapt,numele unui tablou este convertitde c!tre compilator într-un pointer constant pe începutul zonei de memorie unde se afl! tabloul.Efectul este c! numele unui tablou este o expresie pointer.Aceasta are câteva implica$ii utile. Din moment ce numele unui tablou este sinonim culoca$ia elementului s!u zero,asignarea pa = &a[0] poate fi scris! %i pa = a7O referin$! la a[i] poate fi scris! %i ca *(a+i).Evaluând pe a[i], C îl converte%te în *(a+i);

    cele dou! forme suntechivalente. Aplicând operatorul & ambilor termeni ai acestei echivalen$e, rezult! ca&a[i] este identic cu a+i: a+i adresaelementului al i-lea în tabloul a.Reciproc, dac! pa este un pointer el poate fi utilizat în expresii cu un indice; pa[i] esteidentic cu *(pa+i).Pe scurt orice tablou %i exprimare de indice pot fi scrise ca un pointer %i deplasament %iorice adres! chiar în aceea%iinstruc$iune. Trebuie $inut seama de o diferen$! ce exist! între numele tablou %i un pointer. Un pointer este o variabil!,astfel ca pa=a %i pa++ sunt opera#ii.

    Dar, un nume de tablou este o constant!, de aceea construc#ii ca a=pa sau a++ suntinterzise.

  • 8/18/2019 ipc hatz

    49/61

    Atunci când se transmite un nume de tablou unei func#ii, ceea ce se transmite este loca$iade inceput a tabloului. In cadrulfunc#iei apelate acest fapt argument este o variabil! ca oricare alta astfel încat unargument nume de tablou este un veritabil pointer, adica o variabila continind o adresa.

     Ne vom putea folosi de aceasta pentru a scrie o nou! versiune a lui strlen, care calculeazalungimea unui sir.int strlen(char *s) // returneazã lungimea sirului s{int n;char *ps;for (n = 0, ps = s; *ps != '0'; ps++)n++;return n;}Ca parametri formali în definirea unei functii

    char s[]%ichar *s;sunt echivalenti; alegerea celui care trebuie scris este determinata în mare parte deexpresiile ce vor fi scrise în cadrulfunctiei. Atunci cind un nume de tablou este transmis unei functii, aceasta poate, dupanecesitati s-o interpreteze catablou sau ca pointer %i sa-l manipuleze în consecinta. Functia poate efectua chiar ambeletipuri de operatii daca i se pare potrivit %i corect.Este posibil! %i transmiterea c!tre o func$ie doar a unei p!r $i dintr-un tablou printransmiterea unui pointer pe începutulsubtabloului. De exemplu, dac! a este un tablou;f(&a[2])sif(a + 2)ambele transmit functiei f adresa elementului a[2] deoarece &a[2] %i a+2 sint expresii pointer care refera al treilea elemental lui a. În cadrul lui f, declarea argumentului poate citif(int arr[]){...}

    8sauf(int *arr){...}Astfel, dupa cum a fost conceput! func$ia f aptul c! argumentul refer ! de fapt o parte aunui tablou mai mare, nu areconsecin$e.6.5 Pointeri pe caractere %i functiiUn sir constant scris astfel " … " este un tablou de caractere (de tipul char[]). În

    reprezentare intern!, compilatorultermin! un tablou cu caracterul \0 în a"a fel încât programele s! poat! detecta sfâr "itul.

  • 8/18/2019 ipc hatz

    50/61

    Lungimea în memorie pentru un sir de caractere ( “…” ) este astfel mai mare cu 1 decâtnum!rul de caractere cuprinseîntre ghilimele.char message[40] = "now is the time";defineste un sir de 40 de caractere %i îl asigneaz! cu sirul de caractere "now is the time".

    Exemplu : strcpy(char s[], char t[]) copiaza sirul t în sirul s, versiunea cu tablouri :int mystrcpy(char s[], char t[]) //copiaza t în s{int i;i = 0;while ((s[i] = t[i]) != '\0')i++;return i;}

    Versiunea lui mystrcpy cu pointeristrcpy(char *s, char *t) //copiaza t în s, versiunea pointeri{while ((*s = *t) != '\0') {s++;t++;}}Deoarece argumentele sunt transmise prin valoare (atentie: avem pointeri transmisi prinvaloare), mystrcpy poate utiliza s%i t în orice fel se dore"te. Aici ei sunt conven#ional utilizati ca pointeri, care parcurgtablourile pina în momentul în cares-a copiat \0 sfirsitul lui t, în s.In practic!, mystrcpy nu va fi scris asa cum s-a aratat mai sus. O a doua posilitate ar fiint mystrcpy(char s[], char t[]) //copiaza t în s{int i = 0;

    while ((*s++ = *t++) != '\0') i++;return i;}9In aceasta ultim! v