Sunteți pe pagina 1din 55

PROGRAMAREA CALCULATOARELOR I LIMBAJE DE PROGRAMARE

NDRUMAR DE LABORATOR

Liviu erbnescu UNIVERSITATEA HYPERION

LISTA LUCRRILOR

1. Iniiere ntr-un mediu de programare. Structura unui program C 2. Implementarea structurii secveniale. Tipuri de variabile 3. Operatori; 4. Operatori la nivel de bit. Construcia mtilor. 5 Funcii. Aria de vizibilitate a variabilelor 6.Transferul parametrilor n cadrul funciilor 7. Instruciuni de decizie 8. Instruciuni de ciclare; 9. Tablouri. Pointeri. Alocarea dinamic. 10. Aritmetica pointerilor; 11. Implementare liste 12. Funcii recursive - Arbori. 13. Funci C din biblioteci. 14. Teste.

LABORATORUL NR.1 INIIERE NTR-UN MEDIU DE PROGRAMARE. STRUCTURA UNUI PROGRAM C Scop: 1. Familiarizarea cu mediul integrat CodeLite. 2. nelegerea structurii unui program scris n limbajul C. 3. nelegerea rolului unui comilator. 4. nelegerea rolului link-editrii.

Consideraii teoretice: Mediul integrat - OpenSource - CodeLite Un spaiu de lucru (workspace) detine un numar de proiecte, de exemplu, acestea pot avea legtur unele cualtele sau nu.. Crearea unui spaiu de lucru se realizeaz prin selectarea " "Workspace | Create new Workspace..."" Un proiect (project) poate avea va rezultat n urma compilrii i apoi a link-editrii un executabil, o bibliotec dinamic (*.DLL), o bibliotec static(*.LIB), etc. Proiectul n sine conine toate informaiile necesare pentru a produce o aplicaie de un anumit tip (aplicaie consol, aplicaie grafic ce utilizeaz un anumit set de controale vizuale, aplicaie cu obiecte grafice, etc). Fiierul ce conine informaii despre spaiul de lucru se numete <workspace-name>.workspace Fiierul ce conine informaii despre proiect este <project-name>. prj

1. Organizarea programelor
La baza oricrui program (software) st un algoritm (metod de rezolvare). Acesta preia date din memoria dinamic a calculatorului (RAM) sau de pe suporturi de stocare i le prelucreaz. Rezulutatul prelucrrii (a execuiei algoritmilor) este stocat n memoria dinamic i apoi poate fi afiat, memorat pe suporturi de stocare a datelor, sau transmis ctre alte aplicaii software. Codul surs se scrie cu ajutorul unui editor de texte, acest editor poate fi unul simplu gen notepad, notepad++, getit sau unul specializat, nglobat ntr-un mediu integrat de dezvoltare pentru software-uri(ex: TuboC++, BorlandC++, C++Builder, VisualC++, SymantecC++, DevC++, CodeLite, NetBean, EclipseC++, gt++, gtk++, etc.).
Programator
Editare Editor de text Compilator

Executabil / bibliotec (*.exe / *.dll, *.lib, ...)


Linkeditare Link-editor

Cod surs ( *.c,*.cpp)

Compilare

Cod obiect (*.obj, *.o)

Biblioteci statice (*.lib)

Etapele pentru ob'inerea unui fiier executabil

Compilatorul transform codul surs n cod obiect ( textul literar l transform n cod main reprezentat de comenzi la nivel de microprocesor). n cadrul codului surs se pot utiliza rutine(proceduri-funcii) definite n cadrul unor biblioteci statice (codul utilizat al bibliotecilor statice este ncorporat n executabil). Codul bibliotecilor dinamice (*.dll dynamic link library) este doar apelat, el nefiind inclus n fisierul executabil (*.exe) sau n biblioteca rezultat. Structura unui program C/C++ Un program C/C++ cuprinde urmtoarele elemente pricipale:

operatori (aritmetici, logici, etc) instruciuni (de decizie, de parcurgere a unei bucle, etc) funcii (apelate din cadrul bibliotecilor sau definite de utilizator) variabile i constante funcia main()

Textul unui program poate fi scris ntr-un fiier sau n mai multe fiiere. Un program va avea o singur funcie main() indiferent dac este scris ntr-un singur fisier sau n mai multe fiiere. Programul compilat i linkeditat va incepe ntodeauna prin lansarea n execuie a instruciunilor i funciilor din cadrul lui main(). Prin ieirea din funcia main() se ncheie i execuia programului.

Desfurarea lucrrii: 1. Lansarea mediului CodeLite, i studierea principalelor componente ale interfeei acestuia 2. Crearea unor spaii de lucru 3. Crearea unui proiect pentru aplicaie consol 4. Compilarea unui exemplu. Modificarea setrilor implicite de compilare. 5. Executarea separat aLink-editrii pentru o aplicaie. Modificarrea setrilor implicite pentru link-editare

LABORATORUL NR.2 IMPLEMENTAREA STRUCTURII SECVENIALE. TIPURI DE VARIABILE Scop: 1. Familiarizarea cu funciile de intrare-ieire pentru consol. 2. nelegerea noiunii de variabil 3. nelegerea diferenelor de reprezentare i de lucru date de tipurile de variabile Consideraii teoretice:
Variabile Datele din cadrul unui program sunt stocate n memoria dinamic (RAM), ele vor fi sterse fie la un anumit moment n timpul execuiei programului, fie la sfritul acestuia. Acestea pot fi date ce urmeaz a se modifica n cadrul programului prin realizarea de operaii asupra acestora denumite VARIABILE i date care rmn constante n urma execuiei programului denumite CONSTANTE. Pentru ca aceste date s poat fi accesate este necesar declararea acestora n cadrul programului. O variabil va avea o denumire pe care o va pune utilizatorul n momentul declarrii acestora. Operaiile din cadrul unui program se realizeaz asupra variabilelor. Fiecare variabil va avea o anumit structur n ceea ce priveste reprezentarea sa n memorie (tipul de variabil) Tipurile de variabile n funcie de reprezentarea n cadrul memoriei variabilele pot fi de mai multe tipuri. Acestea trebuie declarate nainte de compilarea programului astfel nct compilatorul s le rezerve sau nu memorie n momentul ncrcrii executabilului n memorie. Principalele tipuri de variabile sunt prezentate n anexa 1. n momentul compilrii programului, este cunoscut tipul variabilelor. n acest mod programul tie ct ocup n memorie fiecare variabil i cum s utilizeze variabila respectiv. IMPLEMENTAREA STRUCTURII SECVENIALE Structura secvenial este o niruire de instruciuni, plasate una dup alta, n ordinea execuiei acestora. Schema logic:
I1 I2 In

Pseudocodul:
instr1; instr2;........; instr n; instr1; instr2;........; instr n;

Implementarea structurii secveniale se realizeaz cu ajutorul instruciunilor: Instruciunea vid Sintaxa: ; Instruciunea vid nu are nici un efect. Se utilizeaz n construcii n care se cere prezena unei

instruciuni, dar nu se execut nimic. Instruciunea expresie Sintaxa: expresie; sau: apel_funcie; Ex: sqrt() este o funcie definit n biblioteca matematic
int a=3,b=4,c; double d; c=a+b; d=sqrt(b);

Instruciunea compus (instruciunea bloc) Sintaxa:


{ declaraii variabile; { declaraii variabile; instr1; instr2;........; instr n; instr1; instr2;........; instr n; } }

ntr-un bloc de instruciuni se pot declara variabile care pot fi accesate doar n corpul blocului. Instruciunea bloc este utilizat n locurile n care este necesar prezena unei singure instruciuni, ns procesul de calcul implic executarea mai multor instruciuni. Principalele tipuri de variabile Tip variabil Reprezentare n cadrul memoriei (numr de bii) 8 8 8/16/32/64 8/16/32/64 16 16 32 32 32 64 80 8 8/16/32/64 true / false Valori posibile Descriere

char unsigned char int unsigned int short unsigned short long unsigned long float double long double bool void

-27 +27-1 0 +216-1 -231 +231-1 0 +232-1 -215 +215-1 0 +2 -1 -215 +215-1 0 +2 -1
cca. 10 semnificative
38

caracter utilizat i pentru codurile ASCII (0127) caracter i utilizat pentru codurile ASCII (0255) ntreg cu semn (dependent de sistem 8/16/32/64 bii ) ntreg fr semn (dependent de sistem 8/16/32/64 bii ) ntreg scurt cu semn ntreg scurt fr semn ntreg lung cu semn ntreg lung fr semn
10 , 6 cifre
38

16

16

Numr real reprezentat pe 32 de bii Numr real reprezentat pe 64 de bii (cel mai des utilizat) Numr real reprezentat pe 80 de bii boolean Nimic / vid

cca. 10308 10308, 15 cifre semnificative

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.3 OPERATORI Scop: 1. negerea i familarizarea cu operatorii din C 2. Utilizarea operatorilor din limbajul C Consideraii teoretice:
Operatori unari SIMBOLUL + ++ ++a a----a Operatori binari aritmetici SIMBOLUL FORMA + a+b a-b * a*b / a/b % a%b Operatori de atribuire aritmetici SIMBOLUL FORMA = a=b += a+=b -= a-=b /= a/=b %= a%=b

FORMA -a +a a++

Operaia realizat negarea lui a valoarea lui a Postincrementare: preia valoare, apoi creste Preincrementare: mai nti crete cu 1, apoi valoarea Postdecrementare: preia valoarea, apoi scade Predecrementare: mai nti scade cu 1, apoi valoarea Operaia realizat a adunat cu b b sczut din a a nmuit cu b a mprit la b a modulo b (restul mpririi)

cu 1 preia cu 1 preia

Exemplu -3 3 a=3++; a are val. 3 a=++3; a are val. 4 a=3--; a are val. 3 a=--3; a are val. 2

Exemplu 3.7+5.3 3.1-5.0 1.2*4.1 1.2/4.1 5%4

Operaia realizat a preia valoarea lui b a=a(fostul coninut)+b a=a-b a=a/b a=a%b

Operatori relaionali ( 0 este false, diferit de 0 este adevrat, ex:-0.0000007 este adevrat / are valoare de adevr true) SIMBOLUL > >= < <= == != FORMA a>b a>=b a<b a<=b a==b a!=b Operaia realizat dac a>b, atunci true, altfel false daca a>=b atunci true, altfel false daca a<b atunci true, altfel false daca a<=b atunci true, altfel false dac a identic cu b, atunci true, altfel false dac a difer de b, atunci true, altfel false

Operatorii logici SIMBOLUL && || ! (T true, F - false) x F F T T Operatorul cast SIMBOLUL (tip) y F T F T x&&y F F F T x||y F T T T !x T T F F FORMA a&&b a||b !a Operaia I/AND SAU/OR NEGAT/NOT

FORMA (tip)a

Operaia realizat a este convertit la tipul tip

Operatorul sizeof (tipse refera la tip de dat,ex:int,double,structuri,clase) SIMBOLUL FORMA Operaia realizat sizeof(tip) sizeof(tip) d numrul de octei ai tipului sizeof sizeof(a) sizeof(a) d numrul de octei ai variabilei a Operatorul condiional SIMBOLUL FORMA ?: a?b:c

Operaia realizat Dac a0 (true), va fi preluat b, altfel c

Operatorii primari (vor fi utilizai n laboratoarele urmtoare) OPERATORUL SIMBOLUL FORMA Operaia realizat & &a adresa variabilei a adresa variabilei a fiind pointer (adres), *a este coninutul unui * *a coninutul lui a pointer [] a[2] elementul al treilea din vector indexare . x.y valoarea membrului y al structurii x punct valoarea membrului y al unei structuri sgeat spre -> p->y punctate prin intermediul pointerului p dreapta

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.4 OPERATORI LA NIVEL DE BIT. CONSTRUCIA MTILOR. Scop: 1. negerea i familarizarea cu operatorilor la nivel de bit, din limbajul C 2. Utilizarea operatorilor din limbajul C. 3. Construcia i aplicarea mtilor binare

Consideraii teoretice:
Operatorii de manipulare la nivel de bit (binari+unari) SIMBOLUL FORMA Operaia realizat a este deplasat spre dreapta cu b biti (se completeaz >> a>>b
restul cu 0)

<< & | ~ ^

a<<b a&b a|b ~a a^b

a este deplasat spre stnga cu b biti a i b (bit cu bit) a sau b (bit cu bit) negare (bit cu bit) sau exclusiv (bit cu bit)

Operatorii de atribuire i manipulare la nivel de bit SIMBOLUL FORMA Operaia realizat >>= a>>=b a=a(fosta valoare)>>b <<= a<<=b a=a<<b &= a&=b a=a&b |= a|=b a=a|b ^= a^=b a=a^b TABEL DE ADEVR (0 false, 0 true) (presupunem x i y dimensiune un bit): x 0 0 1 1 Ex: Inversarea a dou valori int a=3,b=5; a=a^b; b=a^b; a=a^b; y 0 1 0 1 x&y 0 0 0 1 x|y 0 1 1 1 x^y 0 1 1 0 ~x 1 1 0 0

Desfurarea lucrrii: 1. Se ruleaz exemplul din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.5 FUNCII. ARIA DE VIZIBILITATE A VARIABILELOR Scop: 1. nelegerea noiunii de funcie n limbajul C. Apelul i prototipul funciilor. 2. negerea noiunii de parametru pentru o funcie. 3. Utilizarea cuvntului cheie return. 4. Utilizarea variabilelor locale 5. Utilizarea varabilelor globale 6. Utilizarea variabilelor de tip static 7.Utilizarea variabilelor prin cuvntul cheie extern 8.Utilizarea operatorului rezoluie :: n cadrul accesrii variabilelor 9. Controlul domeniului de vizibilitate pentru variabile.

Consideraii teoretice:
FUNCII Orice program C/C++ este structurat pe funcii, astfel nu vom avea instruciuni dect n cadrul funciilor. Orice program C/C++ ncepe prin execuia funciei main(). Un program va avea o singur funcie main(), indiferent de numrul de fiiere n care este scris codul. Ieirea din funcia main() echivaleaz cu ieirea din program.

STRUCTURA UNEI FUNCII


Din punct de vedere conceptual, funcia reprezint o aplicaie definit pe o mulime D (D=mulimea, domeniul de definiie), cu valori n mulimea C (C=mulimea de valori, codomeniul), care ndeplinete condiia c oricrui element din D i corespunde un unic element din C.

Funciile comunic prin lista de argumente. Ele primesc ca parametri (argumente) datele de intrare, efectueaz prelucrrile descrise n corpul funciei asupra acestora i pot returna rezultatul ntr-o singur variabil care poate fi i de tip pointer. n cazul n care funcia trebuie s ntoarc mai multe valori se va utiliza transferul prin referin. Execuia programului ncepe cu funcia principal, numit main(). Funciile pot fi descrise n cadrul aceluiai fiier, sau n fiiere diferite. O funcie nu poate fi spart n mai multe fiiere.
O funcie este formata din antet si corp:
antet_funcie antet_funcie {corpul_funciei {corpul_funciei } }

sau
tip_val_return nume_func(lista_declaraiilor_param_formali) tip_val_return nume_func(lista_declaraiilor_param_formali) {declaraii_variabile_locale {declaraii_variabile_locale instruciuni instruciuni return valoare/pointer return valoare/pointer } }

Prima linie reprezint antetul funciei, n care se indic: tipul funciei, numele acesteia i lista

declaraiilor parametrilor formali. Dac funcia nu ntoarce nici o valoare, n locul tip_vali_return se specific void. Dac tip_val_return lipsete, se consider, implicit, c acesta este int. Nume_funcie este un identificator. Lista_declaraiilor_param_formali (ncadrat ntre paranteze rotunde) const ntr-o list (enumerare) care conine tipul i identificatorul fiecrui parametru de intrare, desprite prin virgul. Tipul unui parametru poate fi oricare, chiar i tipul pointer. Dac lista parametrilor formali este vid, n antet, dup numele funciei, apar doar parantezele ( ), sau (void). Corpul funciei este un bloc, care implementeaz algoritmul de calcul folosit de ctre funcie. n corpul funciei apar (n orice ordine) declaraii pentru variabilele locale i instruciuni. Dac funcia ntoarce o valoare, se folosete instruciunea return valoare. La execuie, la ntlnirea acestei instruciuni, se revine n funcia apelant. ntr-o funcie putem avea mai multe intruciuni return, doar una din acestea va putea fi executat. n limbajul C/C++ se utilizeaz declaraii i definiii de funcii. Declaraia conine antetul funciei i informeaz compilatorul asupra tipului, numelui funciei i a listei parametrilor formali (n care se poate indica doar tipul parametrilor formali, nu i numele acestora). Declaraiile de funcii se numesc prototipuri, i sunt constituite din antetul funciei, din care pot lipsi numele parametrilor formali. Definiia conine antetul funciei i corpul acesteia. Nu este admis definirea unei funcii n corpul altei funcii. APELUL I PROTOTIPUL FUNCIILOR O funcie poate fi apelat printr-o construcie urmat de punct i virgul, numit instruciune de apel, de forma: nume_funcie (lista_parametrilor_efectivi); Parametrii efectivi trebuie s corespund cu cei formali ca ordine i tip. La apel, se atribuie parametrilor formali valorile parametrilor efectivi, dup care se execut instruciunile din corpul funciei. La revenirea din funcie, controlul este redat funciei apelante, i execuia continu cu instruciunea urmtoare instruciunii de apel, din funcia apelant. DOMENIUL DE VIZIBILITATE AL VARIABILELOR Variabilele pot fi globale )declarate la nceputul fiierului, n afara funciilor sau locale declarate n cadrul funciilor. O variabil global poate fi vazut n orice funcie din fiierul respectiv. Variabilele declarate n interiorul unei funcii, ct i parametrii formali ai acesteia nu pot fi accesai dect n interiorul acesteia. Aceste variabile sunt numite variabile locale i nu pot fi accesate din alte funcii. Domeniul de vizibilitate a unei variabile este poriunea de cod la a crei execuie variabila respectiv este accesibil. Deci, domeniul de vizibilitate a unei variabile locale este funcia n care ea a fost definit. Dac n interiorul unei funcii exist instruciuni compuse (blocuri) care conin declaraii de variabile, aceste variabile nu sunt vizibile n afara blocului. Dac nainte de apelul funciilor folosite, acestea au fost definite (antet+corp) acestea nu mai trebuiesc declarate la nceputul fiierului sau in fiierele de tip header . Prototipurile funciilor din biblioteci (predefinite) se gsesc n headere. Utilizarea unei astfel de funcii impune doar includerea n program a headerului asociat, cu ajutorul directivei preprocesor #include. Programatorul i poate crea propriile headere, care s conin declaraii de funcii, tipuri globale, macrodefiniii, etc. Domeniul de valabilitate (vizibilitate) a unei variabile sau a unei funcii este: fiierul surs, dac declaraia funciei apare n afara oricrei funcii (la nivel global); funcia sau blocul n care apare declaraia. O variabil global declarat ntr-un fiier va putea fi vazut n alt fiier din cadrul aceluiai program numai dac este redeclarat tot la nceputul noului fiier dar avnd cuv-ntul cheie extern n fa .

Ex :

//fiier temp1.cpp #include temp2.h static int a1; int q1,q2; int f2(int); int f1(int a, int b) { int m,n; ............ } void main() {int x,y,z1,z2; .... z1=f1(3,4); z2=f2(a1)-f5(q1); } int f2(int d) { return d++; }

//fiier temp2.h int f5(int);

//fiier temp2.cpp extern int q2; int f3(int a, int b) { int m,n; ............ } int f4(void) {int x,y,d; ........ x=f3(q2,y); y=f5(q2); ........ } int f5(int d) {int a; a=::d-d; // return a--; } //prin ::d se preia val. din functia superioara (f4)

Prin declararea cu static variabila global se vede doar in fisierul respectiv i nu poatre fi declarat prin extern in alt fiier. Valoarea variabilei de tip static declarat local la nivelul unei funcii i va menine valoarea chiar i dup ieirea din funcia respectiv, la o nou intrare n funcie ea va avea ultima valoare. n cazul variabilelor locale, compilatorul aloc memorie n momentul execuiei blocului sau funciei n care acestea sunt definite. Cnd execuia funciei sau blocului se termin, se elibereaz memoria pentru acestea i valorile pentru variabilele locale se pierd. Atenie! Dac variabila este de tip pointer i a fost alocat dinamic n interiorul funciei ea va trebui dealocat cu funcia corespunztoare altfel ea va ocupa n continuare spaiul din memorie chiar i dup ieirea din funcie. Timpul de via a unei variabile locale este durata de execuie a blocului (sau a funciei) n care aceasta este definit. Timpul de via a unei variabile globale este durata de execuie a programului. Moduri de alocare a memoriei:

Se aloc static memorie pentru variabilele globale i variabilele locale declarate n mod explicit static. Se aloc memorie pe stiv pentru variabilele locale. Se aloca dinamic memorie n mod explicit, cu ajutorul funciilor de alocare dinamica

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.6 TRANSFERUL PARAMETRILOR N CADRUL FUNCIILOR Scop: 1. nelegerea tranferului prametrilor prin valoare 2. nelegerea tranferului prametrilor prin adres 3. nelegerea tranferului prametrilor prin referin Consideraii teoretice: TRANSFERUL PARAMETRILOR UNEI FUNCII
Funciile comunic ntre ele prin argumente (parametrii). Exist urmtoarele moduri de transfer (transmitere) a parametrilor ctre funciile apelate: Transfer prin valoare; Transfer prin pointeri; Transfer prin referin.

TRANFERUL PARAMETRILOR PRIN VALOARE


De la programul apelant ctre funcia apelat, prin apel, se transmit valorile partametrilor efectivi, reali. Aceste valori vor fi atribuite, la apel, parametrilor funciei. Deci procedeul de transmitere a parametrilor prin valoare const n ncrcarea valorii parametrilor efectivi n zona de memorie a parametrilor funciei (n stiv). La apelul unei funcii, parametrii reali trebuie s corespund ca ordine i tip cu cei din declaraie. O modificare a valorii parametrului de intrare, n interiorul funciei (printr-o operaie din corpul funciei), nu va modifica valoarea parametrului din afara funciei , ci doar a copiei locale a parametrului din cadrul stivei. Ex
//transfer prin valoare int f1(int a, int b) {a++;b-=5; return a+b; } void main() {int x,y,z; cout<<"x=";cin>>x;//ex:3 cout<<"y=";cin>>y;//ex:4 z=f1(x,y); cout<<"z="<<z;//ex:z=7 cout<<"\nDupa iesire din f1: "; cout<<"x="<<x<<";y="<<y; getch();//ex:x=3,y=4 }

TRANSFERUL PARAMETRILOR PRIN POINTERI


Parametrii transmii unei funcii pot fi pointeri (variabile care conin adrese). n aceste cazuri, parametrii funciei apelate vor fi iniializai cu valorile parametrilor efectivi, deci cu valorile unor adrese. Astfel, funcia apelat poate modifica coninutul locaiilor spre care pointeaz argumentele (pointerii). Ex:

//transfer prin pointeri #include <iostream.h> #include <conio.h> int f2(int *a, int *b) {(*a)++;(*b)-=5; return *a+*b; } void main() {int x,y,z; cout<<"x=";cin>>x;//ex:3 cout<<"y=";cin>>y;//ex:4 z=f2(&x,&y); cout<<"z="<<z;//ex:z=3 cout<<"\nDupa iesire din f2: "; cout<<"x="<<x<<";y="<<y; getch();//ex:x=4;y=-1 }

TRANSFERUL PARAMETRILOR PRIN REFERIN


Este asemntoare cu transferul prin pointeri cu deosebire c parametrului funiei i se poate asocia (atribui) chiar obiectul(valoarea variabilei) parametrului efectiv. Astfel, parametrul efectiv poate fi modificat direct prin operaiile din corpul funciei apelate. Funcia getch() ateapt apsarea unei taste i este definit n conio.h . Ex:
//transfer prin referin #include <iostream.h> #include <conio.h> int f3(int &a, int &b) {a++;b-=5; return a+b; } void main() {int x,y,z; cout<<"x=";cin>>x;//ex:3 cout<<"y=";cin>>y;//ex:4 z=f3(x,y); cout<<"z="<<z;//ex:z=3 cout<<"\nDupa iesire din f3: "; cout<<"x="<<x<<";y="<<y; getch();//ex:x=4;y=-1 }

Comparnd cele trei moduri de transmitere a parametrilor ctre o funcie, se poate observa: 1. La apelul prin valoare transferul datelor este unidirecional, adic valorile se transfer numai de la funcia apelant ctre cea apelat. La apelul prin referin transferul datelor este bidirecional, deoarece o modificare a parametrilor funciei determin modificarea parametrilor efectivi, care sunt sinonime (au nume diferite, dar refer aceleai locaii de memorie). 2. La transmiterea parametrilor prin valoare, ca parametrii efectivi pot apare expresii sau nume de variabile. La transmiterea parametrilor prin referin, ca parametri efectivi nu pot apare expresii, ci doar nume de variabile. La transmiterea parametrilor prin pointeri, ca parametri efectivi pot apare expresii de pointeri.

n cazul n care funcia trebuie s ntoarc mai multe valori, iar acestea nu pot fi grupate sub o variabil de tip pointer (tablouri sau structuri), se poate utiliza transferul prin referin.

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.7 INSTRUCIUNI DE DECIZIE Scop: 1. nelegerea instruciunii if... else 2. nelegerea instruciunii switch 3. Lucrul cu instruciuni de decizie imbricate Consideraii teoretice:

Instruciunea if
if(<expresie>) if(<expresie>) instr1; instr1; [else [else instr2;] instr2;]

Sintaxa:

unde [ ...] semnific faptul c este opional Ramura else este opional.
TRUE FALS if (<expresie>) E

instr.1

instr.1

La ntlnirea instruciunii if, se evalueaz <expresie>. Dac valoarea expresiei este true ( diferit de zero) se execut instruciunea 1; dac valoarea expresiei este false (egal cu zero), se execut instruciunea 2. Se execut doar una dintre cele dou instruciuni: fie instr1, fie instr2. Dup execuia instruciunii if se trece la execuia instruciunii care urmeaz acesteia. Instr1 i Instr2 pot fi instruciuni compuse (blocuri), sau chiar alte instruciuni if (if-uri imbricate). Exemplu:
int a,b,c; int a,b,c; cin>>a;cin>>b; cin>>a;cin>>b; if(a<(b+1)) c++; if(a<(b+1)) c++; else {a--; c=a+b; else {a--; c=a+b; if(c) a++; if(c) a++; } }

Citirea de la tastatur se realizeaz prin intermediul cin>> (console input) (va fi explicat n cursul despre iostream-uri)
Instruciunea switch n unele cazuri este necesar o decizie multipl special. Instruciunea switch permite acest lucru.

case

test expresie

default

instruciune m instruciune 1 instruciune 2


break break

instruciune n

Dac expresie=expresie_const_1 Dac expresie=expresie_const_1 instruciune1; instruciune1; [ieire;] [ieire;] Dac expresie=expresie_const_2 Dac expresie=expresie_const_2 instruciune2; instruciune2; [ieire;] [ieire;] ........................ ........................ Dac expresie=expresie_const_n Dac expresie=expresie_const_n instruciune_n; instruciune_n; Altfel instruciune_m; Altfel instruciune_m;

Se testeaz dac valoarea pentru expresie este una dintre constantele specificate (expresie_const_1, expresie_const_2, etc.) i se execut instruciunea de pe ramura corespunztoare. n schema logic test_expresie este una din condiiile: expresie=expresie_const_1, expresie=expresie_const_2, etc. Sintaxa:
switch (<expresie>) switch (<expresie>) { { case expresie_const_1: instructiune_1;[break;] case expresie_const_1: instructiune_1;[break;] case expresie_const_2: instructiune_2;[break;] case expresie_const_2: instructiune_2;[break;] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . case expresie_const_n: instructiune_n; case expresie_const_n: instructiune_n; [ default:instructiune_n; ] [ default:instructiune_n; ] } }

Este evaluat <expresie> (expresie aritmetic), iar valoarea ei este comparat cu valoarea expresiilor constante 1, 2, n, etc. (expresii constante=expresii care nu conin variabile). Se execut instruciunea corespunztoare acelei expresie_const_k este egal cu rezultatul evalurii <expresie>. ramuri (instruciune_k) unde

Dac se ntlnete instruciunea break, parcurgerea este ntrerupt i se va iei din blocul dat de switch. Dac nu este ntlnit instruciunea break, se parcurge i instruciunea urmtoare. n cazul n care valoarea expresiei nu este gsit printre valorile expresiilor constante, se execut cazul marcat cu eticheta default (opional). Expresiile expresie, expresie_const_1, expresie_const_2,etc., trebuie s fie ntregi. n cazul n care sunt de alt tip este necesar convertirea acestora la tipul ntreg. Ex:

int a=3,b=4,luna; cin>>luna; switch(luna) { case 1:a++; break; case 2:{a--;b++;} break; case 3:{a--;b--;} case 4:a--; default:{a=0;b=0;} }

pentru luna=1 obinem a=4, b=4 pentru luna=2 obinem a=2, b=5 pentru luna=3 obinem a=1, b=3 pentru luna=4 obinem a=2, b=4 pentru luna>4 obinem a=0, b=0 Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.8 INSTRUCIUNI DE CICLARE Scop: 1. Lucrul cu bucla while 2. Lucrul cu bucla do...while 3. Lucrul cu bucla for 4. Utilizarea instruciunii break n cadrul buclelor 5. Utilizarea instruciunii continue n cadrul buclelor Consideraii teoretice:
IMPLEMENTAREA STRUCTURILOR REPETITIVE (CICLICE) Exist dou categorii de instruciuni ciclice: cu test iniial i cu test final. Implementarea structurilor ciclice cu test iniial

Structura ciclic cu test iniial este implementat prin instruciunile for i while.

Instruciunea for

Limbajul C are o instruciune for deosebit de flexibil. Instruciunea for implementeaz structura ciclic cu numr cunoscut de pai

evaluare expresie1 evaluare expresie1 ATTA CT TIMP expresie2 este TRUE REPET ATTA CT TIMP expresie2 este TRUE REPET begin begin instruciune instruciune evaluare expresie3 evaluare expresie3 end end

Sintaxa:
for (expresie1; expresie2; expresie3) for (expresie1; expresie2; expresie3) instructiune; instructiune;

Nu este obligatorie prezena expresiilor, ci doar a instruciunilor vide. Exemple:


int a=0; for(int i=0;i<100;i++) a++;

evaluare <expresie1> (de obicei iniializare contori) FALSE evaluare <expresie2> TRUE

Instruciune 1 (blocul instr. for)


evaluare <expresie3> (de obicei incrementare contori)

int i,j,m,n,a,b; for(i=0;i<n;i++) for(j=0;j<m;j++) {a+=i*j; if(i<j) b=a; else b=-a; } int i=0,a=0; for(;i<100;) {i++;a++;}

Instruciunea while
while(<expresie>) while(<expresie>) instr1; instr1;

Sintaxa:

evaluare <expresie> FALSE TRUE

Instruciune 1 (blocul instr)


La ntlnirea acestei instruciuni, se evalueaz expresie. Dac aceasta are valoarea TRUE (diferit de ZERO), se execut instruciunea instr1. Se reevalueaz din nou valoarea expresiei. Dac ea este tot 1, se repet instruciunea, etc. Astfel, instruciunea (corpul ciclului) se repet att timp ct expresie are valoarea de adevr TRUE. n momentul n care <expresie> are valoarea de

adevr FALSE(sau egal cu ZERO), se iese din ciclu i se trece la urmtoarea instruciune din afara buclei while. n cazul n care la prima evaluare a expresiei, aceasta are valoarea de adevr FALSE, corpul instruciunii while nu va fi executat niciodat. Instr1 din corpul ciclului while poate fi compus (un bloc). Instruciunea/nile din corpul ciclului while trebuie s modifice valoarea expresiei, altfel va fi un ciclu infinit. Implementarea structurilor ciclice cu test final
Instruciunea do while Sintaxa:
do instr1; do instr1; while(<expresie>) while(<expresie>)

Se execut instruciunea instr1 sau blocul de instruciuni. Se evalueaz apoi <expresie>. Dac aceasta are valoarea TRUE, se execut din nou instr1 altfel se iese din bucl. Se testeaz din nou valoarea expresiei. Se repet execuia instruciunii instr1 atta ct timp valoarea expresiei este TRUE. n cazul instruciunii do while, corpul ciclului se execut cel puin o dat.

Instruciunea break
tip_val_return nume_func (lista_declaraiilor_param_ tip_val_return nume_func (lista_declaraiilor_param_ formali) formali) {declaraii_variabile_locale {declaraii_variabile_locale instruciuni instruciuni return valoare/pointer return valoare/pointer } }

Aceasta foreaz ieirea din interiorul unei bucle fr a se mai ine seama de condiia de meninere n bucl. Instruciunile situate n corpul buclei dup instruciunea break nu vor mai fi executate.

Intruciunea continue

Aceasta duce la ignorarea instruciunilor din bucl, situate dup aceasta, i testarea din nou a expresiei de meninere n bucl. n cazul buclelor for se realizeaz si evaluarea celei de a treia expresii responsabil cu incrementarea contorilor.

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.9 TABLOURI. POINTERI. ALOCAREA DINAMIC. Scop: 1. nelegerea noiunii de tablou 2. Tablouri cu o dimensiune - vectori 3. Tablouri cu dou dimensiuni - matrici 4. Tablouri cu trei dimensiuni 5. Tablouri n- dimensionale 6. nelegerea noiunii de pointer 7. Alocarea dinamic pentru vectori 8. Alocarea dinamic pentru matrici 9. nelegerea alocrii dinamice pentru tablouri n-dimensionale. Consideraii teoretice:
NOTIUNEA DE POINTER Pointerii au fost introdusi in limbajele de programare pentru a putea rezolva mai eficient anumite probleme. Pointerul este o variabila ce contine adresa unui obiect. Obiectul a carei adresa este coninut de pointer poate fi variabil sau funcie. Ex:
int a; int *b;

echivalent cu a scrie

int a,*b;

sau

int *b,a;

(declararea a dou variabile)

Variabila a este de tip ntreg iar variabila b este de tip pointer, ea conine adresa unei variabile de tip ntreg (adresa la care se afl o valoare de tip ntreg ) Pentru calculatoarele pe 32 bii adresele sunt pe 32 bii, adic 4 octei (fr.) / bytes(en.) n cazul declarrii variabilei, semnul * din stnga acesteia semnific faptul ca acesta conine o adres (variabila este de tip pointer) i nu o valoare. n momentul utilizrii variabilei semnul * din stnga acesteia are alt semnificaie, acesta semnific faptul c se preia valoarea variabilei de tip pointer. Ex:
a=*b;

variabila a preia valoarea de la adresa lui b (valoarea la care pointeaz b)


b=&a;

Operatorul unar & este utilizat pentru obinerea adresei. Ex: Ex:
int *b,****c,**d;

sunt de asemenea pointeri.

NOIUNEA DE TABLOU Tablourile au acelai tip de dat i pot avea una sau mai multe dimensiuni (tablori cu o dimensiune = vectori, tablouri cu dou dimensiuni = matrici). Declarea tablourilor se realizeaz prin utilizarea operaratorului [ ]

Ex:

double b[10],c[10][5],d[5][6][3][8],a;

, b este un tablou unidimensional cu 10 elemente

de tip double, c este un tablou bidimensional cu 10x5 elemente de tip double, d este un tablou cu patru dimensiuni avnd 5x6x3x2 elemente de tip double. n cazul variabilelor de tip tablou, este alocat automat memorie pentru ntregul tablou. Elementele acestuia nu sunt iniializate, acestea avnd valori aleatorii. Referirea la un element din cadrul tabloului se va realiza n modul urmtor: Ex:
a = d[1][2][0][6]; // a preia valoarea unei celule din cadrul tabloului d

Indeci ncep cu valoarea 0. n memoria tablourile sunt repezentate prin secvente continue. Practic, d va conine adresa tabloului (un bloc compact de 5x6x3x8 elemente, ocupnd n memorie 5x6x3x8x8 octei - double este pe 8 octei). n exemplul dat, primii 3 vectori din imagine conin adrese i doar ultimul vector conine valorile de tip double.

Ex:
int a,*a1,a2[4],b1[3][4],*b2[5],**b3; int c1[4][7][2],*c2[14][6],**c3[7],***c4 ;

n acest exemplu a este o variabil de tip ntreg (conine o valoare de tip ntreg), a1 este o variabil pointer la tip ntreg (conine adresa unde este memorat variabila de tip ntreg), a2 este un tablou unidimensional (vector) cu 4 elemente de tip ntreg, b1 este un tablou bidimensional (matrice) cu 3x4 elemente de tip ntreg, b2 este un vector cu 5 elemente de tip pointer la ntreg, b3 este un pointer la o matrice cu elemente de tip ntreg, c1 este un tablou tridimensional cu elemente de tip ntreg i cu dimensiunea 4x7x2, c2 este o matrice 14x6 cu elementele de tip pointer la tip ntreg, c3 este un vector cu 7 elemente de tip pointer la matrici de tip ntreg, iar c4 este un pointer la tablou tridimensional cu elemente de tip ntreg. Ex. de atribuiri:
a=a2[1]; a=b1[0][0]; a=c1[1][0][1]; a1=a2; //atunci in urma:a=a1[1];a va avea aceeasi //valoare ca in cazul a=a2[1]; a1=b1[1]; a1=b2[3];a1=c1[1][2];a1=c2[1][0]; b3=c2[3]; b3=c3[1]; a=*a1; a=a1[0];a=b2[2][0]; a=c2[1][0][0]; c3[2][0][0]=a; a1=&a; b3[1]=a1; c4[0]=c3[1];

Alocarea dinamic a memoriei. Utilizatorul poate solicita n timpul execuiei programului alocarea unei zone de memorie. Aceast zon de memorie poate fi eliberat, n momentul n care nu mai este necesar. Alocarea memoriei se poate realiza cu funciile din biblioteca avnd prototipul(declaraiile) n <alloc.h> sau prin utilizarea operatorului new. void *malloc(unsigned n); Funcia aloc un bloc de memorie de n octei. Funcia ntoarce un pointer la nceputul zonei de memorie alocat. n cazul n care nu este posibil alocarea unei zone compacte de n octei funcia returneaz NULL(0x0000). Memoria alocat NU este iniializat. La sfritul operaiilor memoria trebuie eliberat. n cazul alocrii cu funcia malloc dealocarea memoriei se face cu funcia: void free(void *p);

Funcia elibereaz o zon de memorie indicat de p, alocat n prealabil prin malloc(). Funciile de alocare ntorc pointeri generici (void*) la zone de memorie, n timp ce utilizatorul aloc memorie ce pstreaz informaii de un anumit tip. Pentru a putea accesa memoria alocat, indirect, prin intermediul pointerului, acesta va trebui s fie un pointer cu tip, ceea ce impune conversia explicit (prin cast) a pointerului ntors de funcia de alocare ntr-un pointer cu tip.
int *p; p=(int*)malloc(n*sizeof(int)) if(p==NULL) { printf(Memorie insuficienta!); ...... if(p) // identic cu if(p!=NULL) free(p); int *p; p=new int[n]; if(p==NULL) { printf(Memorie insuficienta!); ...... if(p) delete[] p;

sau

Exemplu de alocare dinamic a unei matrici si de eliberare a zonei alocate.


#include <stdio.h> #include <conio.h> #include <alloc.h> //aloca dinamic o matrice cu m linii si n coloane double **aloca2double(int m,int n) {double **A; int k,i; A=(double**) malloc(m*sizeof(double*)); if(!A) return NULL; for(k=0;k<m;k++) {A[k]=(double*) malloc(n*sizeof(double)); if(!A) //alocare esuata, elibereaza memoria deja alocat { for(i=0;i<k;i++) free(A[i]); free(A); return NULL; }//endif }//endfor for(k=0;k<m;k++) for(i=0;i<n;i++) A[k][i]=0; return A; } //----------------------------------------//elibereaza zona de memorie alocata void elib2double(double**A, int m) {int k; for(k=0;k<m;k++) if(A[k]) free(A[k]); if(A) free(A); } //-------------------------------------void main(void) { double **x; x=aloca2double(100,50); if(x==NULL) printf("Memorie insuficienta"); //..... operatii cu matricea x .... elib2double(x,100); getch(); }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.10 ARITMETICA POINTERILOR Scop: 1. Realizarea unor operaii cu adrese pentru vectori 2. Realizarea unor operaii cu adrese pentru matrici 3. Realizarea unor operaii cu adrese pentru tablouri n-dimensionale Consideraii teoretice:
ARITMETICA POINTERILOR Datorit faptului c adresele de memorie a elementelor dintr-un tablou sunt consecutive se pot efectua operaii cu aceste adrese n cadrul tabloului. La incrementarea unei variabile pointer, C++ incrementeaz automat adresa cu o valoare adecvat (1 octet dac tipul variabilei la care puncteaz este char, 2 octei pentru tipul de date short, patru octei pentru long sau float, etc.), astfel nct pointerul s indice urmtoarea valoare pe care o are tipul pointerului (tipul datei la care puncteaz). Pentru tipuri de date complexe (structuri, clase) se incrementeaz cu dimensiunea structurii sau clasei la care puncteaz. Ex:
#include <stdio.h> //biblioteca pentru functia printf -- afisare #include <conio.h> //biblioteca pentru functia getch asteapta //apasarea unei taste DOS void main(void) { int t[4]={0, 1, 2, 3}; int *p; p=&t[2]; p-=2;printf("%d\n", *p); /* afiseaza valoarea lui t[0] */ p+=1;printf("%d\n", *p); /* afiseaza valoarea lui t[1] */ p++;printf("%d\n", *p); /* afiseaza valoarea lui t[2] */ (*p)+=5;printf("%d\n", *p); /* afiseaza valoarea lui t[2]+5 */ getch(); }

Ex:
int a01,a02,*a1,b1[3][4] a3[10]; a1=b1[0];implica a1+2=b1[2]; b1[0]=&b1[0][0];implica b1[0]+5=&b1[1][0]; a3=&a3[0]; b1=&b1[0];b1=&b1[2]-2; b1[2][1]=*(&b1[2][1]); b1[2][1]=*(b1[2]+1); b1[2][1]=*(*(b1+2)+1); b1[2][3]=*(*(b1+2)+3) b1[2][3]=*(&b1[2]+3)

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.11 STRUCTURI . IMPLEMENTARE LISTE Scop: 1. Utilizarea structurilor de date 2. Construcia listelor simplu i dublu nlnuite 3. Parcurgerea listelor 4. Inserarea ntr-o list 5. tergerea dintr-o list Consideraii teoretice: STRUCTURI
Structurile grupeaz date de tipuri diferite, constituind definiii ale unor noi tipuri de date. Componentele unei structuri se numesc membrii (cmpurile) structurii. La declararea unei structuri se pot preciza tipurile, identificatorii elementelor componente i numele structurii. Forma general de declarare a unei structuri:
struct identificator_tip_structura { struct identificator_tip_structura { lista_de_declaratii_membrii; lista_de_declaratii_membrii; } lista_identificatori_variabile; } lista_identificatori_variabile;

n care: struct este un cuvnt cheie (obligatoriu) identificator_tip_structura reprezint numele noului tip (poate lipsi) lista_de_declaratii_membri este o list n care apar tipurile i identificatorii membrilor structurii lista_identificatori_variabile este o list cu identificatorii variabilelor de tipul declarat. Membrii unei structuri pot fi de orice tip cu excepia tipului structur care se declar. Ex:
struct data { int zi; char luna[11]; int an; }; .............. struct data d1,*d2; d1.zi=4; d1->zi=5; strcpy(d1.luna,aprilie);strcpy(d2->luna,mai); d1.an=1968;d2->an=1969;

DECLARAII DE TIP
Limbajul C permite atribuirea unui nume pentru un tip (predefinit sau utilizator) de date. Pentru aceasta se folosesc delcaraiile de tip. Forma general a acestora este: typedef tip nume_tip;
typedef tip nume_tip;

Nume_tip poate fi folosit la declararea datelor n mod similar cuvintelor cheie pentru tipurile predefinite. Ex:

typedef int INTREG; INTREG x, y;

typedef struct{ double parte_real; double parte_imaginar; } COMPLEX; COMPLEX x, y;

typedef struct NOD{ .................. NOD *urm,*ant; } NOD; NOD *cap, *p;

LISTE 1.Lista este o colectie de elemente (celule) nlanuite ce formeaz o structura dinamic, situata in memoria dinamic, n care toate elementele sunt de acelasi tip; numarul de elemente este variabil, chiar nul. 2.O lista este o secventa de zero sau mai multe elemente, numite noduri, toate fiind de acelasi tip. Spre deosebire, tabloul este o structura statica, situata in memoria dinamic, in care toate elementele sunt de acelasi tip; numarul de elemente fiind constant. Un nod al liste liniare apare ca o structura recursiva, avand o componenta de tip pointer la structura, reprezentand legatura ( inlantuirea ) spre nodul urmator. Fiecare element(celul/nod) din cadrul listei nlanuite are o structur de tipul:
Informaie util; Informaie de nlanuire ctre elementul(celula) urmtor; //pentru listele dublu nlnuite Informaie de nlanuire ctre elementul(celula) anterior;

Daca n cadrul elementului/celulei/nodului se face referire doar la elementul/celula/nodul urmtor atunci avem liste simplu nlnuite. Dac se face i referire la nodul anterior atunci avem liste dublu nlanuite. Structura unui element / celule / nod:
ADRESA NODULUI ANTERIOR DATE NOD ADRESA NODULUI URMTOR

CAP LIST

Pentru lucrul cu liste simplu nlnuite este suficient s se cunoasc adresa capului liste, iar pentru listele dublu nlantuite se poate ajunge la orice nod dac se cunoate adresa unui singur nod din list, oricare ar fi el. Crearea unei liste dublu nlanuite Este necesar alocarea dinamic de memorie pentru orice nod nou creat. Alocarea se poate face att cu funcia malloc ct i cu operatorul new. Stergerea elementelor din list trebuie s asigure i dealocarea (eliberarea) memoriei corespunztoare. Aceasta se realizeaz cu funciia free , respectiv operatorul delete. Ex:
............... cap=new NOD;//crearea capului listei sau // (cap=(NOD*) malloc(sizeof(NOD));) memset(cap,0,sizeof(NOD);// asigur initializarea // cu val.0 respectiv val. NULL pentru pointeri //........................................................//pre supunem: p ultimul nod al listei p1=new NOD;memset(cap,0,sizeof(NOD); p->urm=p1; p1->ant=p; p=p1;

Este OBLIGATORIU ca la cele dou capete cap->ante i p->urm sa aib valoarea NULL ( p fiind ultimul nod din list).

Dac p->urm==cap si cap->ante==p atunci avem list circular. Parcurgerea unei liste Presupunem c n acest caz variabila p este un pointer de tip NOD folosit la parcurgerea listei.
......................................... for(p=cap;p->urm;p=p->urm);

Bucla for execut o instruciune vid. Avansul se oprete pe ultimul nod; Exemplu:
#include <stdio.h> #include <malloc.h> #include <string.h> typedef struct NOD2{ int id; NOD2 *urm,*ant; }NOD2; //crearea unei liste cu n noduri, intoarce adresa capului listei NOD2* fc(int n) {NOD2 *p, *p1, *caplista; p=NULL; for(int i=0;i<n;i++) { p1=p; p = (NOD2*)malloc(sizeof(NOD2)); memset(p,0,sizeof(NOD2)); p->id=i+1000;// ptr. o viitoare identificare a nodului if(!i) caplista=p; else { p1->urm=p; p->ant=p1; } } return caplista; } //parcurgerea listei cu pozitionare pe ultimul nod (intoarce adresa ultimului nod din cadrul listei) NOD2* fp1(NOD2 *caplista) { NOD2 *p; for(p=caplista;p->urm;p=p->urm); // p->urm sau p->urm==NULL return p; } //parcurgerea listei cu prelucrare pentru fiecare nod void fp2(NOD2 *caplista) { NOD2 *p; for(p=caplista;p;p=p->urm) {//ex: id=-id p->id=-p->id; } return; } //afisare lista void afis(NOD2 *caplista) { NOD2 *p; int i; printf("\n"); for(p=caplista,i=0;p;p=p->urm,i++) {printf(" [%d]:%d",i,p->id); } return; } //stergerea unui nod din lista prin adresa void fd1(NOD2 *d) { if(d->urm) //nu este ultimul {d->ant->urm=d->urm; d->urm->ant=d->ant; } else {d->ant->urm=NULL;} free(d); }

//stergerea unui nod din lista dat prin id void fd2(int id,NOD2 *caplista) { NOD2 *p; for(p=caplista;p->id!=id;p=p->urm); if(p->id==id) fd1(p); } //adaugarea unui nod (la sfarsitul listei) void fa1(NOD2 *caplista, NOD2 *a) { NOD2 *p; p=fp1(caplista);//pozitionare pe ultimul nod p->urm=a; a->ant=p; } //insereaza nod (cu exceptia primei si ultimei pozitii) -- se da nodul anterior void fi1(NOD2 *anterior, NOD2 *ins) {ins->ant=anterior; ins->urm=anterior->urm; anterior->urm->ant=ins; anterior->urm=ins; } //insereaza nod --- se da id-ul nodului anterior void fi2(int anterior_id, NOD2 *ins, NOD2 *caplista) { NOD2 *p; for(p=caplista;p->id!=anterior_id;p=p->urm); if(p->id==anterior_id) fi1(p,ins); } int main(int argc, char **argv) {NOD2 *c1,*x,*y; c1=fc(10); //x=fp1(c1); //printf("\nUltimul nod:%d",x->id); //fp2(c1); //sterge nod //fd2(1007,c1); //adauga nod //y=(NOD2*)malloc(sizeof(NOD2)); memset(y,0,sizeof(NOD2)); y->id=999; //fa1(c1,y); //insereaza nod y=(NOD2*)malloc(sizeof(NOD2)); memset(y,0,sizeof(NOD2)); y->id=999; fi2(1004,y,c1); afis(c1); getchar(); return 0;}

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.12 FUNCII RECURSIVE - ARBORI Scop: 1. nelegerea lucrului cu stivele de tip LIFO 2. negerea apelului recursiv 3. nelegerea transmiterii parametrilor i a vizibilitii variabilor n cazul apelurilor recursive 4. Construcia arborilor binari 5. Parcurgerea arborilor binari utiliznd tehnici recursive 6. Parcurgerea arborilor (cazul general) utiliznd tehnici recursive Consideraii teoretice: FUNCII RECURSIVE
O funcie este numit funcie recursiv dac ea se autoapeleaz, fie direct (n definiia ei se face apel la ea nsi), fie indirect (prin apelul altor funcii). Pentru fiecare apel al funciei, parametrii i variabilele automatice se memoreaz pe stiv, avnd valori distincte. Variabilele statice ocup tot timpul aceeai zon de memorie (figureaz ntr-un singur exemplar) i i pstreaz valoarea de la un apel la altul. Orice apel al unei funcii conduce la o revenire n funcia respectiv, n punctul urmtor instruciunii de apel. La revenirea dintro funcie, stiva este curat (stiva revine la starea dinaintea apelului). Un exemplu de funcie recursiv este funcia de calcul a factorialului, definit astfel: fact(n)=1, dac n=0; fact(n)=n*fact(n-1), dac n>0;
#include <iostream.h> #include<conio.h> int fact(int n) { if (n<0) { cout<<"Argument negativ!\n"; else if (n==0) return 1; else return n*fact(n-1); } void main() {int nr, f; cout<<"nr="; cin>>nr; f=fact(nr); if(f<0) cout<<"EROARE"; cout<<nr<<"!="<<f<<'\n'; getch(); }

return -1; }

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.13 FUNCII C DIN BIBLIOTECI Scop: 1. Familiarizarea cu cele mai utilizate funcii din bibliotecile C 2. Lucrul cu iruri Consideraii teoretice:
Operatii cu funcii din biblioteca matematic

Ex:
#include <math.h> #include <string.h> char str[10]; double a=0.5, b=3 ,c; c=pow(a,b); c=sqrt(b); c=exp(b); c=log(exp(b)); strcpy(str,15.9); c=atof(c); //ascii to float

Operatii cu caractere Tipul predefinit, destinat n C lucrului cu caractere, este tipul char. Spatiul de memorie asociat variabilelor acestui tip este 1 octet; un caracter se memoreaza ca numarul ntreg corespunzator codului ASCII al caracterului respectiv. Prin urmare, n C un caracter poate aparea n operatii numerice. Valorile acestui tip sunt cuprinse n intervalul [-128...127] n cazul caracterelor cu semn, respectiv [0...255] n cazul celor fara semn. Biblioteca ce contine funiile pentru siruri este data de header-ul <string.h> Ex:
char *str, a[10],d[5][7]; char *b={TEST123}; copiaza b in str strcpy(str,b); //copiaza primele 6 caractere strncpy(str,b); //concateneaza sirurile strncat(str,b); int l=strlen(str);//lungime sir str[3]='R';str[4]=32; //32 este codul ASCII pentru ' '; str[5]=0; //terminator de sir; //a este vector de carctere iar str //este un sir de caractere //putem avea: str[5]=a[3]; sau a[4]=str[2];

Desfurarea lucrrii: 1. Se ruleaz exemplele din seciunea teoretic 2. Se continu cu exemplele corespunztoare din seciunea TESTE

LABORATORUL NR.14 TESTE Scop: Testarea cunotinelor Test #1


A. Ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente):
1. int a=19; (a %= +3)++; cout<<a; R:...... 2. int a=11; a >>= 3; cout<<a; R:...... 3. int a=15,b; b = (a-6)&(a^4); cout<<b; R:...... 4. int a,b[7] = {17,16,15,14,13,12,11}; a = *(&b[3]-1); cout<<a; 5. int a,c[4][2] = {{8,5},{1,2},{3,9},{6,4}}; a = **c+*(*(c+**(&c[1]))); cout<<a; R:.... 6. char *str = "ABCDEF"; str[1] = str[1]+1-'C';str[3]=str[4]-(str[3]+1); cout<<str; R:... R:......

B .S se implementeze o funcie care ntoarce valoarea rezultat:

(1ai1)
i=1

j=1

aij

k =1

bk aijai1

double

f1(double **a, double *b)

{
}

C. Se d structura nodurilor dintr-un arbore binar:


typedef struct NOD{int ID; NOD *st, *dr, *ant} NOD; S se scrie o funcie ce preia o adres a unui nod oarecare dintr-un arbore i ntoarce adresa nodului rdcin.

NOD* radArb(NOD *nodX) { }

Test #2

A. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul
existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:
1a. int a=22; a%=+1; printf(%d,a); 1b. int a,b=22; a=b++; printf(%d,a); 2 . int a=11; a>>=2;printf(%d,a); 3. int a=11,b,c,d; b=(a^11)&(a|22); c= a^11; d=a|22; 3a printf(%d,c);R3a:... 3b printf(%d,d); R3b:... 3c printf(%d,b); R3c:.... 4. int a[2],b[7]={11,22,33,44,55,66,77}; a[0]=*(&b[0]+1); a[1]=*b; 4a.printf(%d,a[0]); R4a:...... 4b.printf(%d,a[1]); R4b:...... R1a:...... R1b:...... R2a:......

5. int a[3],c[4][3]={{11,22,33},{12,23,34},{13,24,35},{14,25,36}}; a[0]=1+*(&c[0][0]+2); a[1]=**(&c[0]+1); a[2]=2-**c; 5a.printf(%d,a[0]); R5a:...... 5b.printf(%d,a[1]); R5b:...... 5c.printf(%d,a[2]); R5c:......

B. S se implementeze o funcie double f1(double


i care ntoarce valoarea

11 b i
i =1

**a, double *b) care preia matricea a i vectorul b

22
8 k=1

ai k ak.k

expresiei:

C.Se d funcia f2, s se scrie ce va fi afiat n urma execu iei funciei main() (sunt afi ate 4linii):

void f2(int a, int* b, int& c) { int m=22; static int t; a++;b++;c++;t++;m++; printf(a=%d b=%d c=%d t=%d\n,a,*b,c,t);return;} int main() { int x=1,y=2,z=3,w[3]; f2(x,&y,z); printf(x=%d y=%d z=%d\n,x,y,z); w[0]=x; w[1]=y; w[2]=z; f2(w[0],&w[1],w[2]); printf(w[0]=%d w[1]=%d w[2]=%d\n,w[0],w[1],w[2]); return 0;} R1.............................................. R2.............................................. R3.............................................. R4..............................................

D.

Se d structura nodurilor dintr-un arbore binar: typedef struct NODA{int ID; NODA *pSt, *pDr} NODA; S se scrie o funcie ce preia adresa capului arborelui i ntoarce adresa capului unei liste dublu

nlnuite ce conine ID-urile nodurilor din marginea dreapt a arborelui. Structura nodurilor listei va fi: typedef struct NODL{int ID; NODL *urm, *ant} NODL;

TEST #3

A. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul
existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:
1a. int a=33; a%=+1; printf(%d,a); 1b. int a,b=33; a=b--; printf(%d,a); 2. int a=33; a>>=2;printf(%d,a); 3. int a=33,b,c,d; b=(a^11)&(a|22); c= a^11; d=a|22; 3a printf(%d,c);R3a:... 3b printf(%d,d); R3b:... 3c printf(%d,b); R3c:.... 4. int a[2],b[7]={11,22,33,44,55,66,77}; a[0]=*(&b[2]+1); a[1]=1-*b; 4a.printf(%d,a[0]); R4a:...... 4b.printf(%d,a[1]); R4b:...... R1a:...... R1b:...... R2a:......

5. int a[3],c[4][3]={{11,22,33},{12,23,34},{13,24,35},{14,25,36}}; a[0]=1+*(&c[1][1]-1); a[1]=**(&c[1]+1); a[2]=**c-3; 5a.printf(%d,a[0]); R5a:...... 5b.printf(%d,a[1]); R5b:...... 5c.printf(%d,a[2]); R5c:......

. S se implementeze o funcie double f1(double **a, double *b) care preia matricea a i vectorul b i care ntoarce valoarea

11

bi
i =1

bi
i=1


22

expresiei:

ai k
k =1

C.Se d funcia f2, s se scrie ce va fi afiat n urma execu iei funciei main() (sunt afi ate 4linii):

void f2(int a, int* b, int& c) { int m=33; static int t; a--;b--;c--;t--;m--; printf(a=%d b=%d c=%d t=%d\n,a,*b,c,t);return;} int main() { int x=10,y=20,z=30,w[3]; f2(x,&y,z); printf(x=%d y=%d z=%d\n,x,y,z); w[0]=x; w[1]=y; w[2]=z; f2(w[0],&w[1],w[2]); printf(w[0]=%d w[1]=%d w[2]=%d\n,w[0],w[1],w[2]); return 0;} R1.............................................. R2.............................................. R3.............................................. R4..............................................

D.

Se d structura nodurilor dintr-un arbore binar: typedef struct NODA{int ID; NODA *pSt, *pDr} NODA; S se scrie o funcie ce preia adresa capului arborelui i ntoarce adresa
frunz

capului unei liste dublu nlnuite ce conine ID-urile nodurilor NODL *urm, *ant} NODL;

(terminale). Structura nodurilor listei va fi: typedef struct NODL{int ID;

TEST#5

I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=22; a%=+8; printf(%d,a);


2. int a,b=13; a=(--b)++; printf(%d,a);

R1:...... R2:......

3. int a=15,b=2;if((a>1)&&(b>=3)) a<<=b; else a>>=b;printf(%d,a); R3:...... 4. int a=13,b; b=(a^5)&(a|2);printf(%d,b); R4:......

5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[0]+3); printf(%d,a); R5:...... 6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(&c[3][0]-2)+**(&c[0]+1);printf(%d,a); R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=***a+**(*a+1); printf(%d,a); R7:........ 8. char *str="ABCDEFG"; str[1]=str[4]-str[1]+'B';str[2]=!str[4]; printf(%s,str); R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

b i
i=1 j =1

double

f_(double **a, double *b)

b j

k=1

bk a j.ja k.k

TEST #6

A. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul
existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:
1a. int a=22; a%=+2; printf(%d,a); 1b. int a,b=10; a=b++; printf(%d,a); 2 . int a=10; a>>=2;printf(%d,a); 3. int a=10,b,c,d; b=(a^10)&(a|11); c= a^10; d=a|2; 3a printf(%d,c);R3a:... 3b printf(%d,d); R3b:... 3c printf(%d,b); R3c:.... 4. int a[2],b[7]={12,23,34,45,56,67,78}; a[0]=*(&b[2]+1); a[1]=*b; 4a.printf(%d,a[0]); R4a:...... 4b.printf(%d,a[1]); R4b:...... R1a:...... R1b:...... R2a:......

5. int a[3],c[4][3]={{10,23,34},{11,22,13},{31,42,33},{14,21,31}}; a[0]=1+*(&c[0][1]+1); a[1]=**(&c[1]+1); a[2]=**c; 5a.printf(%d,a[0]); R5a:...... 5b.printf(%d,a[1]); R5b:...... 5c.printf(%d,a[2]); R5c:...... 6. char *str = "ABCDEF"; str[1] = str[1]+1-'C';str[3]=str[4]-(str[3]+1); printf(%s,str); R6:...

B. S se implementeze o funcie double f1(double


i care ntoarce valoarea expresiei:
9 6

**a, double *b) care preia matricea a i vectorul b

(1ai1) aij
i=1 j=1

k =1

bk aijai1

TEST #7

A. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul
existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:
1a. int a=3; a%=+1; printf(%d,a); 1b. int a,b=3; a=b--; printf(%d,a); 2. int a=3; a>>=2;printf(%d,a); 3. int a=3,b,c,d; b=(a^10)&(a|2); c= a^9; d=a|8; 3a printf(%d,c);R3a:... 3b printf(%d,d); R3b:... 3c printf(%d,b); R3c:.... 4. int a[2],b[7]={21,12,13,14,51,16,17}; a[0]=*(&b[2]+3); a[1]=2+*b; 4a.printf(%d,a[0]); R4a:...... 4b.printf(%d,a[1]); R4b:...... R1a:...... R1b:...... R2a:......

5. int a[3],c[4][3]={{10,2,3},{2,23,4},{13,21,35},{14,12,5}}; a[0]=*(&c[1][1]-1); a[1]=**(&c[1]+3); a[2]=**c; 5a.printf(%d,a[0]); R5a:...... 5b.printf(%d,a[1]); R5b:...... 5c.printf(%d,a[2]); R5c:...... 6. char *str="ABCDEFG"; str[5]=str[3]-str[0]+'B';str[6]=!(str[5]-str[3]); printf(%s,str); R6:...

. S se implementeze o funcie double f1(double **a, double *b) care preia matricea a i vectorul b i care ntoarce valoarea expresiei:
9 6

bi
i=1

j =1

8 bj b a i.j a i.i k =1 k

TEST #8

I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora :

1. int a=10; a%=+3; cout<<a;


2. int a,b=10; a=(--b)++; cout<<a; 3. int a=20,b=3;if((a>1)&&(b>=2)) a>>=b; else a<<=b; cout<<a; 4. int a=10,b; b = (a | 15) & (a ^ 12); cout<<b; 5. int a,b[7]={13,11,15,17,19,21,23}; a=*(&b[2]-1); cout<<a;

R1:...... R2:...... R3:...... R4:...... R5:......

6. int a,r,s,t,c[4][3]={{13,11,15},{4,23,25},{31,3,35},{14,22,10}}; r=c[3][0]; s=*c[1]; t=**(&c[2]+1);a=*(&r-s)+t; a)cout<<r; b)cout<<s; c)cout<<t; d)cout<<a; R6a:....... R6b:....... R6c:....... R6d:.......

7. int r,s,a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}}; r=***a; s=*(a[1][2]-1); a) cout<<r; R7a:........ b) cout<<s; R7b:........ 8. char *str="ABCDEFG"; str[2]=str[3]-str[1]+'B';str[4]=!str[4]; cout<<str; R8:............

II. S se implementeze o funcie care ntoarce valoarea rezultat:

bk i=1 j =1 k=1 a j.j a k.k Tablourile a i b conin numere reale i sunt transmise prin adres, iar valorile iMax, jMax i kMax sunt transmise prin referin.

iMax

b i

jMax

b j

kMax

III. Ce va afia urmtoarea secven de cod?


#include <stdio.h> #include <conio.h> int main() {int s=3,t; for(;;--s) { if(!(s+2)) break; switch(s) { case 0:t=3;t<<=1; break; case 1:t=4;t^=5; break; case 2:t=5;t%=t; break; default: t=9; }; printf("s= %d --- t=%d \n",s,t); } getch(); return 0; }

TEST #9 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=13; a%=+8; cout<<a;


2. int a,b=11; a=(--b)++; cout<<a; 3. int a=28,b=3;if((a>1)&&(b>=3)) a>>=b; else a<<=b; cout<<a; 4. int a=11,b; b = (a | 15) & (a ^ 11); cout<<b;

R1:...... R2:...... R3:...... R4:......

5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[1]-1); cout<<a;

R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(&c[3][0]-*c[1])+**(&c[2]+1);cout<<a;R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=***a+*(a[1][2]-1); cout<<b; R7:........ 8. char *str="ABCDEFG"; str[2]=str[3]-str[1]+'C';str[4]=!str[4]; cout<<str; R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

bi
i=1

j =1

double

f_(double **a, double *b)

b j

k=1

bk a i.jai.i

TEST

#10

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a-3; a-=3; *b-=4; c-=5; s++; ::d--; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=1,b=2,*c,m[2]; c =(int*)malloc(1*sizeof(int)); *c=3;d=4; m[0]=fx(a,&b,*c); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(*c,&a,b); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa capului arborelui i realizeaz inversarea (stnga cu dreapta) a nodurilor al cror nod printe are ID-ul divizibil cu 5. void d5iArb(NOD *cap) {

TEST #11 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=16; a%=+8; cout<<a;


2. int a,b=12; a=(++b)--; cout<<a;

R1:...... R2:......

3. int a=7,b=2;if((a>25)&&(b>=3)) a>>=b; else a<<=b; cout<<a;R3:...... 4. int a=12,b; b=(a|10)&(a^7); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[1]+1); cout<<a; R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(c[1]-1)+**(&c[2]+1);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=*(**a+1)+***(&a[1]-1); cout<<b; R7:........ 8. char *str="ABCDEFG"; str[0]=str[3]-str[2]+'A';str[5]=!str[4]; cout<<str; R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

i=1 j =1

10

double

f_(double **a, double *b)

b j

k=1

bk a i.jai.i

TEST #12 I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a-4; a-=7; *b+=8; c-=5; s++; ::d--; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=2,b=3,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=4;d=5; m[0]=fx(b,c,a); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(a,c,b); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa nodului rdcin al arborelui i ntoarce adresa nodului rdcin al unui arbore(subarbore) al carui ID este 21, iar ambele noduri descendente (copil) au ID-uri pare. NOD* adrId21Arb(NOD *cap) {

TEST #13 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=19; a%=+8; cout<<a;


2. int a,b=13; a=(--b)++; cout<<a;

R1:...... R2:......

3. int a=15,b=2;if((a>1)&&(b>=3)) a>>=b; else a<<=b; cout<<a;R3:...... 4. int a=13,b; b=(a^5)&(a|2); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[0]+3); cout<<a; R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(&c[3][0]-2)+**(&c[0]+1);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=***a+**(*a+1); cout<<b; R7:........ 8. char *str="ABCDEFG"; str[1]=str[4]-str[1]+'B';str[2]=!str[4]; cout<<str; R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

b i
i=1 j =1

double

f_(double **a, double *b)

b j

k=1

bk a j.ja k.k

TEST #14

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a+3; a+=10; *b-=10; c+=10; s++; ::d++; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=3,b=4,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=5;d=6; m[0]=fx(b,&a,*c); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(a,&b,*c); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa nodului rdcin al arborelui i terge ultimul nivel de noduri (noduri frunz fr descendeni) dac acestea au ID-uri impare. void delNodFrunzaArb(NOD *cap) {

TEST #15 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=22; a%=+8; cout<<a;


2. int a,b=14; a=(++b)--; cout<<a;

R1:...... R2:......

3. int a=14,b=2;if((a>1)&&(b>=3)) a>>=b; else a<<=b; cout<<a;R3:...... 4. int a=14,b; b=(a&5)&(8^a); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[0]+5); cout<<a; R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(&c[3][2]-2)+**(&c[1]+1);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=**(*a+1)-*(a[0][1]+1); cout<<b; R7:........ 8. char *str="ABCDEFG"; str[4]=str[0]-str[0]+'A';str[5]=!str[4]; cout<<str; R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

bi
i=1

j =1

double

f_(double **a, double *b)

8 bj b a i.j a i.i k =1 k

TEST #16

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a-1; a-=2; *b-=3; c+=9; s++; ::d++; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=4,b=5,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=6;d=7; m[0]=fx(*c,&a,b); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(*c,&b,a); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia o adres a unui nod oarecare dintr-un arbore i ntoarce adresa nodului printe ce conine ID-ul maxim raportat la toate nodurile printe din ierarhia nodului preluat iniial (ID-urile din cadrul arborelui sunt generate aleator). NOD* radArb(NOD *nodX) {

TEST #17 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=25; a%=+8; cout<<a;


2. int a,b=15; a=(--b)++; cout<<a; 3. int a=23,b=1;if((a>1)&&(b>3)) a>>=b; else a<<=b; cout<<a; 4. int a=15,b; b=(a|5)&(a^2); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[5]-1); cout<<a;

R1:...... R2:...... R3:...... R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(&c[0][0]+2)+**(&c[3]-3);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=*(**(a+1)+1)+*a[1][2]-**a[1]; cout<<b; R7:........ 8. char *str="ABCDEFG"; str[5]=str[3]-str[0]+'B';str[6]=!(str[5]-str[3]); cout<<str; R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

i=1

10

j=1

double

f_(double **a, double *b)

bi bj
20 k=1

bk ai.j a i.i

TEST

#18

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a-2; a+=1; *b+=4; c-=2; s++; ::d++; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=5,b=6,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=7;d=8; m[0]=fx(a,c,b); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(b,&a,*c); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar avnd ID-urile nodurilor generate aleator: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa rdcinii arborelui i ntoarce adresa nodului cu ID-ul minim. NOD* maxID_Arb(NOD *cap) {

TEST #19 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=28; a%=+8; cout<<a;


2. int a,b=16; a=(++b)--; cout<<a;

R1:...... R2:......

3. int a=12,b=1;if((a>1)&&(b>=3)) a>>=b; else a<<=b; cout<<a; R3:...... 4. int a=16,b; b=(a-1)^(a&4); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[5]-3); cout<<a; R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=**(&c[1]-1)+*(&c[1][2]-1);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=*(**a+1)+*(a[1][2]-1)-**a[0]; cout<<b; R7:........ 8. char *str="ABCDEFG"; str[0]='D'-str[3]+str[1];str[4]=!str[4]; cout<<str; R8:............

II.S se implementeze o funcie care ntoarce valoarea rezultat:

i=1

j=1

20

double

f_(double **a, double *b)

bk
k =1 8

10

a j.j

k=1

1 a k.j ai.k

TEST #20

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a+5; a-=9; *b-=2; c+=3; s++; ::d--; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=6,b=7,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=8;d=9; m[0]=fx(*c,&b,a); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(b,c,a); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa nodului rdcin i realizeaz tergerea din memorie tuturor nodurilor al cror ID este par i n acelai timp nodul printe are ID-ul impar. Se presupune c alocrile de memoriei sau realizat cu funcia void* malloc(size_t). void dipArb(NOD *cap) {

TEST #21 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=31; a%=+8; cout<<a;


2. int a,b=17; a=(--b)++; cout<<a;

R1:...... R2:......

3. int a=9,b=1;if((a<22)&&(b>=3)) a>>=b; else a<<=b; cout<<a; R3:...... 4. int a=17,b; b=(a-5)&(a^!a); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[7]-4); cout<<a; R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(&c[0][0]+2);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=***(a+1)+*(a[1][0]+1); cout<<b; R7:........ 8. char *str="ABCDEFG"; str[1]='A'+str[3]-str[1]; str[4]=!str[4]; cout<<str; R8:...........

II.S se implementeze o funcie care ntoarce valoarea rezultat:

bi
i=1

j =1

double

f_(double **a, double *b)

a m.j
m=1 k=1

bk a i.j a i.i

TEST #22

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a+2; a-=3; *b-=5; c+=1; s++; ::d++; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=7,b=8,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=9;d=10; m[0]=fx(b,&a,*c); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(*c,&a,b); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID, nivel; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa capului arborelui, parcurge arborele i seteaz variabila nivel din cadrul fiecrui nod cu nivelul nodului din cadrul arborelui. Se consider c nodul rdcin este pe primul nivel. void setNivArb(NOD *cap) {

TEST #23 I. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:

1. int a=34; a%=+8; cout<<a;


2. int a,b=18; a=(++b)--; cout<<a;

R1:...... R2:......

3. int a=20,b=2;if((a>1)&&(b>=2)) a>>=b; else a<<=b; cout<<a;R3:...... 4. int a=18,b; b=(a-4)|(a^15); cout<<b; 5. int a,b[7]={11,13,15,17,19,21,23}; a=*(&b[6]-6); cout<<a; R4:...... R5:......

6. int a,c[4][3]={{11,13,15},{21,23,25},{31,33,35},{41,43,45}}; a=*(c[3]-1)+*(&c[0][1]-1);cout<<a; R6:....... 7. int a[2][3][2]={{{10,12},{13,15},{14,16}},{{50,52},{51,53},{54,56}}},b; b=***a+*(a[1][2]-1)+**(a[0]+1); cout<<b; R7:........ 8. char *str="ABCDEFG"; str[3]='G'-!(str[3]-str[1]);str[4]=!str[3]; cout<<str; R8:...........

II.S se implementeze o funcie care ntoarce valoarea rezultat:

bi
i=1

10

j =1

double

f_(double **a, double *b)

b j

bk

k=1

a m.k a i.i
m=1

TEST #24

I. Ce se afieaz n urma execuiei urmtoarelor linii de cod:


#include <stdio.h> #include <conio.h> int d; int fx(int a,int *b,int &c) { static int s; int d; d=a-1; a-=8; *b-=2; c+=3; s++; ::d++; printf("_s=%d _a=%d _b=%d _c=%d _d=%d\n",s,a,*b,c,::d); return a+*b+c+d; } int main(void) {int a=8,b=9,*c,m[2]; c=(int*)malloc(1*sizeof(int)); *c=10;d=11; m[0]=fx(*c,&a,b); printf("1a=%d 1b=%d 1c=%d 1d=%d m[0]=%d\n",a,b,*c,d,m[0]); m[1]=fx(a,&b,*c); printf("2a=%d 2b=%d 2c=%d 2d=%d m[1]=%d\n",a,b,*c,d,m[1]); getch(); free(c); return 0;} R1: _s=... R6: 1a=... R11:_s=... R16:2a=... R2: _a=... R7: 1b=... R12:_a=... R17:2b=... R3: _b=... R8: 1c=... R13:_b=... R18:2c=... R4: _c=... R9: 1d=... R14: _c=... R19:2d=... R5: _d=... R10:m[0]=... R15: _d=... R20:m[1]=...

Not: R1, R2, R3, R4, R5 reprezint valorile la primul apel al funciei, iar R11, R12, R13, R14, R15 reprezint valorile din cadrul funciei corespunztoare celui de al doilea apel al funciei

II. Se d structura nodurilor dintr-un arbore binar: typedef struct NOD{int ID; NOD *pSt, *pDr, *pAnt} NOD; S se scrie o funcie ce preia adresa nodului rdcin i ntoarce numrul total al nodurilor din cadrul arborelui. int cntNodArb(NOD *cap) {

TEST #25

A. Scriei ce se afieaz n urma execuiei urmtoarelor instruciuni (liniile sunt independente), iar n cazul
existenei unor erori s se semnalezeze erorile aprute n urma execuiei i sursa acestora:
1a. int a=22; a%=+2; printf(%d,a); 1b. int a,b=10; a=b++; printf(%d,a); 2 . int a=10; a>>=2;printf(%d,a); 3. int a=10,b,c,d; b=(a^10)&(a|11); c= a^10; d=a|2; 3a printf(%d,c);R3a:... 3b printf(%d,d); R3b:... 3c printf(%d,b); R3c:.... 4. int a[2],b[7]={12,23,34,45,56,67,78}; a[0]=*(&b[2]+1); a[1]=*b; 4a.printf(%d,a[0]); R4a:...... 4b.printf(%d,a[1]); R4b:...... R1a:...... R1b:...... R2a:......

5. int a[3],c[4][3]={{10,23,34},{11,22,13},{31,42,33},{14,21,31}}; a[0]=1+*(&c[0][1]+1); a[1]=**(&c[1]+1); a[2]=**c; 5a.printf(%d,a[0]); R5a:...... 5b.printf(%d,a[1]); R5b:...... 5c.printf(%d,a[2]); R5c:...... 6. char *str = "ABCDEF"; str[1] = str[1]+1-'C';str[3]=str[4]-(str[3]+1); printf(%s,str); R6:...

B. S se implementeze o funcie double f1(double


i care ntoarce valoarea expresiei:

**a, double *b) care preia matricea a i vectorul b

(1ai1)
i=1

j=1

aij

k =1

bk aijai1

TEST #26

S se scrie o funcie
double f1(int m, double **a, double **c, double *b)

care preia adresele matricilor Amxm, Cmxm i a vectorului bm .Funcia ntoarce: bk (1+a ki c ik )+ b 2 + i k i i k a ik c kj
j i

1. S se scrie o funcie
void f2(unsigned long x,unsigned short s1,unsigned short &c2)

care realizeaz urmtoarele operaii asupra valorii x: a) citete n variabila c2 primii 5 bii din octetul cel mai puin semnificativ (cccccxxx c reprezint biii care se citesc) b) scrie coninutul variabilei s1 (s1<64) n ultimii 6 bii ai octetului cel mai semnificativ (xxssssss s reprezint biii care se scriu) 3. S se scrie o funcie care preia adresa rdcinii unui arbore binar i terge toate nodurile frunz intiiale. S se scrie structura utilizat pentru nodurile arborelui.

BIBLIOGRAFIE
http://www.unixinside.org/papers/C++-Book/ http://codelite.org/Main/ReadMore