Sunteți pe pagina 1din 125

Instruciunea de atribuire. Operatori aritmetici INSTRUCIUNEA DE ATRIBUIRE. OPERATORI ARITMETICI 1.

SCOPUL LUCRRII n aceast lucrare se vor studia urmtoarele: -Funcii de citire / scriere: -Instruciunea de atribuire -Operatori aritmetici 2. BREVIAR TEORETIC

2.1. Funcii de citire / scriere Orice program are anumite date de intrare, pe care le prelucreaz i n final afieaz rezultatul. Datele de intrare, ct i rezultatele pariale i finale, sunt stocate (memorate) n variabile. Datele de intrare ale programului pot fi: - citite de la tastatur (tastatura este principala surs de date de intrare) - iniializate direct prin instruciunea de atribuire - iniializate cu numere generate aleator - citite dintr-un fiier de pe disc - recepionate dintr-un port de intrare al calculatorului (de exemplu de pe portul serial sau paralel al PC-ului) Astfel, funcia scanf() este folosit pentru a citi date de la tastatur sub controlul unui format de citire. Datele citite sunt memorate n variabilele specificate prin argumentele funciei. Modul de utilizare tipic: scanf(irul de formate, adresele variabilelor n care se citesc datele); Formatele de citire cele mai folosite sunt: %d pentru tipul de date int %c pentru tipul de date char %lf pentru tipul de date double (Atenie: este lf i nu 1f) Exemplu: Pentru a citi un numr ntreg de la tastatur pe care s-l memorm n variabila numr, se folosete secvena de program: int numar; scanf("%d,&numar);

Instruciunea de atribuire. Operatori aritmetici

Exemplu: Pentru a citi de la tastatur, folosind o singur instruciune scanf(), 4 valori numerice, i anume: dou numere ntregi, un caracter i un numr real, se folosete secvena de program: int i1,i2; char c; double r; scanf(%d%d%c%lf,&i1,&i2,&c,&r); Datele de citit, se tasteaz separate prin caracterele: spaiu (blank) sau TAB sau ENTER. Pentru a citi date de tip caracter se poate folosi i instruciunea getch(). Aceast funcie returneaz codul ASCII al tastei apsate. Exemplu: int c=getch(); Folosind funcia getch(), caracterului tastat nu i se face ecou pe ecran. Pentru a i se face ecou, se folosete o variant a acestei funcii, i anume funcia getche(). Att funcia getch(), ct i funcia scanf(), ateapt pn cnd utilizatorul tasteaz datele. Pentru a detecta dac s-a apsat sau nu o tast, fr a atepta apsarea efectiv, se folosete funcia kbhit(). Aceasta funcie nu are nici un parametru. Ea ntoarce ca rezultat, valoarea 0, dac nu a fost apsat nici o tast, i o valoare diferit de 0, dac a fost apsat o tast. Funcia kbhit(), examineaz bufferul tastaturii n care sunt automat stocate caracterele tastate. Dac nu este nici un caracter prezent, ntoarce drept rezultat valoarea 0. Funcia kbhit() nu ateapt apsarea unei taste, programul continund cu urmtoarea instruciune din program. Exemplu: int este=kbhit(); Pentru a afia date pe monitor, n modul text, se folosete funcia printf(). Ea afieaz texte i eventual, coninutul unor variabile, sub controlul unor formate de afiare, ncepnd de la poziia curent a cursorului. n cazul textului, pot aprea anumite caractere speciale, ce nu sunt afiate ca atare, denumite secvene escape. Caractere speciale uzual folosite n textul de afiat sunt: \n - are rolul de a muta cursorul la nceputul liniei urmtoare \t - are rolul de a avansa cursorul cu un TAB.

Instruciunea de atribuire. Operatori aritmetici \\ - afieaz caracterul \ \ - afieaz caracterul

Exemplu: printf("Numele directorului curent este: C:\\TURBO"); Pentru a afia, pe lng texte, i coninutul unor variabile, sintaxa, n cazul general, este urmtoarea: printf("Sirul de texte si formate",lista de variabile); Cele mai utilizate formate de afiare, sunt urmtoarele: %d pentru variabile de tipul int %c pentru variabile de tipul char %lf pentru variabile de tipul double. (Atenie: este lf i nu 1f) %f pentru variabile de tipul float Exemplu: printf("x=%d,y=%d",x,y); 2.2. Instruciunea de atribuire Valoarea depozitat ntr-o locaie de memorie, poate fi schimbat printr-o operaie de atribuire. Ca operator de atribuire, n limbajul C, se folosete semnul egal. Sintaxa operaiei de atribuire este urmtoarea: nume_variabil = expresie ; Exemplu: x=2.5; Se citete: x primete valoarea 2.5. n urma acestei operaii, n variabila x se memoreaz valoarea 2.5 . Variabila x trebuie declarat de tipul real (float sau double). Exemplu: x=x+1; Se citete: x primete vechea valoare a lui x crescut cu 1. Aceast operaie de cretere a coninutului unei variabile cu o unitate, se cheam incrementare. Incrementarea fiind o operaie des ntlnit n programe, n limbajul C exist un operator special ce o realizeaz: operatorul ++ . Acesta este un operator unar i el poate fi plasat fie la stnga, fie la dreapta unui operand. Aciunea lui va fi diferit ns, depinznd de poziia lui (n stnga sau n dreapta operandului).

10

Instruciunea de atribuire. Operatori aritmetici

Exemplu: int x,y; x=7; y=x++; Operatorul ++, n acest exemplu, este plasat la dreapta unui operand: nti se va face operaia de atribuire (y=x) i apoi se va face incrementarea variabilei x (x=x+1). Astfel, n final se va obine y=7 i x=8. Exemplu: int x,y; x=7; y=++x; Operatorul ++, n acest exemplu, este plasat la stnga unui operand: nti se va face incrementarea variabilei x (x=x+1) i apoi se va face operaia de atribuire (y=x). Astfel, n final se va obine y=8 i x=8. Pentru decrementarea unei variabile (scderea valorii variabilei cu o unitate ), exist n limbajul C un operator special: operatorul -- . Acest operator se folosete la fel ca operatorul de incrementare. 2.3 Operatori aritmetici Sunt 5 operatori aritmetici de baz, i anume: + adunare scdere * nmulire / mprire % restul mpririi ( modulo) Operatorul de mprire / , n cazul numerelor ntregi, calculeaz trunchind rezultatul exact. Astfel 7 / 2 este evaluat ca 3 si nu ca 3.5 Toi aceti operatori sunt operatori binari ( adic cu operanzi i n stnga i n dreapta). Operatorul % poate avea drept operanzi doar numere ntregi. Operatorii aritmetici, au prioritile cunoscute de la aritmetic. Astfel, n expresia a+b*c nti se calculeaz produsul i apoi suma. Observaie important: Deoarece limbajul C are foarte muli operatori, a cror prioritate nu mai este chiar aa de evident ca la cei aritmetici, se recomand, att pentru claritatea programului, ct i pentru evitarea

Instruciunea de atribuire. Operatori aritmetici

11

greelilor, folosirea parantezelor. Totdeauna operaiile cuprinse ntre paranteze se execut primele. 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 Sa se afieze urmtorul text, citat din Biblie: "Cautati mai intai Imparatia lui Dumnezeu !" Se vor afia inclusiv ghilimelele. Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { clrscr(); printf("\"Cautati mai intai Imparatia lui Dumnezeu !\""); getch(); } Programul nr. 2 S se comute coninutul a dou variabile a i b, ntre ele. Algoritm: -se salveaz n variabila auxiliar aux, variabila a -se copiaz n a variabila b -se copiaz n b variabila aux Greeli frecvente: -Nu se folosete o variabila auxiliar, ci se face comutarea direct: a=b i apoi b=a. Sursa programului: #include <stdio.h> #include <conio.h> void main() { int a, b, aux; clrscr(); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); aux=a; a=b;

12

Instruciunea de atribuire. Operatori aritmetici

b=aux; printf("Dupa comutare: a=%d, b=%d",a,b); getch(); } Programul nr. 3 Calculul mediei aritmetice a 3 numere ntregi, citite de la tastatur. Algoritm: - se calculeaz suma numerelor, i rezultatul se mparte la 3. Greeli frecvente: - se declar variabila medie, de tip ntreg - se calculeaz medie=(a+b+c)/3 , ceea ce este greit cci rezultatul se trunchiaz la ntreg. Sursa programului: #include <stdio.h> #include <conio.h> void main() { int a,b,c; double medie; clrscr(); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); medie=(a+b+c)/3.0; printf("medie=%lf",medie); getch(); } Programul nr. 4 Se citesc trei numere ntregi a, b i c de la tastatur, coeficieni ai polinomului de gradul doi P(x)=ax2+bx+c. S se calculeze i afieze valoarea polinomului pentru o valoare particular ntreag x, citit de la tastatur. Sursa programului: # include <conio.h> # include <stdio.h> void main (void) { int a,b,c,x;

Instruciunea de atribuire. Operatori aritmetici

13

int P; //presupunem ca nu se depaseste capacitatea de stocare a //tipului int printf("Tastati 3 numere intregi, a, b si c: "); scanf("%d%d%d",&a,&b,&c); printf("x="); scanf("%d",&x); P=a*x*x+b*x+c; printf ("P=%d",P); } Programul nr. 5 Se citete un numr ntreg de la tastatur. Acest numr are semnificaia unui interval de secunde. S se afieze intervalul n ore, minute i secunde. Exemplu: Dac numrul citit este 61, trebuie s se afieze: Nr. Ore = 0; Nr. Minute = 1; Nr. Secunde = 1 Sursa programului: #include <stdio.h> void main(void) { int N; // intervalul in secunde citit int nrOre; int nrMin; int nrSec; printf(Tastati durata in secunde a intervalului: ); scanf(%d,&N); nrOre = N/3600; nrMin = (N % 3600)/60; nrSec = N - nrOre * 3600 - nrMin * 60; printf(\nNr. Ore=%d,nrOre); printf(\nNr. Minute=%d,nrMin); printf(\nNr. Secunde=%d,nrSec); } Programul nr. 6 Se citete un numr ntreg, pozitiv, de la tastatur. S se calculeze cifra unitilor, cifra zecilor i cifra sutelor. Algoritm: - cifra unitilor este restul mpririi numrului la 10 - pentru calcul cifrei zecilor, se mparte numrul iniial la 10. n noul numr obinut, vechea cifr a zecilor a devenit cifra unitilor. Aceasta se afl ca restul mpririi noului numr la 10.

14

Instruciunea de atribuire. Operatori aritmetici

- cifra sutelor se obine dupa acelai algoritm ca i cifra zecilor. Greeli frecvente: - se mparte direct numrul la 10, pentru a afla cifra zecilor - se imparte direct numrul la 100, pentru a afla cifra sutelor Sursa programului: #include <stdio.h> #include <conio.h> void main() { int nr; int u,z,s;//unitati, zeci, sute clrscr(); printf("nr="); scanf("%d",&nr); //cifra unitatilor: u=nr%10; //calcul cifra zecilor: nr=nr/10; z=nr%10; //cifra sutelor: nr=nr/10; s=nr%10; //afisare rezultate: printf("u=%d, z=%d, s=%d",u,z,s); getch(); } Programul nr. 7 Se citete un numr natural de la tastatur, care const din cel puin dou cifre. S se calculeze noul numr obinut prin comutarea cifrei unitilor cu cifra zecilor. Exemplu: Pentru numrul iniial 4532, dup comutare se obine 4523. Sursa programului: # include <stdio.h> void main (void) { int nr; printf("Dati un numar natural >= 10: "); scanf("%d",&nr); int u;//cifra unitatilor

Instruciunea de atribuire. Operatori aritmetici

15

u=nr%10; int z;//cifra zecilor z=(nr/10)%10; int ramas;//numarul ramas prin eliminarea cifrei zecilor si a cifrei //unitatilor ramas=nr/100; //Dupa comutare, numarul devine: nr=ramas*100+10*u+z; printf("Dupa comutare, nr=%d",nr); } Programul nr. 8 Se citesc doua numere naturale a si b, capetele unui interval inchis. Sa se genereze un numar aleatoriu in intervalul [a, b]. Sa se afiseze acest numar. Sursa programului: #include<stdio.h> #include<stdlib.h> void main(void) { int a,b,nr; printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); randomize(); nr=a+random(b-a+1); printf("Numar=%d",nr); } 4. PROBLEME PROPUSE 1.S se afieze un dreptunghi ale crui linii sunt formate din stelue (caracterul *) 2. Se citete un numr natural care are cel puin trei cifre. S se calculeze noul numr obinut prin comutarea cifrei unitilor cu cifra sutelor. 3. S se genereze i afieze trei numere ntregi, aleatoare n intervalul nchis [10,100].

16

Instruciuni de decizie INSTRUCIUNI DE DECIZIE 1. SCOPUL LUCRRII n aceast lucrare se vor studia urmtoarele instruciuni: -Instruciunea if cu o singur alternativ -Instruciunea if - else cu dou alternative -Instruciunea if - else cu mai multe alternative -Instruciunea switch 2. BREVIAR TEORETIC

2.1. Instruciunea if cu o singur alternativ Sintaxa: (o singur instruciune executabil) if(condiie_testat) instruciune; Sintaxa: (o secven de instruciuni executabile) if (condiie_testat){ <secven de instruciuni> } Exemple: if(nrOre>24)nrOre=24; if(nrSecunde>=60){ nrSecunde=0; nrMinute++; } 2.2. Instruciunea if-else cu dou alternative Sintaxa: (o singur instruciune n fiecare clauza) if(conditie_testata) instruciune1; else instruciune2; Exemplu: if(nrMinute>=60){ nrMinute=0; nrOre++;} else nrMinute++; 2.3. Instruciunea if-else cu mai multe alternative Sintaxa: if(condiie_testat_1){ <grup 1 de instruciuni> }

Instruciuni de decizie else if(condiie_testat_2){ <grup 2 de instruciuni> } ... else if(condiie_testat_n){ <grup n de instruciuni> } else{ <grup n+1 de instruciuni> } Observaie: ultimul else este opional (poate s nu fie prezent). Exemplu: if(codOperaie=='+')z=x+y; else if(codOperaie=='-')z=x-y; else if(codOperaie=='*')z=x*y; else if( (codOperaie=='/')&&(y!=0) )z=x/y;

17

2.4. Instruciunea switch Aceast instruciune este o form special de construcie decizional cu mai multe alternative. Ea permite s se examineze diverse valori ale unei expresii de tipul int i n funcie de aceast valoare sa se selecteze pentru execuie un anumit grup de instruciuni. Sintaxa: switch(expresie){ case valoarea_1: <una sau mai multe instruciuni> break; case valoarea_2: <una sau mai multe instruciuni> break; ... case valoarea_n: <una sau mai multe instruciuni> break; default: <una sau mai multe instruciuni> break; }//end switch Ramura default din instruciunea switch este opional. Exemplu: switch(poziiaBareiLuminoase){ case 0: f0( ); break; case 1: f1( ); break; case 2: f2( ); break;

18

Instruciuni de decizie case 3: stop=1; break; } 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare.

Programul nr. 1 Se citesc a, b, c - numere reale, coeficienii ecuaiei de gradul doi. S se calculeze i afieze numrul de rdacini reale distincte ale ecuiei. Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { clrscr(); double a,b,c,delta; printf("a="); scanf("%lf",&a); printf("b="); scanf("%lf",&b); printf("c="); scanf("%lf",&c); delta=b*b-4*a*c; if(delta>0)printf("Doua redacini reale si distincte"); else if(delta==0)printf("Doua radacini reale si egale"); else printf("Radacini complexe"); getch(); } Programul nr. 2 S se calculeze i afieze maximul dintre 3 numere ntregi, a,b,c, citite de la tastatur. Algoritm: - se iniializeaz maximul cu primul numr, a - se compar maximul cu b. Dac b este mai mare, se scrie n variabila maxim , valoarea lui b. - se compar maximul cu c, la fel cum s-a procedat i pentru b. Sursa programului: #include <stdio.h> #include <conio.h> void main() {

Instruciuni de decizie int a,b,c,max; clrscr(); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); max=a; if(b>max)max=b; if(c>max)max=c; printf("max=%d",max); getch(); }

19

Programul nr. 3 Se citesc 4 numere ntregi de la tastatur. S se afieze dac cele 4 numere formeaz o progresie aritmetic. Algoritm: - se calculeaz raia ca fiind diferena primilor doi termeni - se compar aceast raie cu distanele (diferenele) dintre urmatorii termeni. Sursa programului: #include <stdio.h> #include <conio.h> void main() { int a,b,c,d; int ratia; clrscr(); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); printf("d="); scanf("%d",&d); ratia=b-a; if((c-b==ratia)&&(d-c==ratia)) printf("Sunt in progresie aritmetica."); else printf("Nu sunt in progresie aritmetica."); getch(); }

20

Instruciuni de decizie

Programul nr. 4 Se citesc 3 numere ntregi a, b, c, de la tastatur. Sa se afieze dac cele 3 numere sunt distincte sau nu. Algoritm: - se compar a cu b, a cu c i b cu c. Dac toi sunt diferii, numerele sunt distincte. Greeli frecvente: - nu se fac toate cele 3 comparaii Sursa programului: #include <stdio.h> #include <conio.h> void main() { int a,b,c; clrscr(); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); if((a!=b)&&(a!=c)&&(b!=c))printf("Sunt distincte."); else printf("Nu sunt distincte."); getch(); } Programul nr. 5 Se citete un numr real x de la tastatur. S se calculeze i afieze valoarea expresiei E(x), definit astfel: E(x)=|x-5|+2 dac x<0 E(x)=1 dac x=0 E(x)=x-1 dac x>0 Algoritm: -aplicaie foarte simpl a instruciunii if cu mai multe alternative Greeli frecvente: -notarea cu E(x) a unei variabile Sursa programului: #include <stdio.h> #include <conio.h> #include <math.h> //pentru functia abs() void main() { double x,E;

Instruciuni de decizie clrscr(); printf("x="); scanf("%lf",&x); if(x<0)E=abs(x-5)+2; else if(x==0)E=1; else E=x-1; printf("E=%lf",E); getch(); }

21

Programul nr. 6 Se citesc de la tastatur trei numere ntregi a, b, c. S se calculeze i afieze cte numere pare au fost introduse, i suma acestor numere pare. Algoritm: -se iniializeaz contor de numere pare cu 0, i suma cu 0 -dac a este par, se incrementeaz contor i se adaug a la suma -daca b este par, se incrementeaz contor i se adaug b la suma -daca c este par, se incrementeaz contor i se adaug c la suma Greeli frecvente: -nu se face iniializarea contorului -nu se face iniializarea sumei Sursa programului: #include <stdio.h> #include <conio.h> void main() { int a,b,c,contor,suma; clrscr(); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); printf("c="); scanf("%d",&c); contor=0; suma=0; if(a%2==0){ contor++; suma=suma+a;} if(b%2==0){ contor++; suma=suma+b;}

22

Instruciuni de decizie

if(c%2==0){ contor++; suma=suma+c;} if(contor==0)printf("Nu este nici un numar par."); else printf("Sunt %d nr. pare. Suma lor este: %d",contor,suma); getch(); } Programul nr. 7 S se afieze codul ASCII al unei taste apsate. Se poate apsa o tast normal ( exemplu: tasta A ) sau o tast special ( Exemplu: tasta F1 ). -se citete codul tastei cu funcia de bibliotec getch() -dac acest cod este 0, este o tast special, i al doilea cod al acestei taste se obine apelnd din nou funcia getch() Sursa programului: #include <stdio.h> #include <conio.h> void main() { int c; clrscr(); printf("Apasati o tasta, normala sau speciala: "); c=getch(); if(c!=0)printf("\nTasta normala, are codul ASCII: %d",c); else{ //este tasta speciala. c=getch(); printf("\nTasta speciala, are codul: 0 si %d",c); } getch(); } Programul nr. 8 Se citete de la tastatur un numr natural ntre 1 i 12, care reprezint numrul unei luni din an. S se scrie numele lunii corespunztoare numrului citit. Exemplu: Daca numrul citit este 2, se va afia: FEBRUARIE

Instruciuni de decizie Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { int nr; clrscr(); printf("nr="); scanf("%d",&nr); switch(nr){ case 1: printf("IANUARIE"); break; case 2: printf("FEBRUARIE"); break; case 3: printf("MARTIE"); break; case 4: printf("APRILIE"); break; case 5: printf("MAI"); break; case 6: printf("IUNIE"); break; case 7: printf("IULIE"); break; case 8: printf("AUGUST"); break; case 9: printf("SEPTEMBRIE"); break; case 10: printf("OCTOMBRIE"); break;

23

24

Instruciuni de decizie

case 11: printf("NOIEMBRIE"); break; case 12: printf("DECEMBRIE"); break; }//end switch } Programul nr. 9 Se citete de la tastatur un numr natural de 3 cifre (cuprins ntre 100 i 999 ). S se calculeze i afieze, care este cel mai mare numr ce se obine rearanjnd corespunztor cifrele numrului citit. Exemplu: dac se citete N=172, numrul maxim ce se obine prin rearanjarea cifrelor, este 721. Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { clrscr(); int nr; int s,z,u;//sute, zeci, unitati printf("Numar="); scanf("%d",&nr); u=nr%10; z=(nr/10)%10; s=nr/100; //Ordonam cele 3 cifre, descrescator (s,z,u): //(algoritm sortare prin interschimbare) int aux; if(s<z){//le interschimbam: aux=s; s=z; z=aux;} if(s<u){ aux=s; s=u; u=aux;} if(z<u){ aux=z;

Instruciuni de decizie z=u; u=aux;} //Noul numar (cel maxim) este: nr=100*s+10*z+u; printf("max=%d",nr); getch();
}

25

4. PROBLEME PROPUSE 1. Se citesc de la tastatur trei numere ntregi a, b, c. S se calculeze i afieze produsul numerelor pare introduse. 2. Se citesc patru numere ntregi de la tastatur. S se afieze dac cele 4 numere pot fi lungimile laturilor unui ptrat sau nu. 3. Se citesc trei numere ntregi a, b, c, de la tastatur. Pot fi lungimile laturilor unui triunghi oarecare? 4. Se citesc trei numere ntregi a, b, c, de la tastatur. Pot fi lungimile laturilor unui triunghi dreptunghic? 5. Se citesc trei numere ntregi a, b, c, de la tastatur. Pot fi lungimile laturilor unui triunghi isoscel? 6. Se citesc de la tastatur dou numere ntregi x i y. S se afieze dac acestea sunt soluii pentru ecuaia 5x+7y=19. 7. Se citete un numr natural de la tastatur (valoarea maxim ce se poate tasta este valoarea maxim pentru tipul de date int: 32767). S se calculeze i afieze cte cifre conine. Se va folosi instruciunea if multiplu. 8. Se citete un caracter de la tastatur. S se afieze dac este vocal sau nu. 9. Se citete de la tastatur un numr natural cuprins ntre 1 i 365, ce reprezint numrul unei zile din an. S se calculeze i afieze luna din an, din care face parte ziua respectiv. Se presupune c luna februarie are 28 de zile. Exemplu: dac numrul tastat este 77, se va afia: Martie. 10. S se rezolve ecuaia ax+b=0, unde a i b sunt dou numere reale care se citesc de la tastatur. 11. Ce numr natural cuprins ntre 1 i 3 trebuie adugat la un numr natural x, citit de la tastatur, astfel nct rezultatul sa fie divizibil cu 3 ? 12. Se citesc 4 numere ntregi a, b, c i d, de la tastatur. S se afieze dac cele 4 numere sunt n ordine strict cresctoare.

26

Instruciuni de ciclare INSTRUCIUNI DE CICLARE

1. SCOPUL LUCRRII n aceast lucrare se vor studia instruciuni de ciclare for, while si dowhile. 2. BREVIAR TEORETIC 2.1. Instruciunea for Sintaxa: for(<expr1: iniializarea variabilelor de control ale ciclului>; <expr2: testul de continuare a ciclului>; <expr3: actualizarea variabilelor de control ale ciclului>) { <grup de instruciuni> } Observaii: - NAINTE de prima iteraie se evalueaz expr1. - DUP fiecare iteraie pe bucl, este evaluat expr3. - Toate cele 3 expresii sunt opionale. - Repetarea la infinit a unui grup de instruciuni se face astfel: for(;;){ <grup instruciuni> } Exemplu: for(i=0;i<=10;i++) printf("\nPatratul lui %d este %d",i,i*i); 2.2. Instruciunea do-while Sintaxa: do{ <grup de instruciuni> }while(expresie_condiie); Descriere: Grupul de instruciuni este executat repetitiv, ct timp valoarea expresiei rmne diferit de zero (rmne adevrat). Expresia de test este evaluat DUP fiecare execuie a grupului de instruciuni. Exemplu: do{ printf("\nTastati un numar intreg strict pozitiv: ");

Instruciuni de ciclare scanf("%d",&nr); }while(nr<=0);

27

2.3. Instruciunea while Sintaxa: while(expresie_condiie){ <grup de instruciuni> }//end while Descriere: Grupul de instruciuni se execut repetat, ct timp valoarea expresiei rmne diferit de 0 (rmne adevrat). Expresia de test este evaluat NAINTE de fiecare execuie a grupului de instruciuni. Exemplu: stop=0; while(!stop){ c=getch( ); if(c=='q')stop=1; else printf("\Codul Ascii al caracterului %c este %d",c,c); } 2.4. Instruciunea continue Sintaxa: continue; Descriere: Determin, n iteraia curent, saltul la sfritul secvenei de instruciuni ce formeaz corpul unui ciclu (for, do-while, while) i reluarea ciclului cu iteraia urmtoare (daca mai sunt iteraii de fcut). Exemplu: for(i=1;i<=10;i++){ printf("\nTastati un numar intreg: "); scanf("%d",&nr); if(nr==0)continue; printf("\nInversul numarului este %.5lf",1.0/nr); } 2.5. Instruciunea break Sintaxa: break; Descriere:

28

Instruciuni de ciclare

Realizeaz ieirea forat n afara ciclului curent ( for, do-while, while). Exemplu: for(;;){ c=getch( ); if(c=='q')break; else printf("\Codul Ascii al caracterului %c este %d",c,c); } 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 Se citete un numr natural N. S se afieze N stelue, pe vertical. Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { clrscr(); int i,N; printf("N="); scanf("%d",&N); for(i=1;i<=N;i++) printf("*\n"); getch(); } Programul nr. 2 S se calculeze i s se afieze suma a N numere citite de la tastatur. (N este cunoscut). Sursa programului: # include <stdio.h> # include <conio.h> #define N 20 void main(void) { int nr; //numarul curent citit int i; int suma;

Instruciuni de ciclare clrscr(); suma = 0; for(i=1;i<=N;i++) { printf(Tastati un numar intreg: ); scanf(%d,&nr); suma = suma + nr; } printf(Suma calculata este %d,suma); getch(); }

29

Programul nr. 3 S se calculeze i afieze maximul a N numere ntregi citite de la tastatur. Sursa programului: #include <stdio.h> #include <conio.h> void main(void) { int i; int nrCrt;//numarul curent citit int maxim; int N; //numarul de numere clrscr(); printf("Introduceti numarul total de numere: "); scanf("%d",&N); //Se initializeaza maximul, cu primul numar citit: printf(Numarul 1: ); scanf(%d,&maxim); //Se citesc restul numerelor. Daca numarul curent citit, // este mai mare decat maxim, se schimba variabila maxim: for(i=2;i<=N;i++){ printf("Numarul %d: ",i); scanf("%d",&nrCrt); if(nrCrt > maxim)maxim=nrCrt; } printf("Maximul dintre numerele tastate este %d .",maxim); getch(); }

30

Instruciuni de ciclare

Programul nr. 4 Se citete un numr natural de la tastatur. S se stabileasc dac este numr prim sau nu. Sursa programului: #include <stdio.h> #include <conio.h> #include <math.h> void main(void) { int a,i; int estePrim;// Variabila semafor. Ia valoarea 1, daca a este prim. //Ia valoarea 0, daca a nu este prim. clrscr(); printf(a=); scanf(%d,&a); //Un numar este prim, daca are ca divizori, // doar pe 1 si pe el insusi. estePrim=1;// Initializare. for(i=2;i<=sqrt(a);i++) if(a%i==0){ estePrim=0; break;} if(estePrim==1)printf(Este prim.); else printf(Nu este prim.); getch(); } Programul nr. 5 S se realizeze un program care scoate ca rezultat numrul de numere naturale de trei cifre care au suma cifrelor mai mare dect 10. Sursa programului: #include <stdio.h> #include <conio.h> void main(void) { int N; int s;//cifra sutelor numarului N int z;//cifra zecilor numarului N int u;//cifra unitatilor numarului N int nr=0;//nr. de numere naturale care indeplineste conditia clrscr();

Instruciuni de ciclare for(N=100;N<=999;N++){ s=N/100; z=(N-s*100)/10; u=N%10; if((s+z+u)>10){ nr++; printf("%d ",N); //afisez si numerele care indeplinesc //conditia }// if } //for printf("\n%d",nr); //afisez numarul de numere care indeplinesc //conditia getch(); }// main

31

Programul nr. 6 Se citesc dou numere naturale a i b. S se afieze dac sunt prime ntre ele sau nu. Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { clrscr(); int a,b; printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); //Daca nu sunt in ordine crescatoare le interschimbam: int aux; if(a>b){ aux=a; a=b; b=aux;} int i; int sunt=1;//presupunem ca sunt for(i=2;i<=a;i++) if((a%i==0)&&(b%i==0)){//au un divizor comun

32

Instruciuni de ciclare

sunt=0; break;} if(sunt==1)printf("Sunt prime intre ele"); else printf("Nu sunt prime intre ele"); getch(); } Programul nr. 7 S se rezolve n numere naturale ecuaia: 2x + 3y + 4z = 71 . Sursa programului: # include <stdio.h> # include <conio.h> void main(void) { int x,y,z; clrscr(); //Se genereaza toate tripletele x, y, z , posibile a fi solutie: for(x=0;x<=71/2;x++) for(y=0;y<=71/3;y++) for(z=0;z<=71/4;z++) if(2*x+3*y+4*z==71) printf(x=%d, y=%d, z=%d\n,x,y,z); getch(); } Programul nr. 8 Se repet citirea unui numr ntreg de la tastatur, pn cnd numrul introdus se gsete n intervalul [ 7, 20 ]. Sursa programului: #include<stdio.h> #include<conio.h> void main(void) { int nr; clrscr(); for(;;){ printf(\nTastati un numar:); scanf(%d,&nr); if((nr>=7)&&(nr<=20))break;

Instruciuni de ciclare } printf(\n S-a tastat %d,nr); getch(); }//main

33

Programul nr. 9 S se calculeze numrul de cifre al unui numr ntreg citit de la tastatur. Sursa programului: #include <stdio.h> #include <conio.h> void main(void) { long int n; int nrCifre; clrscr(); printf("n="); scanf("%ld",&n); nrCifre=0;//initializare //Numarul de cifre se calculeaza impartind repetat numarul la // valoarea 10, pana cand numarul devine 0. for(;;){ n=n/10; nrCifre++; if(n==0)break; } printf("Numarul are %d cifre. ",nrCifre); getch(); } Programul nr. 10 Folosind instruciunea do..while, s se scrie un program n care se execut urmtorul meniu de comenzi: 1. desen triunghi 2. desen ptrat 3. ieire Figurile geometrice se deseneaz n modul text, folosind caracterul stelu (asterisc).

34

Instruciuni de ciclare

Sursa programului: # include <stdio.h> # include <conio.h> void main(void) { int stop;/*variabila semafor care ne va spune cand este cazul sa nu se mai execute acest meniu*/ int nrOptiune; stop=0; do{ //afisare meniu clrscr(); printf("1. Desen triunghi\n"); printf("2. Desen patrat\n); printf("3. Iesire\n"); printf("Introduceti nr. optiunii: "); //se citeste nr.optiunii si apoi se executa comanda: nrOptiune=getch(); //executia meniului: switch(nrOptiune) { case 1: clrscr(); printf( *\n); printf( * *\n); printf(*****); getch(); break; case 2: clrscr(); printf(****\n); printf(* *\n); printf(* *\n); printf(****); getch(); break; case 3: stop=1; break; }//switch }while(stop==0); }//end main

Instruciuni de ciclare

35

Programul nr. 11 Folosind instruciunea do...while, s se transpun n limbajul C urmtoarea secven de program, scris n pseudocod: se repet se repet se citete numrul ntreg a ct timp a este n afara intervalului [1 , 10] se citete numrul ntreg b ct timp b<a . Sursa programului: #include <conio.h> # include <stdio.h> void main(void) { int a,b; clrscr(); do{ do{ printf("a=");scanf("%d",&a); }while((a<1)||(a>10)); printf("b=");scanf("%d",&b); }while(b<a); printf("a=%d, b=%d",a,b); getch(); } Programul nr. 12 S se calculeze cel mai mare divizor comun a doua numere naturale a i b, folosind urmtorul algoritm: ct timp ab repet dac a>b atunci a a-b altfel b b-a cmmdc a Sursa programului: #include <stdio.h> #include conio.h> void main() { int a; int b;

36

Instruciuni de ciclare

clrscr(); printf("a=");scanf("%d",&a); printf("b=");scanf("%d",&b); while(a!=b) if(a>b)a=a-b; else b=b-a; printf("cmmdc=%d",a); getch(); } 4. PROBLEME PROPUSE 1. S se implementeze, folosind instruciunea for, urmtoarea secven de instruciuni, descris n pseudocod: se repet se repet se citete a pn cnd a > 0 se citete b ct timp b < a 2. Se citete un numr natural a. S se calculeze i afieze primul numr prim mai mare dect a. 3. S se realizeze un program care realizeaz c.m.m.d.c. a trei numere. 4. Se citesc dou numere N1 i N2, naturale (N2 > N1). Cte numere prime sunt n intervalul [N1, N2] ? 5. S se implementeze jocul afl numrul. Operatorul alege un numr ntre 1 i 1000. Calculatorul trebuie s-l determine din ct mai puine ncercri. Calculatorul propune un numr. Operatorul i rspunde: Este prea mare, este prea mic, sau egal. 6. S se arate c fracia (65n+3)/(39n+2) este ireductibil pentru orice numr natural n cuprins ntre 1 i 500. 7. Ce semne ( + sau -, deci adunare sau scdere) se pun n locul semnului ? pentru ca expresia urmtoare sa fie adevrata? 5 ? 7 ? 2 ? 20 = 30

Vectori (I) VECTORI (I)

37

1. SCOPUL LUCRRII n aceast lucrare se vor studia tablouri unidimensionale (vectori). 2. BREVIAR TEORETIC Un tablou reprezint o colecie de date de acelai tip. Tablourile unidimensionale sunt denumite i vectori. La declararea unui tablou se specific numrul de elemente ale fiecrei dimensiuni, incluznd fiecare dintre aceste numere ntre paranteze drepte. Indexul inferior al fiecrei dimensiuni este 0. Sintaxa pentru declararea unui vector este urmtoarea: tipul_datelor nume_vector[Numrul_total_de_elemente]; Exemplu: tab -vector ce conine 100 de numere reale: double tab[100]; Elementele tabloului se acceseaz indexnd corespunztor numele tabloului. Exemplu: tab[10]=tab[10]+1; Un vector poate fi iniializat nc din faza de declarare, ca n exemplul urmator: int x[4]={-1, 2, 0, 56}; 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. S se calculeze maximul din vector. Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void) { int a[N]; int i; clrscr(); for(i=0;i<N;i++){

38

Vectori (I)

printf("a[%d]=",i); scanf("%d",&a[i]);} int max=a[0]; for(i=1;i<N;i++) if(a[i]>max)max=a[i]; printf("maximul = %d",max); getch(); } Programul nr. 2 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. S se calculeze cate numere pare sunt n vector. Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void) { int a[N]; int i; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} int contor=0; for(i=0;i<N;i++) if(a[i]%2==0)contor++; printf("Numarul de numere pare=%d",contor); getch(); } Programul nr. 3 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. S se memoreze toate numerele pare din vectorul a ntr-un vector b. Sa se afieze vectorul b. Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void)

Vectori (I) { int a[N],b[N]; int i; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} int j=0;//index in vector b for(i=0;i<N;i++) if(a[i]%2==0){ b[j]=a[i]; j++; } //afisare vector b: if(j==0)printf("Nu sunt numere pare in vectorul a"); else for(i=0;i<j;i++) printf("%d\n",b[i]); getch(); }

39

Programul nr. 4 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. S se afieze dac toate numerele introduse sunt egale ntre ele. Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void) { int a[N]; int i; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} int suntEgale=1; //presupunem ca sunt toate egale //Le comparam pe toate cu primul element: for(i=1;i<N;i++) if(a[i]!=a[0]){

40

Vectori (I)

suntEgale=0; break; } if(suntEgale)printf("Sunt toate egale"); else printf("Nu sunt toate egale"); getch(); } Programul nr. 5 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. S se afieze daca toate numerele introduse sunt diferite ntre ele. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define N 7 void main(void) { int a[N]; int i,j; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} //Se parcurge vectorul // se compara elementul curent cu toate elementele de dupa el for(i=0;i<N-1;i++) for(j=i+1;j<N;j++) if(a[i]==a[j]){ printf("Nu sunt toate diferite"); getch(); exit(0);} printf("Sunt toate diferite"); getch(); } Programul nr. 6 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. Se citete un numr ntreg x. S se afieze dac numrul x este prezent n vector sau nu (algoritmul de cutare liniara).

Vectori (I) Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void) { int a[N]; int i; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} int x; printf("x="); scanf("%d",&x); int estePrezent=0; //presupunem ca nu este for(i=0;i<N;i++) if(a[i]==x){ estePrezent=1; break; } if(estePrezent)printf("%d este prezent in vector",x); else printf("%d nu este prezent in vector",x); getch(); }

41

Programul nr. 7 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. Se citete un numr ntreg poz, ce reprezint o poziie n vector. S se tearg din vector numrul aflat pe poziia poz, i s se afieze noul vector. Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void) { int a[N]; int i; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i);

42

Vectori (I)

scanf("%d",&a[i]);} int poz; printf("poz="); scanf("%d",&poz); //Parcurgem vectorul de la indexul poz+1 pana la sfarsit, // si mutam prin copiere, elementul curent spre stanga cu o //pozitie for(i=poz+1;i<N;i++) a[i-1]=a[i]; //Afisare: for(i=0;i<N-1;i++) printf("%d\n,a[i]); getch(); } Programul nr. 8 Se citesc N numere ntregi de la tastatur i se memoreaz ntr-un vector a. Se citete un numr ntreg poz, ce reprezint o poziie n vector. Se citete un numr ntreg x. S se insereze numrul x pe poziia poz, n vectorul a i s se afieze noul vector. Sursa programului: #include <stdio.h> #include <conio.h> #define N 7 void main(void) { int a[N]; int i; clrscr(); for(i=0;i<N;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} int poz; printf("poz="); scanf("%d",&poz); int x; printf("x="); scanf("%d",&x); /* Mutam incepand de la pozitia poz, spre dreapta cu o pozitie, toate elementele vectorului. Aceata mutare o facem parcurgand vectorul in sens invers, pentru a nu distruge informatia din vector */

Vectori (I) for(i=N-1;i>=poz;i--) a[i+1]=a[i]; // Inseram pe x: a[poz]=x; //Afisare: for(i=0;i<=N;i++) printf("%d\n,a[i]); getch(); }

43

Programul nr. 9 Se citesc de la tastatur dou mulimi de numere ntregi, a de 20 de elemente i b de 10 de elemente (elementele, n fiecare mulime, se presupun distincte). Se calculeaz i se afieaz reuniunea celor dou mulimi de numere. Vom folosi constantele simbolice na i nb, pentru stocarea dimensiunii mulimilor a i b. Sursa programului: #include <stdio.h> #include <conio.h> #define na 20 #define nb 10 void main(void) { int a[na],b[nb]; //vectorul folosit pentru reprezentarea multimii reuniune: int c[na+nb]; //dimensiune acoperitoare int i,j,k; int esteComun;//variabila semafor clrscr(); //citire vector a: for(i=0;i<na;i++){ printf(a[%d]=,i); scanf(%d,&a[i]); } //citire vector b: for(i=0;i<nb;i++){ printf(b[%d]=,i); scanf(%d,&b[i]); }

44

Vectori (I)

/* Vectorul c consta din vectorul a si elementele din b care nu sunt si in a. */ //Copiem in c pe a: for(i=0;i<na;i++) c[i]=a[i]; //Adaugam in c si elementele din b care nu sunt si in a: k=na-1;//indexul ultimei componente adaugate in c for(i=0;i<nb;i++){ //este prezent b[i] in a? esteComun=0;//initializare: nu este prezent. for(j=0;j<na;j++) if(b[i]==a[j]){ esteComun=1;//este prezent break;//din for(j ) }//end if if(esteComun==0){//se adauga b[i] in multimea c k++;//cresc index curent in multimea c c[k]=b[i]; } }//for(i) //Afisarea multimii reuniune: for(i=0;i<=k;i++) printf(\n %d,c[i]); getch(); } 4. PROBLEME PROPUSE 1. Se citete un numr natural de tip long int. S se copieze toate cifrele ntr-un vector. 2. Se citete un numr natural N. S se copieze primele N numere prime ntr-un vector. 3. S se realizeze un program care rotete un vector spre stnga cu o poziie. 4. S se realizeze un program care rotete un vector spre dreapta cu o poziie. 5. S se calculeze intersecia a dou mulimi de numere ntregi, reprezentate prin vectori. 6. S se realizeze un program care analizeaz dac ntr-un vector elementele sunt n progresie aritmetic.

Vectori (II) VECTORI (II)

45

DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 Se citesc 20 de numere ntregi de la tastatur i se memoreaz ntr-un vector A. S se construiasc vectorul B ce conine toate numerele prime din vectorul A. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define N 20 void main(void) { int A[N]; int B[N]; int i,j,k; int estePrim; clrscr(); for(i=0;i<N;i++){ printf("A[%d]=",i); scanf("%d",&A[i]);} j=0;//index in vectorul B for(i=0;i<N;i++){ //este A[i] numar prim? estePrim=1;//initializare semafor estePrim for(k=2; k<A[i];k++) if(A[i]%k==0){ estePrim=0;//nu este numar prim break;} if(estePrim){ B[j]=A[i]; j++;} } //afisare vector B: if(j==0){ printf("Nu sunt numere prime in vectorul A! "); getch();

46

Vectori (II)

exit(1);} printf("Vectorul B:\n"); for(i=0;i<j;i++) printf("%d\n",B[i]); getch(); } Programul nr. 2 S se realizeze un program care realizeaz produsul scalar a doi vectori. Sursa programului: #include<conio.h> #include<stdio.h> void main(void){ int A[100],B[100]; //vectori de maxim 100 numere intregi int i,dim; long int produsScalar=0; clrscr(); printf("Introduceti dimensiunea vectorilor:"); scanf("%d",&dim); for(i=0;i<dim;i++){ printf("A[%d]=",i); scanf("%d",&A[i]); } //s-a citit vectorul A de la tastatura printf("\n"); for(i=0;i<dim;i++){ printf("B[%d]=",i); scanf("%d",&B[i]); } //s-a citit vectorul B de la tastatura //calculez produsul scalar: for(i=0;i<dim;i++) produsScalar=produsScalar+A[i]*B[i]; //afisez produsul scalar: printf("Prod. scalar pentru cei doi vectori este %ld",produsScalar); getch(); }//main

Vectori (II)

47

Programul nr. 3 S se citeasc de la tastatur N numere ntregi distincte, ce se vor memora ntr-un vector A. Dac se tasteaz un numr care a fost introdus deja n vectorul A, se repet tastarea pn se va introduce un numr distinct. Exemplu: Introducei numrul 1: 7 Introducei numrul 2: 1 Introducei numrul 3: 7 Introducei numrul 3: 5 Introducei numrul 4: ... Se observ cum s-a repetat introducerea numrului 3. Sursa programului: #include <stdio.h> #include <conio.h> #define N 10 //numarul de numere void main(void) { int A[N]; int i,j; int esteDistinct; //variabila semafor (flag) clrscr(); //citeste primul numar: printf("Introduceti numarul 1: "); scanf("%d",&A[0]); for(i=1;i<N;i++) for(;;){ printf("Introduceti numarul %d: ",i+1); scanf("%d",&A[i]); //este distinct de cele introduse pana acum in A ? esteDistinct=1; for(j=0;j<=i-1;j++) if(A[j]==A[i]){//nu este esteDistinct=0; break;} if(esteDistinct==1)break; }//for;; //Afisarea numerelor tastate: printf("\n"); for(i=0;i<N;i++)

48

Vectori (II)

printf("\nA[%d]=%d",i,A[i]); getch(); } Programul nr. 4 Se d un vector A de numere ntregi. S se sorteze n ordine cresctoare, folosind metoda sortrii prin interschimbare. Sursa programului: #include <stdio.h> #include <conio.h> #define N 10 void main(void) { /* n aceast metod se parcurge vectorul si se compar elementul curent cu toate elementele ce se afla in vector dupa el. Dac elementele comparate nu sunt n ordinea corespunztoare sortrii dorite, se inverseaz ntre ele (se comut coninutul lor). */ int i,j; int A[N]; int temp; clrscr(); for(i=0;i<N;i++){ printf("A[%d]=",i); scanf("%d",&A[i]);} for(i=0;i<N-1;i++) for(j=i+1;j<N;j++) if(a[i]>a[j]){ temp=a[i]; a[i]=a[j]; a[j]=temp;} //Afisarea vectorului sortat: for(i=0;i<N;i++) printf("\nA[%d]=%d",i,A[i]); getch(); } Programul nr. 5 Se d un vector A de numere ntregi. S se sorteze n ordine descresctoare, folosind metoda bubble sort.

Vectori (II)

49

Sursa programului: #include <stdio.h> #include <conio.h> #define N 10 void main(void) { /* n aceast metod se compar fiecare element cu urmtorul element (vecinul su din dreapta). Dac cele dou componente nu sunt n ordinea corespunztoare sortrii dorite, se inverseaz ntre ele (se comut coninutul lor). Se repet acest procedeu pn cnd s-a parcurs tot vectorul. Deci, pentru vectorul A, se compar A[0] cu A[1], apoi A[1] cu A[2], A[2] cu A[3] .a.m.d. Dac dup parcurgerea vectorului au fost fcute comutri, nseamn c nc nu este sortat i se reia parcurgerea lui (cu compararea elementelor nvecinate) ncepnd cu prima component. */ int i,j; int A[N]; int temp; int existaInversiuni;//variabila semafor clrscr(); for(i=0;i<N;i++){ printf("A[%d]=",i); scanf("%d",&A[i]);} //Se ordoneaza descrescator componentele vectorului A: //Metoda bubble sort: do{ existaInversiuni=0; for(i=0;i<N-1;i++) if(A[i]<A[i+1]){ existaInversiuni=1; //se inverseaza A[i] cu A[i+1]: temp=A[i]; A[i]=A[i+1]; A[i+1]=temp;}//if }while(existaInversiuni==1); //Afisarea vectorului sortat: printf("\n Vectorul A sortat descrescator: "); for(i=0;i<N;i++) printf("\nA[%d]=%d",i,A[i]);

50

Vectori (II)

getch(); } Programul nr. 6 S se implementeze un program care implementeaz algoritmul de sortare prin inserie a elementelor unui vector. Sursa programului: //Sunt doua grupe: cea din stanga este sortata, cea din //dreapta nu este. //Initial, grupa din stanga contine primul element din vector:A[0] #include <stdio.h> #include <conio.h> #define N 9 void main() { int A[N]={11111,-1,77,8,111,4,3,55,100}; int iNesortatSt;//indexul din stanga grupei nesortate int nr; int i,j; clrscr(); for(iNesortatSt=1;iNesortatSt<N;iNesortatSt++){ nr=A[iNesortatSt]; //inserez pe nr in grupa sortata din stanga, ce cuprinde // elem. de pe pozitiile 0,1,...,iNesortatSt-1 if(nr>A[iNesortatSt-1])continue;//nr e pe pozitia care //trebuie for(i=0;i<iNesortatSt;i++) if(nr<A[i]){ //ii fac loc: le mutam pe oate de la i spre dreapta: for(j=iNesortatSt-1;j>=i;j--) A[j+1]=A[j]; A[i]=nr; break;//din for i } } //afisare: for(i=0;i<N;i++) printf("\n%d",A[i]); getch(); }

Vectori (II)

51

Programul nr. 7 Se citete un numr natural x, de la tastatur. S se copieze primele N numere prime (N cunoscut), care sunt strict mai mari ca x, ntr-un vector A. S se afieze acest vector. Sursa programului: #include <stdio.h> #include <conio.h> #include <math.h> #define N 10 void main() { int x; int nrCrt; int A[N]; int i; clrscr(); printf("x="); scanf("%d",&x); nrCrt=x+1; for(i=0;i<N;i++) //se introduce in A[i], urmatorul numar prim >= nrCrt: //cautam acest numar prim: for(;;){ //este prim nrCrt? int este=1; //presupunem ca este int j; for(j=2;j<=sqrt(nr);j++) if(nr%j==0){ este=0; break;} if(este==1){ A[i]=nrCrt; nrCrt++; break; //iese din for(;;)} else nrCrt++; }//end for;; //afisarea vectorului A: for(i=0;i<N;i++) printf("\n%d",A[i]); getch(); }

52

Vectori (II)

Programul nr. 8 Fie a i b doi vectori de numere ntregi, citite de la tastatur. S se construiasc vectorul c, obinut prin concatenarea (lipirea) celor doi vectori. Sursa programului: #include <stdio.h> #include <conio.h> #define na 5 //numarul de elemente ale vectorului a #define nb 7 void main(void) { int i; int a[na], b[nb]; int c[na+nb];//vectorul obtinut prin concatenarea vectorilor a si b clrscr(); for(i=0;i<na;i++){ printf("a[%d]=",i); scanf("%d",&a[i]);} for(i=0;i<nb;i++){ printf("b[%d]=",i); scanf("%d",&b[i]);} //se copiaza vectorul a in c: for(i=0;i<na;i++)c[i]=a[i]; //In continuarea lui c, se copiaza vectorul b: for(i=0;i<nb;i++)c[na+i]=b[i]; //Afisarea vectorului c: for(i=0;i<na+nb;i++) printf("\nc[%d]=%d",i,c[i]); getch(); } Programul nr. 9 Folosind alocarea dinamica a memoriei, s se memoreze ntr-un vector, un numr de valori introduse de la tastatur, n vederea unor prelucrri ulterioare. Pentru alocarea dinamic a memoriei, n limbajul C se folosesc funciile malloc() i free(). (n limbajul C++, pe lng acestea, se folosete i operatorul new).

Vectori (II)

53

Funcia malloc() aloc memorie din zona de memorie dinamic ( heap ) i returneaz adresa de nceput a zonei alocate. Are ca parametru de intrare, numrul de octei solicitai. Funcia free() elibereaz memoria alocat anterior din heap, pentru o eventual reutilizare. Ea are ca parametru de intrare, adresa zonei din heap anterior alocat printr-un apel al funciei malloc(). Prototipurile acestor funcii sunt: void *malloc(size_t numr_de_octei); void free(void * p); Ambele funcii sunt declarate n fiierul header stdlib.h . n prototipul lui malloc(), numr_de_octei reprezint numrul de octei cerui pentru alocare dinamic. Dac nu mai este suficient memorie liber n heap, funcia malloc() returneaz pointerul NULL ( valoarea 0 ). Tipul size_t este definit n stdlib.h i reprezint un tip generic de ntreg fr semn, ce este capabil s in cea mai mare cantitate de memorie ce poate fi alocat n urma unui apel al funciei malloc() . Alocarea dinamic a memoriei se folosete tipic n aplicaiile cu structuri arborescente (liste nlnuite, arbori). Sursa programului: #include <stdio.h> #include <conio.h> #include <alloc.h> //pentru functiile malloc() si free() #include <stdlib.h> void main(void) { int nrElemente; //adresa de inceput a vectorului in care se memoreaza numerele: int * tab; int i; clrscr(); printf("Tastati numarul de elemente:"); scanf("%d",&nrElemente); tab=(int * )malloc(nrElemente * sizeof(int) ); if(tab==NULL){ printf("Nu exista memorie disponibila!"); getch(); exit(1); } for(i=0;i<nrElemente;i++){ printf("tab[%d]=",i);

54

Vectori (II)

scanf("%d",&tab[i]);} //afisare: printf("\nComponentele introduse in memoria dinamica sunt:"); for(i=0;i<nrElemente;i++)printf("\n%d",tab[i]); free(tab); getch(); }//main 4. PROBLEME PROPUSE 1. Se d un vector de numere ntregi. Care este cea mai mare distan ntre dou elemente alturate. Ex. {2,3,17,25}. R: 14. 2. S se realizeze un program care calculeaz c.m.m.d.c. a elementelor unui vector. 3. S se realizeze un program care calculeaz suma a dou numere mari reprezentate ca vectori. 4. S se scrie un program prin care se calculeaz i afieaz N! unde N este un numr mare ( Exemplu: 50!)

Tablouri bidimensionale TABLOURI BIDIMENSIONALE

55

1. SCOPUL LUCRRII n aceast lucrare se prezint aplicaii cu tablouri bidimensionale (matrici) si aplicaii cu iruri de caractere (stringuri). 2. BREVIAR TEORETIC 2.1. Tablouri bidimensionale Un tablou reprezint o colecie de date de acelai tip. Tablourile bidimensionale sunt denumite i matrici. La declararea unui tablou se specific numrul de elemente ale fiecrei dimensiuni, incluznd fiecare dintre aceste numere ntre paranteze drepte. Indexul inferior al fiecrei dimensiuni este 0. Sintaxa pentru declararea unei matrici este urmtoarea: tipul_datelor nume_matrice[nr_linii][nr_coloane]; Exemplu: a : o matrice de numere ntregi , ce are 10 linii a cte 5 componente pe linie : int a[10][5]; n general la tablourile multidimensionale i n particular la matrici, indexul cel mai din dreapta variaz cel mai rapid, adic pentru exemplul tabloului a, elementele componente sunt stocate n memorie, n urmtoarea ordine: a[0][0], a[0][1], ..., a[0][4], a[1][0], a[1][1], .... Un tablou bidimensional poate fi iniializat nc din faza de declarare, ca n exemplul urmtor: int mat[3][2]={ 0, 1, 3, 3, 4, 8}; 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 S se calculeze i s se afieze suma a dou matrice de cte 3 linii i 4 coloane fiecare. Vom iniializa prin atribuire direct, elementele celor dou matrici. Sursa programului: #include <stdio.h>

56

Tablouri bidimensionale

#include <conio.h> #define N 3 //numarul de linii ale matricilor #define M 4 //numarul de coloane ale matricilor void main(void) { int A[N][M]={ 0, 1, 2, 5, 2, 2, 2, 2, 3, 3, 3, 3 }; int B[N][M]={ 1, 5, 7, 9, 1, 3, 7, 0, 4, 4, 6, 2 }; int C[N][M]; //suma matricilor A si B int i, j; for(i=0;i<N;i++) for(j=0;j<M;j++) C[i][j]=A[i][j]+B[i][j]; //afisarea matricii C : clrscr(); for(i=0;i<N;i++){ printf(\n); for(j=0;j<M;j++) printf(%d ,C[i][j]); } getch(); } Programul nr. 2 S se substituie ntr-o matrice ptrat toate elementele aflate sub diagonala principal cu valoarea 0. Dimensiunea matricii se citete de la tastatur. Sursa programului: #include <stdio.h> #include <conio.h> void main() { int a[50][50]; //o dimensiune acoperitoare int n;//dimensiunea matricii int i,j; clrscr(); printf("Dimensiunea matricii n=");

Tablouri bidimensionale scanf("%d",&n); for(i=0;i<n;i++) for(j=0;j<n;j++){ printf("a[%d][%d]=",i,j); scanf("%d",&a[i][j]);} //Afisarea matricii a, inainte de substitutie: printf("Inainte de substitutie:\n"); for(i=0;i<n;i++){ for(j=0;j<n;j++) printf("%d ",a[i][j]); printf("\n");} //Substitutia cu 0: for(i=1;i<n;i++) for(j=0;j<i;j++) a[i][j]=0; //Afisarea matricii a, dupa substitutie: printf("Dupa substitutie:\n"); for(i=0;i<n;i++){ for(j=0;j<n;j++) printf("%d ",a[i][j]); printf("\n");} getch(); }

57

Programul nr. 3 Pentru o matrice ptrat A de numere ntregi, s se calculeze i afieze care este numrul (indexul) coloanei ce are suma elementelor (ale coloanei respective) maxim fa de sumele elementelor din celelalte coloane ale matricii. Sursa programului: #include <stdio.h> #include <conio.h> #define N 3 //numarul de linii (sau coloane) din matricea A void main(void) { int A[N][N]={ 0, 1, 2, 2, 2, 2, 3, 3, 3 }; //(Pentru acest exemplu, vom obtine ca rezultat coloana 2, pentru ca //ea are suma maxima 2+2+3=7)

58

Tablouri bidimensionale

int i,j; int sumaCrt; //suma elementelor coloanei curente int sumaMax; // maximul cautat int indexSumaMax; //indexul cautat clrscr(); //initializam sumaMax cu suma elementelor primei coloane: sumaMax=0; for(i=0;i<N;i++) sumaMax=sumaMax+A[i][0]; //initializare indexSumaMax: indexSumaMax=0; //Calculam sumele elementelor din restul coloanelor: for(j=1;j<N;j++){ //calculul sumei elementelor coloanei j: sumaCrt=0; for(i=0;i<N;i++) sumaCrt=sumaCrt+A[i][j]; //este mai mare ca sumaMax ? if(sumaCrt > sumaMax){ sumaMax=sumaCrt; indexSumaMax=j; } } //end for j printf(\nColoana cautata = %d , indexSumaMax); printf(\nAre suma= %d ., sumaMax); } Programul nr.4 S se creeze o matrice ptrata de dimensiune N, iniializata cu numere aleatoare, ce conine toate numerele din mulimea: {0,1,2,...,N*N-1}, fiecare element al mulimii aprnd o singura data. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define N 3 //dimensiunea matricii patrate void main() { int A[N][N]; int i,j; int nr;

Tablouri bidimensionale

59

int aMaiFostGenerat[N*N];//aMaiFostGenerat[i] este 1, daca numarul i a // mai fost generat anterior, deci este deja scris in matrice. //Initializare vector aMaiFostGenerat[] cu 0 (fals), deoarece la inceput, // nici un numar nu a fost folosit in matrice. for(i=0;i<N*N;i++) aMaiFostGenerat[i]=0; randomize(); for(i=0;i<N;i++) for(j=0;j<N;j++){ for(;;){ nr=random(N*N);//nr este cuprins intre 0 si N*N-1 if(aMaiFostGenerat[nr]==0){ aMaiFostGenerat[nr]=1; break;} } //scriem numarul generat in matrice: A[i][j]=nr; } //afisare matrice: clrscr(); for(i=0;i<N;i++){ for(j=0;j<N;j++) printf("%d ",A[i][j]); printf("\n"); } getch(); } Programul nr. 5 S se copieze toate elementele unei matrici ntr-un vector n urmtoarea ordine: nti prima linie, apoi a doua linie, etc. Sursa programului: #include <stdio.h> #include <conio.h> #define N 3 //numarul de linii #define M 2 //numarul de coloane void main() {

60

Tablouri bidimensionale

int A[N][M]={1,2, 0,1, 4,3}; int V[N*M]; int i,j; clrscr(); for(i=0;i<N;i++) for(j=0;j<M;j++) V[i*M+j]=A[i][j]; //afisare vector: for(i=0;i<N*M;i++) printf("%d ",V[i]); getch(); } Programul nr. 6 Se citesc de la tastatur dimensiunile unei matrici de numere ntregi. Se citete apoi matricea. S se afieze dac sunt diferite toate elementele matricii ntre ele sau nu. Sursa programului: #include <stdio.h> void main() { int a[20][20]; int nL;//nr. efectiv de linii din matrice int nC;//nr. coloane int i,j; printf("nr. linii = "); scanf("%d",&nL); printf("nr. coloane = "); scanf("%d",&nC); for(i=0;i<nL;i++) for(j=0;j<nC;j++){ printf("a[%d][%d]=",i,j); scanf("%d",&a[i][j]);} //Parcurgem toate elementele matricii, ca si cum ar fi dispuse // intr-un vector, de la primul, pana la penultimul: for(i=0;i<nL*nC-1;i++) //compar elementul curent, cu toate elementele dupa el: //(elementul curent este in linia i/nC si in coloana i%nC) for(j=i+1;j<nL*nC;j++) if(a[i/nC][i%nC]==a[j/nC][j%nC]){

Tablouri bidimensionale printf("Nu sunt toate diferite."); return;} printf("Sunt toate diferite."); }

61

Programul nr.7 Scriei un program care verific dac o matrice este ptrat magic. Se va verifica mai nti dac n matrice sunt prezente toate valorile din mulimea 1,2,...,N*N. Sursa programului: /* O matrice patrata de dimensiune N, ce contine toate numerele 1,2,..,N*N, este patrat magic daca suma elementelor din fiecare linie, din fiecare coloana, de pe diagonala principala si de pe diagonala secundara, are aceeasi valoare. Astfel, urmatoarea matrice, este patrat magic: 16 3 2 13 5 10 11 8 9 6 7 12 4 15 14 1 */ #include <stdio.h> #include <conio.h> #include <stdlib.h> #define N 4 //dimensiunea matricii #define NxN N*N //numarul de elemente din matrice void main() { int A[N][N]={16, 3, 2,13, 5,10,11, 8, 9, 6, 7,12, 4,15,14, 1}; int i,j; int suntPrezente[NxN]; int S;//valoarea comuna, daca este patrat magic int sCrt;//suma curenta calculata clrscr(); //Verificam daca matricea contine toate numerele din multimea //{1,2,...,N*N}:

62

Tablouri bidimensionale

//Fiecare numar valid prezent, il inregistram in vectorul //suntPrezente. for(i=0;i<NxN;i++) suntPrezente[i]=0; for(i=0;i<N;i++) for(j=0;j<N;j++) if((A[i][j]<1)||(A[i][j]>NxN)){ printf("Nu are toate elementele in gama 1,..,N*N ."); getch(); exit(1);} else suntPrezente[A[i][j]-1]=1; for(i=0;i<NxN;i++) if(suntPrezente[i]==0){ printf("Nu are toate elementele diferite, in gama 1,..,N*N ."); getch(); exit(1);} //Calculam suma elem. de pe diagonala principala: S=0; for(i=0;i<N;i++) S=S+A[i][i]; //Comparam valoarea S cu suma sCrt a fiecarei linii: for(i=0;i<N;i++){ //calculam suma de pe linia i: sCrt=0; for(j=0;j<N;j++) sCrt=sCrt+A[i][j]; if(sCrt!=S){ printf("Nu este patrat magic."); getch(); exit(1);} } //Comparam valoarea S cu suma sCrt a fiecarei coloane: for(i=0;i<N;i++){ //calculam suma de pe coloana i: sCrt=0; for(j=0;j<N;j++) sCrt=sCrt+A[j][i]; if(sCrt!=S){ printf("Nu este patrat magic."); getch();

Tablouri bidimensionale exit(1);} } //Comparam valoarea S cu suma sCrt de pe diagonala secundara: sCrt=0; for(i=0;i<N;i++) sCrt=sCrt+A[i][N-i-1]; if(sCrt!=S)printf("Nu este patrat magic."); else printf("Este patrat magic."); getch(); }

63

Programul nr.8 Implementai urmtorul algoritm prin care se construiete un ptrat magic, de dimensiune N. Acesta este valabil numai pentru N - impar. Plasai valoarea 1 in mijlocul rndului de jos. Apoi, pentru fiecare numr Nr de la 2 la N*N , se repet: dac numrul anterior ( Nr-1 ) a fost plasat in linia i si coloana j, numrul curent Nr se va plasa in linia i+1 ( o linie mai jos) i n coloana j+1 ( o coloan mai la dreapta ). Dac linia trece peste ultima: se va trece in linia 0. La fel si daca se trece peste ultima coloana: se trece n coloana 0. Daca poziia calculat este deja ocupat, numrul curent se va scrie n aceeai coloan, dar cu o linie mai sus. Astfel pentru N=3, se obine urmtorul ptrat magic: 4 9 2 3 5 7 8 1 6 Sursa programului: #include <stdio.h> #include <conio.h> #define N 3 //dimensiunea matricii void main() { int a[N][N]; int i,j,linCrt,colCrt,lin,col; int nr;//numarul curent ce se plaseaza in matrice clrscr(); //Umplem matrice cu 0: nu e ocupata: for(i=0;i<N;i++) for(j=0;j<N;j++) a[i][j]=0;

64

Tablouri bidimensionale

//punem pe 1 in matrice, in linia N-1 (ultima linie) // si coloana N/2 (cea din mijloc): linCrt=N-1; colCrt=N/2;//n este impar a[linCrt][colCrt]=1; for(nr=2;nr<=N*N;nr++) { //linia curenta si coloana curenta sunt pentru coltul dreapta jos? if((linCrt==N-1)&&(colCrt==N-1))linCrt=N-2; else{ //salvam linia si coloana curenta, in caz ca gasim ocupat: lin=linCrt; col=colCrt; //mergem in dreapta jos: linCrt=linCrt+1; colCrt=colCrt+1; //a iesit din margini ? if (linCrt==N)linCrt=0; if (colCrt==N)colCrt=0; //e ocupat? if(a[linCrt][colCrt]!=0){ linCrt=lin-1; colCrt=col;} }//else a[linCrt][colCrt]=nr; }//for //afisarea matricii rezultate: for(i=0;i<N;i++){ for(j=0;j<N;j++) printf("%d ",a[i][j]); printf("\n"); } getch(); } 4. PROBLEME PROPUSE 1. Se citesc 16 numere ntregi de la tastatur. Aceste numere trebuie memorate ntr-o matrice ptrat de 4 linii i 4 coloane. S se calculeze i afieze maximul din matrice ct i linia i coloana n care

Tablouri bidimensionale

65

apare acest maxim. ( n cazul n care sunt mai multe valori egale cu maximul, se va afia linia i coloana primei apariii). 2. S se comute dou coloane ale unei matrici ntre ele. Matricea i numerele coloanelor care se comut, se vor citi de la tastatur. 3. S se verifice dac o matrice ptrat NxN este simetric (fa de diagonala principal) . 4. Se citesc mai multe numere ntregi, ntr-o matrice. Se citete de asemenea numrul unei linii. S se copieze linia respectiv ntr-un vector. 5. S se permute dou linii ale unei matrici ntre ele. Numerele celor doua linii, ca i matricea, se vor citi de la tastatur. 8. S se scrie un program ce verific dac o matrice ptrat NxN are toate elementele de sub diagonala principal nule.

66

iruri de caractere IRURI DE CARACTERE

1. SCOPUL LUCRRII n aceast lucrare se prezint aplicaii cu iruri de caractere (stringuri). 2. BREVIAR TEORETIC Stringurile sunt vectori de caractere. Pentru a indica sfritul irului, limbajul C folosete drept caracter final al irului, caracterul nul (octet de valoare 0 ). Acesta se poate reprezenta i prin secvena escape \0. O variabil de tipul string cel mai adesea se declar ca vector de caractere. Exemplu: char s[4]; n acest caz dimensiunea vectorului trebuie s fie mai mare cu cel puin o unitate dect lungimea maxim a irurilor ce urmeaz a fi memorate n variabila string respectiv. n cazul variabilei s din exemplul dat, se pot memora iruri de maxim 3 caractere. Variabila ir poate fi iniializat nc din faza de declarare ca n exemplul urmtor: char s[4]=abc; Exist o serie de funcii ce realizeaz operaii asupra irurilor de caractere. Pentru citirea stringurilor de la tastatur se poate folosi funcia scanf cu specificatorul de format %s, sau funcia gets. Cu funcia scanf, spre deosebire de funcia gets, nu se pot citi iruri ce conin n interiorul lor caracterul blank. (La funcia scanf caracterele blank, TAB i ENTER sunt separatori ntre cmpurile de citire). Biblioteca standard furnizeaz un numr de funcii de procesare stringuri, ce au prototipurile declarate n fiierul header string.h . Dintre acestea, cele mai utilizate sunt: - funcia strcpy ce are prototipul: char * strcpy(char * p, char * const q); copiaz irul q n irul p. Funcia returneaz un pointer spre copia nou creat. - funcia strlen ce are prototipul: int strlen(const char * s); returneaz numrul de caractere din irul s (lungimea irului). n lungimea irului nu este inclus i caracterul terminal \0. Astfel irul

iruri de caractere

67

abcd are lungimea, returnat de funcia strlen, de 4 caractere i nu de 5. -funcia strcmp ce are prototipul: int strcmp(const char * p, const char * q); compar stringurile p i q din punct de vedere al ordinei lexicografice. Funcia strcmp returneaz valoarea 0 - dac cele 2 stringuri p i q, sunt egale, returneaz un numr negativ - dac primul ir precede lexicografic (este mai mic) dect cel de-al doilea, sau returneaz un numr pozitiv daca al doilea ir precede pe primul. 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 Se citete de la tastatur un ir de caractere. S se afieze cte cifre conine irul. Pentru a testa dac un caracter ASCII este cifr, se folosete funcia de bibliotec isdigit(). Aceast funcie are prototipul: int isdigit(int c); Ea returneaz 0, dac argumentul ei ( variabila c ) nu este codul ASCII al unei cifre. Dac este cod de cifr, returneaz un ntreg nenul. Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> #include <ctype.h> //fisier in care este declarata functia //isdigit() void main(void) { char s[81];//sir de lungime maxima 80 de caractere clrscr(); printf("Tastai un sir: \n"); scanf(%s,s); int L; //lungimea lui s int i; int nCif;//numarul de cifre din s L=strlen(s); nCif=0; for(i=0;i<L;i++)

68

iruri de caractere

if(isdigit(s[i]))nCif++; printf("Sirul %s are %d cifre.",s,nCif(s)); getch(); } Programul nr. 2 Se citete de la tastatur un ir de caractere. S se afieze dac este palindrom (simetric fata de mijlocul lui). Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> void main(void) { char s[81];//sir de lungime maxima 80 de caractere clrscr(); printf("Tastai un sir: \n"); scanf(%s,s); int L; //lungimea lui s int i; int esteSimetric=1;//presupunem ca este for(i=0;i<L/2;i++) if(s[i]!=s[L-i-1]){ esteSimetric=0; break;} if(esteSimetric)printf(Este palindrom): else printf(Nu este palindrom); getch(); } Programul nr. 3 Se citete de la tastatur un ir de caractere. S se afieze dac irul are toate caracterele diferite ntre ele sau nu. Sursa programului: #include <stdio.h> #include <string.h> #include <stdlib.h> void main() { char sir[100];

iruri de caractere printf("sir="); scanf("%s",sir); int L=strlen(sir); int i,j; for(i=0;i<L-1;i++) for(j=i+1;j<L;j++) if(sir[i]==sir[j]){ printf("NU sunt diferite."); getch(); exit(0);} printf("DA., are toate caracterele diferite."); getch(); }

69

Programul nr. 4 Se citete de la tastatur un ir de caractere s1. S se construiasc irul s2, obinut prin inversarea irului s1. Exemplu: daca s1=mar atunci s2=ram. Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> void main(void) { clrscr(); char s1[80]; printf("Tastai un sir: \n"); scanf(%s,s1); char s2[80]; int L; //lungime sir s1 L=strlen(s1); for(int i=L-1;i>=0;i--) s2[L-1-i]=s1[i]; //terminatorul de string: s2[L]='\0'; printf("Sirul inversat este:\n%s",s2); getch(); }

70

iruri de caractere

Programul nr. 5 Se citesc de la tastatur, sub form de iruri de caractere, dou numere naturale foarte mari. S se afieze care numr este mai mare. Sursa programului: #include <stdio.h> #include <string.h> void main() { char nr1[100]; char nr2[100]; printf("nr1="); scanf("%s",nr1); printf("nr2="); scanf("%s",nr2); int L1=strlen(nr1); int L2=strlen(nr2); if(L1>L2){ printf("nr1 > nr2"); return;} if(L2>L1){ printf("nr2 > nr1"); return;} //Sirurile au aceeasi lungime, comparam cifrele corespunzatoare // intre ele. Incepem cu cea mai semnificativa cifra (pozitia i=0): for(int i=0;i<L1;i++){ int cifra_nr1=nr1[i]-'0'; int cifra_nr2=nr2[i]-'0'; if(cifra_nr1>cifra_nr2){ printf("nr1 > nr2"); return;} if(cifra_nr2>cifra_nr1){ printf("nr2 > nr1"); return;} } printf("nr1 = nr2"); //Singura posibilitate ramasa: } Programul nr. 6 Se citete un ir s1. S se construiasc irul s2 ce conine, n aceeai ordine, cifrele ce apar n s1.

iruri de caractere Exemplu: daca s1=a1b3 atunci s2=13. Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> #include <ctype.h> void main(void) { char s1[81];//sirul citit. char s2[81];//sirul ce va contine doar cifrele int i; clrscr(); printf("sir="); scanf("%s",s1); int j=0;//index in sirul s2. for(i=0;i<strlen(s1);i++) if(isDigit(s1[i])){ s2[j]=s1[i]; j++;} //terminatorul de sir, pentru s2: s2[j]=0; //afisare sirul s2 construit: if(j>0)printf("%s",s2); else printf("Nu exista cifre in sirul s1 !"); getch(); }

71

Programul nr. 7 Se citesc de la tastatur, n trei variabile ir de caractere, numele unui director (folder), numele unui fiier (fr extensie) i extensia lui. S se construiasc ntr-o alt variabil ir, numele complet al fiierului. Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> void main() { char numeF[41]; char numeDir[41]; char extensie[5];

72

iruri de caractere

char numeComplet[100]; clrscr(); printf("nume director: "); scanf("%s",numeDir); printf("nume fisier (fara extensie): "); scanf("%s",numeF); printf("extensia numelui fisierului: "); scanf("%s",extensie); //copiez numele directorului, in stringul ce va contine numele //complet: strcpy(numeComplet,numeDir); //adaugam la acest nume, caracterul \ strcat(numeComplet,"\\"); //adaugam si numele propriu-zis al fisierului: strcat(numeComplet,numeF); //adaugam si caracterul . strcat(numeComplet,"."); //adaugam extensia: strcat(numeComplet,extensie); //afisam rezultatul: printf("%s",numeComplet); getch(); } Programul nr. 8 Se citesc N cuvinte de la tastatur, ntr-un vector de stringuri. S se sorteze n ordine alfabetic acest vector. Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> typedef char string80[81]; #define N 5 //numarul de cuvinte void main() { string80 A[N];//vectorul de cuvinte int i; string80 aux;//sir tampon, folosit la sortare int suntInv;//semafor, folosit la sortare clrscr();

iruri de caractere for(i=0;i<N;i++){ printf("cuvant="); scanf("%s",A[i]);} //sortare cu metoda bubble sort: int ultim=N-1; for(;;){ suntInv=0; for(i=0;i<ultim;i++) if(strcmp(A[i],A[i+1])>0){ strcpy(aux,A[i]); strcpy(A[i],A[i+1]); strcpy(A[i+1],aux); suntInv=1;} if(suntInv==0)break; else ultim--; } //afisare vector sortat: for(i=0;i<N;i++) printf("\n%s",A[i]); getch(); }

73

Programul nr. 9 S se cripteze un ir citit de la tastatur, dup algoritmul introdus de Louis Mansfiel, n 1936. La acest tip de criptare, fiecare litera este nlocuit cu dou vocale. Toate literele alfabetului englez, sunt plasate n celulele unei matrici ptrate de 5 linii si 5 coloane. Pe marginile acestui ptrat se aeaz cele 5 vocale, astfel: A E I O U A a b c d e E f g h i/j k I l m n o p O q r s t u U v w x y z Literele i sau j se codifica la fel. O liter oarecare din cele 25 din matrice, va fi substituit n textul criptat de cele 2 vocale: cea de pe linie i cea de pe coloana literei din matrice. Astfel, caracterul x se codeaz cu perechea de vocale: UI .

74

iruri de caractere

Orice alt caracter diferit de liter, se lsa neschimbat in textul criptat. Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> #include <ctype.h> void main() { char s[80]; char sCriptat[160]; clrscr(); printf("sir="); gets(s); //matricea literelor alfabetului (litera j - lipseste. Se //va coda separat, ca litera i. char C[5][5]={'a','b','c','d','e', 'f','g','h','i','k', 'l','m','n','o','p', 'q','r','s','t','u', 'v','w','x','y','z'}; char V[5]={'A','E','I','O','U'};//vectorul vocalelor folosit in criptare. int c; int gasit;//semafor pentru cautarea liniara int lin,col; int i;//index in sirul s int j;//index in sirul sCriptat j=0; for(i=0;i<strlen(s);i++){ //este caracterul curent litera? c=tolower(s[i]);//Daca este litera mare, va fi convertit la litera mica. //Daca nu este, //va ramane nemodificat. if(islower(c)){ //este litera mica? //cazul literei j - tratat separat, caci nu este prezenta in matrice: if(c=='j'){//j se codeaza cu: EO sCriptat[j]='E'; j++; sCriptat[j]='O'; j++;} else{ //cautam linia si coloana din matrice de cifrare:

iruri de caractere //cautare liniara: gasit=0; for(lin=0;lin<5;lin++){ for(col=0;col<5;col++) if(C[lin][col]==c){ gasit=1; break;} if(gasit==1)break; }//for sCriptat[j]=V[lin]; j++; sCriptat[j]=V[col]; j++; }//else }//a fost litera else{ //nu este litera: sCriptat[j]=c; j++;} }//for i //terminatorul de sir pentru sirul sCriptat: sCriptat[j]=0; printf("%s",sCriptat); getch(); }

75

4. PROBLEME PROPUSE 1. Se citete un ir de la tastatur. S se afieze ultima vocala din irul citit. 2. Se citete un ir de caractere de la tastatur. S se roteasc tot irul spre stnga cu o poziie. Exemplu: irul citit: "abcd" Dup rotaie: "bcda" 3. Se citete un ir de la tastatur. S se afieze care este vocala ce apare de cele mai multe ori n ir. 4. Se citete un ir de caractere de la tastatur. S se afieze dac n ir exist sau nu dou cifre alturate.

76

iruri de caractere

5. Se citesc dou cuvinte de la tastatur. S se afieze dac cel de-al doilea este anagrama primului (o permutare a caracterelor primului ir ). 6. Se citete un numr natural de la tastatur. Numrul putnd fi foarte mare, citirea lui se va face sub form de ir. S se calculeze i afieze care este cifra maxim din numr. 7. Se citete un ir s1 de la tastatur. S se construiasc irul s2 ce conine n ordinea apariiei, caracterele din irul s1, luate o singur dat. Exemplu: dac irul s1 este: CALCULATOR atunci irul s2 este: CALUTOR.

Scrierea modular a programelor SCRIEREA MODULAR A PROGRAMELOR

77

1. SCOPUL LUCRRII n aceast lucrare se va studia modul n care se definesc funciile, n limbajul C. 2. BREVIAR TEORETIC 2.1. Definirea funciilor Orice program C conine cel puin o funcie i aceasta este main (funcie a crei prezen este obligatorie). O funcie poate fi apelat fie din programul principal, fie dintr-o alt funcie. n limbajul C, o funcie nu poate fi definit n interiorul altei funcii. Definiia unei funcii trebuie s fie fcut o singur dat n program i are sintaxa: tipul_rezultatului nume_funcie(list_de_parametrii) { declaraii interne instruciuni } Lista de parametrii cuprinde parametrii funciei, ce pot fi: - de intrare. Valorile lor sunt transmise de ctre programul apelant . Nu sunt modificai n funcie. - de ieire. Sunt creai de funcie (valorile lor sunt calculate n interiorul funciei ). - de intrare / ieire. Sunt i folosii n funcie (recepionai de la programul ce a apelat funcia) dar i modificai n corpul funciei. Alegerea antetului funciei depinde de programator. n momentul apelrii, toi parametrii de intrare trebuie s aib valori (s fie iniializai). n cazul funciilor ce au parametrii de ieire sau parametrii de intrare / ieire, pentru acetia trebuie transmis funciei adresele lor. Pentru a evita lucrul direct cu pointeri i adresarea indirect, care este ceva mai greoi, lsnd aceasta s fie fcut de compilator, vom folosi pentru parametrii de ieire sau de intrare / ieire ai unei funcii (deci, pentru parametrii care trebuiau dai ca pointeri ) notaia de variabile referin (se folosete pentru aceast notaie simbolul & plasat ntre tipul parametrului i numele su ).

78

Scrierea modular a programelor

2.2. Apelul funciilor Un program C, ce const doar dintr-o definiie de funcie (alta dect main), nu poate fi rulat. Pentru testarea unei funcii scrise, trebuie s fie prezent cel puin i funcia main. n general, orice program de test trebuie : - s iniializeze parametrii de intrare - s apeleze funcia - s afieze rezultatul Un apel de funcie const din numele funciei, urmat de parametrii actuali ai funciei. Dac funcia returneaz o valoare, aceasta trebuie atribuit unei variabile. Urmrim: - ca toi parametrii de intrare s fie iniializai - pentru fiecare parametru n parte, trebuie s se respecte tipul lui - s se respecte numrul i ordinea parametrilor Exemplu: Se d urmtorul prototip de funcie: int f1(int a,double b); Fie urmtoarea secven de program: void main(void) { int a; double b; int rezultat; a=3; //se apeleaza functia f1(): .. } Vom da mai multe exemple de mod de apelare a funciei f1(), din programul principal. Unele dintre acestea vor fi greite i vom explica unde sunt greelile, altele vor fi corecte. Apelul 1: f1(a,b); Acest apel nu este corect pentru c argumentul b nu este iniializat. Apelul 2: f1(a,7.5); Este corect , dar valoarea returnat de funcie nu este folosit.

Scrierea modular a programelor Apelul 3: rezultat=f1(2); Nu este corect, pentru ca funcia f1() are doi parametrii. Apelul 4: rezultat=f1(a,3.14); Este corect, valoarea returnat este ncrcat n variabila rezultat.

79

2.3. Instruciunea return Ieirea dintr-o funcie (retransmiterea controlului ctre programul care a apelat-o) se face fie la ntlnirea instruciunii return fie (dac aceasta lipsete) la ntlnirea acoladei ce marcheaz sfritul funciei. Sintaxa instruciunii return: - prima form: return; Aceast form se folosete atunci cnd nu se transmite nici un rezultat ctre programul ce a apelat funcia respectiv. - a doua form: return rezultat; Aceast form se folosete atunci cnd se transmite un rezultat ctre programul ce a apelat funcia respectiv. Se poate folosi i varianta cu paranteze: return(rezultat); 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 S re scrie o funcie mpreun cu un program de test, care decide dac trei numere sunt n progresie aritmetic: Sursa programului: #include<conio.h> #include<stdio.h> int suntProgArit(int a, int b, int c); void main(void){ clrscr(); printf("%d",suntProgArit(1,2,4)); getch();

80

Scrierea modular a programelor

} int suntProgArit(int a, int b, int c) { if(b-a==c-b)return 1; else return 0; } Programul nr. 2 S se scrie o funcie mpreun cu un program de test, care stabilete dac dou numere a i b sunt prime ntre ele. Sursa programului: #include<conio.h> #include<stdio.h> int suntPrimeIntreEle(int a,int b); void main() { clrscr(); printf("%d",suntPrimeIntreEle(3,7)); getch(); } int suntPrimeIntreEle(int a,int b) { int sunt; int i; int min=a; if(b<a)min=b; sunt=1; for(i=2;i<=min;i++) if((a%i==0)&&(b%i==0)){ sunt=0; break; } return sunt; }

Scrierea modular a programelor

81

Programul nr. 3 S se scrie o funcie care returneaz primul numr prim mai mare strict dect un numr ntreg N dat. Se va scrie i programul principal ce testeaz aceast funcie. Sursa programului: #include <conio.h> #include <stdio.h> #include <math.h> //pentru functia sqrt() int primulNrPrim(int N); int estePrim(int nr); void main(void) { int N; clrscr(); printf(N=); scanf(%d,&N); printf(Primul nr. prim > %d este %d ., N, primulNrPrim(N)); getch(); } //definitia functiei primulNrPrim(): int primulNrPrim(int N) { int nrCrt; nrCrt=N+1; for(;;){ if(estePrim(nrCrt))return nrCrt; nrCrt++; } } //definitia functiei estePrim(): int estePrim(int nr) { int i; for(i=2;i<=sqrt(nr);i++) if( nr % i == 0 ) return 0; //nu este numar prim return 1; //este numar prim }

82

Scrierea modular a programelor

Programul nr. 4 S se scrie o funcie, mpreun cu un program de test, care returneaz minimul i maximul dintre trei numere. Sursa programului: #include<conio.h> #include<stdio.h> void max_min(int a,int b,int c,int&max,int& min); void main(void){ int min,max; clrscr(); max_min(30,6,0,max,min); printf("%d %d",min,max); getch(); } void max_min(int a,int b,int c,int&max,int& min) { max=a; if(b>max)max=b; if(c>max)max=c; min=a; if(b<min)min=b; if(c<min)min=c; } Programul nr. 5 S se scrie o funcie care are ca parametru de intrare un string i ca parametru de ieire, stringul inversat. Exemplu: Dac stringul de intrare este: "12abc" atunci stringul de ieire va fi: "cba21" . Sursa programului: #include <stdio.h> #include <conio.h> #include <string.h> void inversareStr(char * in, char* out); void main(void) { char s1[80]="12abc"; char s1Inv[80];

Scrierea modular a programelor inversareStr(s1,s1Inv); clrscr(); printf("Sirul inversat este:\n%s",s1Inv); getch(); } void inversareStr(char* in, char* out) { int i; int L; //lungime sir in L=strlen(in); for(i=L-1;i>=0;i--) out[L-1-i]=in[i]; //terminatorul de string: out[L]='\0'; }

83

Programul nr. 6 S se scrie o funcie, mpreun cu un program de test, ce are ca parametru de intrare un vector A i dimensiunea lui i scoate ca rezultat vectorul ce conine toate numerele prime din A, precum i dimensiunea lui. Sursa programului: #include<conio.h> #include<stdio.h> #include<math.h> int estePrim(int nr); void vectorPrime(int A[], int dimA, int B[], int& dimB); void main(void){ int A[5]={7,9,8,19,31}; int B[5]; int dimB; int i; clrscr(); vectorPrime(A,5,B,dimB); for(i=0;i<dimB;i++)printf("%d ",B[i]); printf("\nDimensiunea vectorului de numere prime este %d",dimB); getch(); }

84

Scrierea modular a programelor

int estePrim(int nr) { int i; int este=1; for(i=2;i<=sqrt(nr);i++) if(nr%i==0){ este=0; break; } return este; } void vectorPrime(int A[], int dimA, int B[], int& dimB) { int i; int j; j=0; for(i=0;i<dimA;i++) if(estePrim(A[i])){ B[j]=A[i]; j++;} dimB=j; } Programul nr. 7 S se scrie o funcie, mpreun cu un program de test, care afieaz dac elementele unui vector sunt sau nu diferite. Sursa programului: #include<conio.h> #include<stdio.h> #include<math.h> int suntDiferite(int A[],int dimA); void main(void){ int A[6]={138,9,19,32,31,18}; clrscr(); printf("\n%d",suntDiferite(A,6)); getch(); } int suntDiferite(int A[],int dimA)

Scrierea modular a programelor { int i,j; for(i=0;i<dimA;i++) for(j=i+1;j<dimA;j++) if(A[j]==A[i])return 0; return 1; }

85

Programul nr. 8 S se scrie o funcie ce face rotirea spre stnga a unui vector, precum i un program de test. Sursa programului: #include<conio.h> #include<stdio.h> void rotireSt(int A[], int dimA); void main(void){ int i,A[6]={138,9,19,32,31,30}; clrscr(); rotireSt(A,6); for(i=0;i<6;i++) printf("%d ",A[i]); getch(); } void rotireSt(int A[], int dimA) { int primul; int i; primul=A[0]; for(i=0;i<dimA-1;i++) A[i]=A[i+1]; //ultimul: A[dimA-1]=primul; } Programul nr. 9 S se scrie o funcie, mpreun cu programul de test care afieaz dac un vector este sau nu sortat cresctor. Sursa programului: #include<conio.h>

86

Scrierea modular a programelor

#include<stdio.h> int esteSortatCresc(int A[], int dimA); void main(void){ int i,A[6]={1,9,19,30,31,36}; clrscr(); printf("%d",esteSortatCresc(A,6)); getch(); } int esteSortatCresc(int A[], int dimA) { int i; int este=1; for(i=0;i<dimA-1;i++) if(A[i+1]<A[i]){ este=0; break; } return este; } Programul nr. 10 S se scrie o funcie, mpreun cu programul de test, care returneaz minimul i maximul dintr-un vector, precum i poziiile lor. Sursa programului: #include<conio.h> #include<stdio.h> void max_minV(int A[], int dimA, int& max, int& pozMax, int& min, int & pozMin); void main(void){ int min,max,pozMin,pozMax,A[6]={11,9,19,30,310,36}; clrscr(); max_minV(A,6,max,pozMax,min,pozMin); printf("Maximul este %d si are indexul %d\n",max,pozMax); printf("Minimul este %d si are indexul %d",min,pozMin); getch(); } void max_minV(int A[], int dimA, int& max, int& pozMax, int& min, int & pozMin)

Scrierea modular a programelor { int i; max=A[0]; pozMax=0; for(i=1;i<dimA;i++) if(A[i]>max){max=A[i]; pozMax=i;} min=A[0]; pozMin=0; for(i=1;i<dimA;i++) if(A[i]<min){min=A[i]; pozMin=i;} }

87

4. PROBLEME PROPUSE 1. S se scrie o funcie mpreun cu un program de test care s afieze toate perechile de numere prime ntre ele din intervalul [N1, N2]. 2. S se scrie o funcie mpreun cu un program de test care s afieze toate numerele prime dintr-un interval [N1, N2]. 3. S se scrie o funcie ce are ca rezultat intersecia a dou mulimi, i are antetul: void intersectie(int A[], int nA, int B[], int nB, int C[], int &nC) 4. S se scrie o funcie ce face rotirea spre dreapta a unui vector. 5. S se scrie o funcie i programul de test, care are ca intrare un numr de tip long int, i scoate ca rezultat un vector ce conine toate cifrele numrului. 6. S se scrie o funcie care returneaz cel mai mare numr prim de patru cifre. 7. S se scrie o funcie care scoate drept rezultat soluiile ecuaiei de gradul al doilea, i are antetul: int ec2(double a, double b, double c, double &x1, double &x2)

88

Funcii recursive FUNCTII RECURSIVE 1. SCOPUL LUCRRII n aceast lucrare se va studia recursivitatea. 2. BREVIAR TEORETIC

2.1. Funcii recursive O funcie recursiv este o funcie care se apeleaz pe ea nsi. La fiecare apel al funciei, parametrii funciei i variabilele locale ei (cele care nu sunt statice) sunt alocate pe stiv (la fiecare apel n zone diferite). La revenirea din apelul funciei recursive, are loc descrcarea stivei. Funciile recursive au avantajul c permit o exprimare uoar, clar, a relaiilor recurente. Dezavantajul lor este c determin mrirea timpului de execuie a programului, fa de varianta nerecursiv (datorit timpului consumat cu ncrcarea / descrcarea stivei ). 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 S se scrie funcia factorial, implementndu-se recursiv urmtoarea definiie: 1! =1 n!=n*(n-1)! , dac n>1 Sursa programului: #include <stdio.h> #include <conio.h> long int factorial (int n); void main(void) { int nr; long int rezultat; clrscr(); printf(nr=);scanf(%d,&nr); rezultat=factorial(nr); printf(%d ! = %ld ,nr,rezultat); getch(); }

Funcii recursive long int factorial (int n) { if (n==1) return 1; else return (n*factorial(n-1)); }

89

Programul nr. 2 S se implementeze o funcie recursiv care s calculeze termenul de rang n din irul lui Fibonacci. irul Fibonacci se definete astfel: a0=1 a1=1 an=an-1 + an-2 dac n>1 Sursa programului: #include <stdio.h> #include <conio.h> int fib(int n); void main (void) { int n, rez; printf ("n="); scanf("%d",&n); rez=fib(n); printf("Termenul de rang %d este : %d",n,rez); getch(); } int fib (int n) { if(n==0) return 1; else if(n==1) return 1; else return (fib(n-1)+fib(n-2)); } Programul nr. 3 Se citete un numr natural de la tastatur. S se afieze dac este termen n irul lui Fibonacci sau nu. #include<stdio.h> #include<conio.h> int fib(int n); void main(void)

90

Funcii recursive

{ clrscr(); printf("nr="); int nr; scanf("%d",&nr); int n=0; for(;;){ int termenFib=fib(n); if(termenFib==nr){ printf("%d este termen in sirul Fibonacci.",nr); break;} if(termenFib>nr){ printf("%d nu este termen in sirul Fibonacci.",nr); break;} n++;} getch(); } int fib (int n) { if(n==0) return 1; else if(n==1) return 1; else return (fib(n-1)+fib(n-2)); } Programul nr. 4 S se scrie o funcie recursiv ce calculeaz suma elementelor unui vector. Sursa programului: #include <stdio.h> #include <conio.h> #define N 5 //numarul de elemente din vector int suma(int A[], int n); void main() { int A[N]={17, 5, 0, 9, 4}; int S;//suma clrscr(); S=suma(A,N); printf("S=%d",S);

Funcii recursive }

91

int suma(int A[], int n) { /* Algoritm: daca n=1 atunci returneaza A[0] (o singura componenta) altfel returneaza suma dintre ultima componenta si suma celor ramase (primele n-1) */ if(n==1)return A[0]; else return (A[n-1]+suma(A,n-1)); } Programul nr. 5 S se scrie o funcie recursiv ce stabilete dac un numr x este prezent ntr-un vector A de N componente. Sursa programului: #include <stdio.h> #include <conio.h> #define N 5//numarul de componente din A int estePrezent(int x, int A[], int n); void main() { int A[N]={1,2,3,4,5}; int x=3; clrscr(); if(estePrezent(x,A,N)==1)printf("Este."); else printf("Nu este."); } int estePrezent(int x, int A[], int n) { /*Algoritm: daca n=1 atunci daca x=A[0] returneaza 1, altfel returneaza 0 altfel (sunt mai multe componente in vector) daca x=ultima componenta returneaza 1. daca x nu este egal cu ultima componenta, se continua cautarea lui x in vectorul A redus (fara ultima componenta) */ if(n==1){ if(x==A[0])return 1;

92

Funcii recursive else return 0;}

else{ if(x==A[n-1])return 1; else return estePrezent(x,A,n-1); } } Programul nr. 6 S se scrie o funcie recursiv ce compar doi vectori de aceeai dimensiune. Returneaz 1, dac cei doi vectori sunt egali, i 0, n caz contrar. Sursa programului: #include <stdio.h> #include <conio.h> #define N 4 int compara(int A[], int B[], int n); void main() { int A[N]={1,2,3,4}; int B[N]={1,2,3,4}; clrscr(); if(compara(A,B,N)==1)printf("Sunt egali."); else printf("Nu sunt egali."); } int compara(int A[], int B[], int n) { /*Algoritm: daca n=1 atunci (vectori au doar o componenta) daca A[0]=B[0] atunci returneaza 1, altfel returneaza 0 altfel (vectorii au mai mult de o componenta) se compara ultima componenta din A cu ultima din B daca sunt egale, se apeleaza recursiv functia pentru a compara vectorii redusi (doar primele n-1 componente) altfel, daca nu sunt egale, returneaza 0. */ if(n==1){ if(A[0]==B[0])return 1; else return 0;}

Funcii recursive else{ if(A[n-1]==B[n-1])return compara(A,B,n-1); else return 0;} }

93

Programul nr. 7 S se scrie o funcie recursiv ce calculeaz i returneaz maximul dintr-un vector. Sursa programului: #include <stdio.h> #include <conio.h> #define N 5 //numarul de elemente din vector int maxim(int A[], int n); void main() { int A[N]={1, 5, 20, 1, 3}; int max; clrscr(); max=maxim(A,N); printf("maxim=%d",max); } int maxim(int A[], int n) { /*Algoritm: daca vectorul are o singura componenta: returneaza A[0] altfel: 1)calculeaza max1: maximul din vectorul redus (fara ultima componenta) 2)returneaza maximul dintre max1 si ultima componenta */ int max1; if(n==1)return A[0]; else{ max1=maxim(A,n-1); if(max1>A[n-1])return max1; else return A[n-1]; } }

94

Funcii recursive

Programul nr. 8 S se sorteze n ordine cresctoare, folosind metoda seleciei maximului, un vector de N componente, numere ntregi. Se va proceda astfel: mai nti calculm maximul dintre cele N numere. Acesta se va muta de pe poziia lui, pe ultima poziie (poziia N-1), comutnd cele dou numere ntre ele. Apoi, se calculeaz maximul dintre primele N-1 numere, i acesta se comut cu numrul de pe penultima poziie (poziia N-2), .a.m.d. Exemplu: N=5 A={17, 5, 0, 9, 4} Pasul 1: maxim1=17. Dup comutare: A={4, 5, 0, 9, 17} Pasul 2: maxim2=9. Dup comutare: A={4, 5, 0, 9, 17} Pasul 3: maxim3=5. Dup comutare: A={4, 0, 5, 9, 17} Pasul 4: maxim4=4. Dup comutare: A={0, 4, 5, 9, 17} Sursa programului: #include <stdio.h> #include <conio.h> #define N 5 //numarul de elemente din vector void ordonare(int A[], int dim);//prototipul functiei recursive. //functia getPozMax() afla pozitia maximului, intr-un vector //ce are dim componente: int getPozMax(int A[], int dim); void main() { int A[N]={17, 55, 0, 9, 4}; int i; clrscr(); ordonare(A,N); //Afisare vector ordonat: for(i=0;i<N;i++) printf("\n%d",A[i]); } void ordonare(int A[], int dim) { int pozMax; int index; /* Algoritm: daca dim=0 atunci este ordonat altfel:

Funcii recursive

95

1)comuta maximul (dintre cele dim elemente),cu elementul de pe ultima pozitie 2)ordoneaza ( apel recursiv) primele dim-1 elemente */ if(dim==0)return;//este ordonat //afla pozitia maximului: pozMax=getPozMax(A,dim); //comutarea maximului gasit A[pozMax], cu elementul de pe ultima pozitie //(pozitia dim-1), prin intermediul variabile auxiliare aux: int aux; aux=A[dim-1]; A[dim-1]=A[pozMax]; A[pozMax]=aux; //se repeta procedeul pentru primele dim-1 componente ale lui A: ordonare(A,dim-1); } int getPozMax(int A[], int dim) { int pozMax;//pozitia (indexul) maximului. Maximul va fi A[pozMax]. int i; pozMax=0; for(i=1;i<dim;i++) if(A[i]>A[pozMax])pozMax=i; return pozMax; } Programul nr. 9 Se dau trei tije notate cu I (tija iniial), M (tija de manevr) i F (tija final). Pe tija I se afl N discuri, de diametre diferite, aezate n ordinea descresctoare a diametrelor (cel mai mare se afl la baz). Acestea trebuie mutate pe tija final F, folosind eventual, pentru manevr, tija intermediar (de manevr) M. O mutare const din luarea unui disc din vrful unui turn i aezarea sa n vrful altui turn. Nu se poate aeza ns, un disc de diametru mai mare, peste un disc de diametru mai mic. Aceast problem este cunoscut sub numele de problema turnurilor din Hanoi. Algoritmul este explicat n comentariile programului.

96

Funcii recursive

Sursa programului: #include <conio.h> #include <stdio.h> #define N 3 //numarul de discuri void Hanoi(char tI, char tF, char tM, int n); //tI: tija initiala (tija de unde se iau discurile ce trebuie mutate) //tF: tija finala (tija unde se muta toate discurile de pe tija initiala) //tM: tija de manevra (tija intermediara) void main() { clrscr(); //trebuie mutate N discuri de pe tija initiala 'I', pe tija //finala 'F', cu ajutorul tijei de manevra 'M'. Hanoi('I','F','M', N); getch(); } void Hanoi(char tI, char tF, char tM, int n) { //daca este doar un disc, acesta se muta direct de pe tija initiala tI, //pe tija finala tF (nu este necesara tija de manevra tM): if(n == 1) { printf("%c -> %c\n", tI, tF); return; } //Cazul cnd sunt mai multe discuri (n>1): //La inceput, se muta n-1 discuri de pe tija tI, pe tija tM, folosind //ca tija de manevra tija tF: Hanoi(tI, tM, tF, n - 1); //ultimul disc, ramas la baza tijei initiale tI, se muta direct pe tija //finala tF, care este libera: printf("%c -> %c\n", tI, tF); //cele n-1 discuri de pe tija tM, se muta pe tija tF, folosind ca tija //de manevra tija tI (tI era libera): Hanoi(tM, tF, tI, n - 1); }

Funcii recursive

97

4. PROBLEME PROPUSE 1. S se scrie o funcie recursiv care calculeaz produsul scalar a doi vectori de aceeai dimensiune. 2. S se scrie o funcie recursiv care returneaz indexul maximului dintr-un vector. 3. S se scrie o funcie recursiv ce calculeaz suma 13+23+33+...+n3, unde n este un numr natural citit de la tastatur. 4. S se scrie o funcie recursiv care returneaz produsul elementelor unui vector. 5. Se citete un numr natural N. Sa se copieze primii N termeni din irul lui Fibonacci ntr-un vector.

98

Structuri STRUCTURI 1. SCOPUL LUCRRII n aceast lucrare se vor studia structuri i vectori de structuri. 2. BREVIAR TEORETIC

2.1. Structuri Structurile sunt folosite pentru a grupa sub acelai nume, mai multe date de acelai tip sau de tipuri diferite. Sunt denumite i nregistrri. n limbajul C, pentru a declara o structur, se folosete cuvntul cheie struct. n mod uzual, numele unei structuri se declar cu ajutorul cuvntului cheie typedef. Sintaxa: typedef struct{ tip1 membrul1; tip2 membrul2; ... }numeStructra; Exemplu: typedef struct{ double re; double im; }complex; Dup ce a fost definit cuvntul cheie typedef, numele asociat structurii poate fi folosit pentru a declara variabile. Exemplu: complex c1,c2; angajat a1; 2.2. Accesul la componentele unei structuri Pentru accesarea membrilor unei structuri, pe baza numelui ei, se folosete operatorul punct. Exemple: c1.re = 0.2; c1.im = 0.7; modulC1 = sqrt(c1.re* c1.re + c1.im* c1.im);

Structuri

99

2.3. Vectori de structuri n mod frecvent se folosesc tablouri ce au drept componente structuri. Astfel, un vector ce conine 100 de numere complexe, se declar n felul urmtor: typedef struct{ double re; double im; }complex; complex tab[100]; Accesm un cmp dintr-o structur component a unui vector, tot prin intermediul operatorului punct, aflat la dreapta componentei. Astfel prin instruciunea: tab[0].re = 0.5; se atribuie cmpului re al primei componente din vectorul tab valoarea 5. 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 Se definete structura punct, ce are dou cmpuri x i y (coordonatele reprezentrii n plan a unui punct). S se scrie un program n care se citesc coordonatele a dou puncte, de la tastatur i se afieaz distana ntre aceste puncte. Sursa programului: #include<conio.h> #include<stdio.h> #include<math.h> typedef struct{ int x; int y; }punct; void main(void) { punct P1,P2; double d12; //distanta de la punctul 1 la punctul 2 clrscr(); printf("Primul punct: x="); scanf("%d",&P1.x); printf("\nPrimul punct: y="); scanf("%d",&P1.y);

100

Structuri

printf("\nAl doilea punct: x="); scanf("%d",&P2.x); printf("\nAl doilea punct: y="); scanf("%d",&P2.y); //se calculeaza distanta dintre cele doua puncte: d12=sqrt((P1.x-P2.x)*(P1.x-P2.x)+(P1.y-P2.y)*(P1.y-P2.y)); printf("Distanta dintre cele doua puncte este %lf",d12); getch(); } Programul nr. 2 Se definete n acest program structura complex, ce const din dou numere reale: partea real i partea imaginar a unui numr complex. Se va scrie o funcie n care se calculeaz modulul unui numr complex, o funcie n care se calculeaz conjugatul unui numr complex i o alt funcie n care se calculeaz suma a trei numere complexe. Sursa programului: #include<conio.h> #include<stdio.h> #include<math.h> typedef struct{ double re; double im; }complex; double modulComplex(complex c); complex sumaComplex(complex c1, complex c2,complex c3); complex complexConjugat(complex c); void afisareComplex(complex c); void main(void){ complex c1,c2,c3,rezultat; double modul; clrscr(); printf("Partea reala si partea imaginara a primului numar"); scanf("%lf%lf",&c1.re,&c1.im); printf("Partea reala si partea imaginara a numarului al doilea"); scanf("%lf%lf",&c2.re,&c2.im); printf("Partea reala si partea imaginara a numarului al treilea"); scanf("%lf%lf",&c3.re,&c3.im); modul=modulComplex(c1); printf("\nModulul primului numar: %lf",modul);

Structuri modul=modulComplex(c2); printf("\nModulul numarului doi: %lf",modul); rezultat=sumaComplex(c1,c2,c3); printf("\nSuma celor trei numere este:\n"); afisareComplex(rezultat); rezultat=complexConjugat(c1); printf("\nComplex conjugatul numarului"); afisareComplex(c1); printf("este: "); afisareComplex(rezultat); getch(); } double modulComplex(complex c) { double rez; rez=sqrt(c.re*c.re+c.im*c.im); return rez; } complex sumaComplex(complex c1,complex c2,complex c3) { complex rez; rez.re=c1.re+c2.re+c3.re; rez.im=c1.im+c2.im+c3.im; return rez; } complex complexConjugat(complex c) { complex rez; rez.re=c.re; rez.im=-c.im; return rez; } void afisareComplex(complex c) { if(c.im>0)printf("%.3lf+%.3lf",c.re,c.im); else if(c.im==0)printf("%.3lf",c.re);

101

102

Structuri

else printf("%.3lf-%.3lf",c.re,-c.im); } Programul nr. 3 Se citesc de la tastatur mai multe numere de tip complex, care se memoreaz ntr-un vector de numere complexe. S se realizeze un program care s calculeze i afieze numrul de modul maxim. Sursa programului: #include<conio.h> #include<stdio.h> #include<math.h> typedef struct{ double re; double im; }complex; double modulComplex(complex c); #define N 2 void main(void) { int i,indexMax; complex A[N]; double ModulMaxim; double Modul[N]; clrscr(); for(i=0;i<N;i++){ printf("Partea reala a numarului %d: ",i); scanf("%lf",&A[i].re); printf("\nPartea imaginara a numarului %d: ",i); scanf("%lf",&A[i].im); } for(i=0;i<N;i++) Modul[i]=modulComplex(A[i]); ModulMaxim=Modul[0]; indexMax=0; for(i=1;i<N;i++) if(Modul[i]>ModulMaxim){ModulMaxim=Modul[i];indexMax=i;} printf("%lf\n",A[indexMax].re); printf("%lf",A[indexMax].im); getch();

Structuri } double modulComplex(complex c) { double rez; rez=sqrt(c.re*c.re+c.im*c.im); return rez; }

103

Programul nr. 4 Folosind structura punct, se vor citi de la tastatur N puncte, care vor fi introduse ntr-un vector. S se realizeze un program care s afieze daca toate cele N puncte sunt diferite intre ele sau nu. Sursa programului: #include<stdio.h> #include<conio.h> typedef struct { int x; int y; } punct; #define N 3 //numarul de puncte void main(void) { punct p[N];//vectorul de puncte clrscr(); int i,j; //citim cele N puncte in vectorul p: for(i=0;i<N;i++){ printf("p[%d].x=",i); scanf("%d",&p[i].x); printf("p[%d].y=",i); scanf("%d",&p[i].y);} int suntDiferite=1;//presupunem ca sunt for(i=0;i<N-1;i++) for(j=i+1;j<N;j++) if((p[i].x==p[j].x)&&(p[i].x==p[j].y)){ suntDiferite=0; break;} if(suntDiferite)printf("Sunt diferite."); else printf("Nu sunt diferite.");

104

Structuri

getch(); } Programul nr. 5 Folosind structura punct, se vor citi de la tastatur N puncte, care vor fi introduse ntr-un vector. S se realizeze un program care s afieze distana maxim dintre dou puncte. #include<stdio.h> #include<conio.h> #include <math.h> typedef struct { int x; int y; } punct; #define N 3 //numarul de puncte double dist(punct a, punct b); //distanta intre doua puncte void main(void) { punct p[N];//vectorul de puncte clrscr(); int i,j; //citim cele N puncte in vectorul p: for(i=0;i<N;i++){ printf("p[%d].x=",i); scanf("%d",&p[i].x); printf("p[%d].y=",i); scanf("%d",&p[i].y);} //Toate distantele sunt pozitive, deci initializam // distMax cu 0: double distMax=0; //Formam toate perechile de puncte posibile: for(i=0;i<N-1;i++) for(j=i+1;j<N;j++){ double distCrt=dist(p[i],p[j]);//distanta intre p[i] si p[j] if(distCrt>distMax)distMax=distCrt;} printf("Distanta maxima=%lf",distMax); getch(); } double dist(punct a, punct b) {

Structuri return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }

105

Programul nr. 6 Se definete structura elev, ce conine dou cmpuri: numele de familie unui elev (de tipul string) i nota obinut de elev (de tipul int). Se citesc de la tastatur i se memoreaz ntr-un vector de structuri elev, elevii unei clase i notele obinute de ei. S se sorteze acest vector n ordinea descresctoare a notelor elevilor. Sursa programului: #include <stdio.h> #include <conio.h> #define NR_ELEVI 20 typedef struct { char nume[41]; int nota; } elev; void main(void) { elev tab[NR_ELEVI]; int i; elev temp; int existaInversiuni;//variabila semafor for(i=0;i<NR_ELEVI;i++){ printf("\n\nNumele elevului numarul %d: ",i+1); scanf("%s",tab[i].nume); printf("Nota elevului numarul %d: ",i+1); scanf("%d",&tab[i].nota); } //sortarea, prin metoda bubble sort: do{ existaInversiuni=0; for(i=0;i<NR_ELEVI-1;i++) if(tab[i].nota<tab[i+1].nota){ existaInversiuni=1; //se inverseaza strucura tab[i] cu structura tab[i+1]: temp=tab[i]; tab[i]=tab[i+1]; tab[i+1]=temp;}//if }while(existaInversiuni==1);

106

Structuri

//Afisarea elevilor: for(i=0;i<NR_ELEVI;i++) printf("%s %d\n",tab[i].numetab[i].nota); } 4. PROBLEME PROPUSE 1. Cu ajutorul structurii punct, definit anterior, s se realizeze un program care afieaz dac trei puncte ale cror coordonate se introduc de la tastatur, sunt sau nu coliniare. 2. S se scrie o funcie n care se realizeaz nmulirea a dou numere complexe. 3. Se citesc N puncte ntr-un vector. S se afieze dac sunt coliniare. 4. Folosind structura elev definit anterior, citim N elevi ntr-un vector. S se afieze toi elevii care au nota > 7.

Operatori de prelucrare la nivel de bit OPERATORI DE PRELUCRARE LA NIVEL DE BIT

107

1. SCOPUL LUCRRII n aceast lucrare se studiaz o parte din operatorii de prelucrare la nivel de bit, ai limbajului C, i anume: & I la nivel de bit | SAU la nivel de bit ^ SAU EXCLUSIV la nivel de bit ~ NEGARE la nivel de bit << DEPLASARE STNGA la nivel de bit >> DEPLASARE DREAPTA la nivel de bit 2. BREVIAR TEORETIC n programarea interfeelor electronice este adesea necesar s prelucrm datele la nivel de bit. Limbajul C este un limbaj adecvat pentru dezvoltarea de sisteme electronice i datorit faptului ca are un set bogat de operatori de prelucrare la nivel de bit i anume: & (operatorul I) | (operatorul SAU) ^ (operatorul SAU EXCLUSIV) ~ (operatorul NEGARE) << (operatorul DEPLASARE STNGA) >> (operatorul DEPLASARE DREAPTA) Toi aceti operatori, cu excepia operatorului ~ (negare), sunt operatori binari, adic au doi operanzi. n general cnd se studiaz operatori noi, acetia trebuie studiai i cu prioritatea lor. Astfel, operatorul I este mai prioritar (leag mai puternic) dect SAU EXCLUSIV, i acesta este mai prioritar dect operatorul SAU. Acest grup de operatori (&, |, ^) au prioritate mai mica dect a operatorilor relaionali, dar mai mare dect a operatorilor logici (&&, ||). Pentru evitarea memorrii acestor prioriti se recomand folosirea parantezelor n expresiile ce conin operatori. 2.1. Operatorul I la nivel de bit Simbol: & Exemplu: unsigned char i,j; j=i & 0x0F;

108

Operatori de prelucrare la nivel de bit

Descriere: Se realizeaz operaia I ntre biii corespondeni, conform tabelei de adevr cunoscute: 0&0=0 0&1=0 1&0=0 1&1=1 2.2. Operatorul SAU la nivel de bit Simbol: | Exemplu: unsigned char i,j; j=i | 0x0F; Descriere: Se realizeaz operaia SAU ntre biii corespondeni, conform tabelei de adevr cunoscute: 0|0=0 0|1=1 1|0=1 1|1=1 2.3. Operatorul SAU EXCLUSIV la nivel de bit Simbol: ^ Exemplu: unsigned char i,j; j=i ^ 0x0F; Descriere: Se realizeaz operaia XOR ntre biii corespondeni, conform tabelei de adevr cunoscute: 0^0=0 ^1=1 1^0=1 1^1=0 2.4. Operatorul NEGARE la nivel de bit Simbol: ~ Exemplu: unsigned char i,j; j=~i;

Operatori de prelucrare la nivel de bit Descriere: Are ca efect inversarea (complementarea) corespondeni, conform tabelei cunoscute: ~0 = 1 ~1 = 0

109

biilor

2.5. Operatorul DEPLASARE STNGA la nivel de bit Simbol: << Exemplu: unsigned char i,j; j=i << 2; Descriere: Se shifteaz toi biii primului operand, spre stnga, cu un numr de poziii dat de al doilea operand (n cazul exemplului, cu 2 poziii). Din partea dreapt "intr" n numrul rezultat, bii de valoare 0. 2.6. Operatorul DEPLASARE DREAPTA la nivel de bit Simbol: >> Exemplu: unsigned char i,j; j=i >> 2; Descriere: Se shifteaza toi biii primului operand, spre dreapta, cu un numr de poziii dat de al doilea operand (n cazul exemplului, cu 2 poziii). Din partea stng "intr" n numrul rezultat, bii de valoare 0 (n cazul numerelor ntregi pozitive), sau bii de valoare 1 n cazul numerelor cu semn negative (reprezentate n complement fa de 2). 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 S se afieze valoarea n baza 10 a tuturor octeilor ce au biii 0, 2 i 5 egali cu 1 (restul biilor pot fi 0 sau 1). Masca folosit n operaia de testare va avea biii 5, 2, 0 de valoare 1, iar restul biilor sunt 0. Deci, n binar, masca pentru operatorul I, va fi: 0010.0101. n baza 16, aceast masc are valoarea: 0x25 .

110

Operatori de prelucrare la nivel de bit

Sursa programului: #include <stdio.h> #include <conio.h> void main(void) { int i; clrscr(); for(i=0;i<256;i++) if( (i & 0x25)==0x25 ){printf("%d\n",i); getch();} } Programul nr. 2 S se scrie o funcie ce returneaz msb-ul (cel mai semnificativ bit) i lsb-ul (cel mai puin semnificativ) dintr-un octet. Sursa programului: #include <stdio.h> #include <conio.h> void msb_lsb(unsigned char b, unsigned char * adrMsb, unsigned char * adrLsb); void main(void) { unsigned char msb,lsb; unsigned char b=0xF1; clrscr(); msb_lsb(b,&msb,&lsb); printf("msb=%d, lsb=%d",msb,lsb); getch(); } void msb_lsb(unsigned char b, unsigned char * adrMsb, unsigned char * adrLsb) { unsigned char ms, ls; //calcul lsb: if((b&0x01)==0)ls=0; else ls=1; //calcul msb: if((b&0x80)==0)ms=0; else ms=1; *adrMsb=ms; *adrLsb=ls; }

Operatori de prelucrare la nivel de bit

111

Programul nr. 3 S se scrie o funcie ce are ca argumente de intrare doi octei, b1 i b2. Funcia returneaz 1 dac b1 i b2 au acelai numr de bii de 1, i returneaz 0 n caz contrar. Exemplu: Dac b1=1 i b2=2, valoarea returnat este 1. Sursa programului: #include <stdio.h> #include <conio.h> int nr_biti_1(unsigned char b); int compara(unsigned char b1, unsigned char b2); void main(void) { unsigned char b1=0x71; unsigned char b2=0x30; clrscr( ); if( compara(b1,b2) )printf("Au numar egal de biti de 1 !"); else printf("Au numere diferite de biti de 1 !"); getch( ); } int compara(unsigned char b1, unsigned char b2) { int nr_b1,nr_b2; nr_b1=nr_biti_1(b1); nr_b2=nr_biti_1(b2); if(nr_b1==nr_b2)return 1; else return 0; } int nr_biti_1(unsigned char b) { int n1;//numarul de biti de 1 unsigned char masca[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; int i; n1=0; for(i=0;i<8;i++) if( (b&masca[i])!=0 )n1++; return n1; }

112

Operatori de prelucrare la nivel de bit

Programul nr. 4 Se d un octet b. S se calculeze i afieze care este cel mai mare numr ce se poate obine aranjnd n alt ordine biii octetului b. Exemplu: b=6 (n binar 0000.0110). Numrul maxim este max=192 (n binar 1100.0000) Sursa programului: #include <stdio.h> #include <conio.h> #include <math.h> int nr_biti_1(unsigned char b); void main(void) { unsigned char b=6; int nr_1;//numarul de biti de 1 ai lui b int i; int max; nr_1=nr_biti_1(b); //calculul valorii maxime ce se poate obtine: max=0; for(i=1;i<=nr_1;i++) max=max+pow(2,8-i); clrscr( ); printf("\nValoarea maxima ce se poate obtine este %d",max); getch( ); } int nr_biti_1(unsigned char b) { int n1;//numarul de biti de 1 unsigned masca[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; int i; n1=0; for(i=0;i<8;i++) if( (b&masca[i])!=0 )n1++; return n1; }

char

Operatori de prelucrare la nivel de bit

113

Programul nr. 5 Se citesc 2 octei a i b de la tastatur. S se permute prin program urmtorii 4 bii ntre cei 2 octei: nainte de permutare: a: a7 a6 a5 a4 a3 a2 a1 a0 b: b7 b 5 b4 b3 b2 b1 b0 Dup permutare: a: a7 a6 a5 a4 b3 b2 b1 b0 b: b7 b6 b5 b4 a3 a2 a1 a0 Sursa programului: #include <stdio.h> #include <conio.h> void main(void) { unsigned char a,b,a_vechi; int n; clrscr( ); printf("octetul a=");scanf("%d",&n); a=n;//conversie int la unsigned char printf("octetul b=");scanf("%d",&n); b=n; a_vechi=a; a=(a&0xF0) | (b&0x0F); b=(b&0xF0) | (a_vechi&0x0F); printf("\nDupa permutare:\na=%d\nb=%d",a,b); getch( ); } Programul nr. 6 S se scrie o funcie ce are ca parametru de intrare un numr ntreg fr semn. Funcia returneaz valoarea complementat (bit cu bit) a celui mai semnificativ octet din numr. Sursa programului: #include <stdio.h> #include <conio.h> unsigned char complementareOctet(unsigned int nr); void main(void)

114

Operatori de prelucrare la nivel de bit

{ unsigned int nr; clrscr(); nr=0x010F; printf("rezultat=%d",complementareOctet(nr)); getch(); } unsigned char complementareOctet(unsigned int nr) { unsigned char b; //calcul msb: b=nr/256; return ~b; } Programul nr. 7 Folosind operatorii de shiftare, s se scrie o funcie ce returneaz suma biilor de valoare 1 dintr-un octet. Sursa programului: #include <stdio.h> #include <conio.h> int suma(unsigned char b); void main(void) { unsigned char b=0xF2; clrscr(); printf("Suma bitilor de 1 este: %d",suma(b)); getch(); } int suma(unsigned char b) { int s=0; int i; unsigned char mascaCrt; for(i=0;i<8;i++){ mascaCrt=0x01<<i; if((b&mascaCrt)!=0)s++;} return s; }

Operatori de prelucrare la nivel de bit

115

Programul nr. 8 Se citete un octet de la tastatur, cruia i se va calcula paritatea. La acest octet se va adaug bitul de paritate, astfel nct per ansamblu, paritatea cuvntului rezultat s fie par. Se va construi deci un cuvnt (16 bii), n care cel mai puin semnificativ octet este octetul citit, iar restul de 8 bii se obin astfel: BIT8 = 0 dac paritatea octetului citit este par BIT8 = 1 dac paritatea octetului citit este impar BIT9...BIT15 = 0 n final se va afia n format binar cuvntul construit. Sursa programului: #include <stdio.h> #include <conio.h> unsigned int makeParitate(unsigned char b);//returneaza cuvintul //obtinut /din byte-ul b prin adaugare bit de paritate int paritate(unsigned char b);//returneaza paritatea octetului b void convertWord(unsigned int w,int A[]);//converteste cuvintul w in //reprezentarea lui binara (16 biti, memorati in vectorul A) void afisareCuvintInBinar(unsigned int w);//afiseaza cei 16 biti ai lui // w void main(void) { unsigned char b; int i_b; unsigned int w; int c,stop; clrscr( ); stop=0; do{ printf("\n\nTastati un octet (0..255): "); scanf("%d",&i_b); b=i_b; w=makeParitate(b); printf("\n Cuvintul cu bitul de paritate adaugat, in binar, este:\n"); afisareCuvintInBinar(w); printf("\n\n Doriti repetare ? [d/n] : "); c=getch( ); if(c=='n')stop=1; }while(!stop); }

116

Operatori de prelucrare la nivel de bit

unsigned int makeParitate(unsigned char b) { unsigned int word; //Cel mai putin semnificativ octet al lui word este b: word=b; //Bitul 8 din word este 1, daca paritatea lui b este impara, //sau 0, daca paritatea lui b este para. if(paritate(b)==0) word=word | 0x0100; return word; } int paritate(unsigned char b) { //returneaza 1 daca b are un nr par de biti de 1 int nr_1;//nr. de biti de valoare 1 int i; nr_1=0; //testez valoarea lui MSB din b: for(i=1;i<=8;i++){ if( (b & 0x80) != 0) nr_1++; b=b << 1;}//for if ((nr_1 % 2)==0)return 1; //paritate para else return 0; } void afisareCuvintInBinar(unsigned int w) { int A[16]; int i; convertWord(w,A); //afisarea numarului in format binar: for(i=15;i>=0;i--) //pentru i=11,7,3, se afiseaza in fata lui A[i] un blank if( (i==11)||(i==7)||(i==3) )printf(" %d",A[i]); else printf("%d",A[i]); }

Operatori de prelucrare la nivel de bit void convertWord(unsigned int w,int A[]) { //A[0] este lsb, A[15] este msb int i; unsigned int MASCA[16]={0x0001,0x0002,0x0004,0x0008, 0x0010,0x0020,0x0040,0x0080, 0x0100,0x0200,0x0400,0x0800, 0x1000,0x2000,0x4000,0x8000}; //MASCA[0] este pentru obtinerea lsb. for(i=0;i<16;i++) if( (w & MASCA[i]) ==0)A[i]=0; else A[i]=1; }

117

Programul nr. 9 S se scrie o funcie n care se realizeaz, pentru un octet, rotirea spre dreapta cu un bit. Astfel dac reprezentarea binar a octetului este: b7 b6 b5 b4 b3 b2 b1 b0, dup rotire se obine b0 b7 b6 b5 b4 b3 b2 b1 . Sursa programului: #include <stdio.h> #include <conio.h> void r_dreapta(unsigned char * b); void main(void) { unsigned char b; b=0x01; r_dreapta(&b); clrscr( ); printf("Dupa rotire: %d",b); getch( ); } void r_dreapta(unsigned char * b) { //shiftez octetul spre dreapta cu un bit, si la acest octet rezultat //ii impun msb-ul (bitul 7) if( (*b)&0x01 != 0 ) //lsb=1 *b =( (*b)>>1 ) | 0x80; //am fortat msb-ul in 1 else //lsb=0

118
*b

Operatori de prelucrare la nivel de bit =( (*b)>>1 ) & 0x7F; //am fortat msb-ul in 0

} Programul nr. 10 S se scrie o funcie ce permut biii de pe poziiile i i j ai unui octet. Sursa programului: #include <stdio.h> #include <conio.h> void comuta_ij(unsigned char * b, int i, int j); void main(void) { unsigned char a=0xf0; clrscr( ); comuta_ij(&a,0,7); //afisare in hexa: printf("Dupa comutarea bitilor 0 si 7 octetul a=0x%x ",a); getch( ); } void comuta_ij(unsigned char * b, int i, int j) { int bit_i;//valoarea bitului de pe pozitia i (1 sau 0) int bit_j; unsigned char masca_i;//masca pentru a determina valoarea bitului i unsigned char masca_j; unsigned char masca; masca_i=0x01 << i; masca_j=0x01 << j; if( ((*b)&masca_i)==0 )bit_i=0; else bit_i=1; if( ((*b)&masca_j)==0 )bit_j=0; else bit_j=1; //daca bit_i = bit_j dupa comutare octetul ramane acelasi, altfel //trebuie complementati bitii i si j: if(bit_i != bit_j){ masca=masca_i | masca_j; *b = (*b) ^ masca; //operatie XOR. 1 ^ 0 = 1, 1 ^ 1 = 0 } }

Operatori de prelucrare la nivel de bit 4. PROBLEME PROPUSE

119

1. S se afieze paritatea unui numr ntreg fr semn, citit de la tastatur. Se va defini pentru acest scop funcia paritate care are ca intrare un numr ntreg fr semn i care returneaz 1, dac paritatea numrului este par, sau 0 , daca paritatea lui este impar. 2. S se scrie o funcie n care se comut biii i i j dintr-un ntreg fr semn. 3. S se scrie o funcie n care se ncarc toi biii dintr-un octet b, ntr-un vector A. Octetul b i vectorul A, se transmit funciei ca argumente. 4. S se scrie o funcie ce are ca intrare un vector de 8 bii (msb-ul pe prima poziie). Funcia returneaz valoarea calculat a octetului corespunztor. Exemplu: A={0,0,0,1,0,1,1,1}. Va returna 23. 5. S se scrie o funcie ce are ca intrare un octet i returneaz un string ce conine reprezentarea binar a octetului respectiv. Exemplu: octet=23; Scoate ca rezultat irul: "00010111" 6. Fie w, un numr ntreg fr semn. S se calculeze i afieze care este cel mai mare numr ce se poate obine aranjnd n alt ordine biii numrului w. Exemplu: w=6 (n binar: 0000.0000.0000.0110). Numrul maxim este: max = 1100.0000.0000.0000 (n binar)

120

Fiiere FIIERE

1. SCOPUL LUCRRII n aceast lucrare se vor studia instruciunile limbajului C specifice lucrului cu fiiere text i cu fiiere binare. 2. BREVIAR TEORETIC 2.1. Instruciunea fopen Prototip: FILE *fopen(char * fileName, char *mode); Exemplu: FILE * fp; fp=fopen("C:\\abc.dat","rb"); Descriere: Este utilizat pentru a deschide fiierul al crui nume extern este dat de primul argument, n modul specificat de al doilea argument. Este o instruciune ce se folosete att pentru fiiere text ct i pentru fiiere binare. 2.2. Instruciunea fclose Prototip: int fclose(FILE *stream); Exemplu: FILE * fp; fclose(fp); Descriere: Este folosit pentru a nchide fiierul cu numele intern dat de argumentul ei (fiier anterior deschis cu fopen). Este o instruciune ce se folosete att pentru fiiere text ct i pentru fiiere binare. 2.3. Instruciunea fwrite Prototip: int fwrite(void * adresa, int size, int nrArticole, FILE *fp); Exemplu: int x; FILE *fp; ... fwrite(&x,sizeof(int),1,fp);

Fiiere

121

Descriere: Scrie la poziia curent din fiierul cu numele intern fp, un numr de nregistrri dat de al treilea argument (nrArticole), fiecare nregistrare avnd un numr de octei dat de argumentul doi (size). nregistrrile de scris ncep de la adresa specificat de primul argument. Este o instruciune specific fiierelor binare. 2.4. Instruciunea fread Prototip: int fread(void * adresa, int size, int nrArticole, FILE *fp); Exemplu: int x; FILE *fp; ... freadf(&x,sizeof(int),1,fp); Descriere: Citete n variabila a crei adres este dat de primul argument (adresa), un numr de nregistrri din fiierul fp, ncepnd din poziia curent a pointerului de fiier. Numrul de nregistrri ce se citesc este dat de argumentul trei (nrArticole), fiecare nregistrare avnd mrimea n octei dat de argumentul doi (size). Este o instruciune specific fiierelor binare. 2.5. Instruciunea fseek Prototip: int fseek(FILE *stream, long offset, int referinta); Exemplu: fseek(fp,0,SEEK_SET); Descriere: Mut pointerul de fiier la o nou poziie, aflat la un offset n octei dat de argumentul doi, fa de poziia de referin specificat de argumentul trei. Offsetul poate fi pozitiv sau negativ. Este o instruciune specific fiierelor binare. 2.6. Instruciunea ftell Prototip: long ftell(FILE * stream); Exemplu: L=ftell(fp);

122

Fiiere

Descriere: Returneaz valoarea n octei a poziiei pointerului de fiier, fa de nceputul fiierului. Este o instruciune specific fiierelor binare. 2.7. Instruciunea fprintf Prototip: int fprintf(FILE *stream, char *format [, variabile, ...]); Exemplu: int nrCrt; FILE *fp; .... fprintf(fp,"%d",nrCrt); Descriere: Scrie date, sub controlul unor formate, ntr-un fiier. Este o instruciune specific fiierelor text. Datele se scriu ncepnd de la poziia curent a pointerului de fiier. 2.8. Instruciunea fscanf Prototip: int fscanf(FILE *stream, char *format [, adresa, ...]); Exemplu: int nrCrt; FILE *fp; ... fscanf(fp,"%d",&nrCrt); Descriere: Citete date dintr-un fiier, sub controlul unor formate. Este o instruciune specific fiierelor text. Datele se citesc ncepnd de la poziia curent a pointerului de fiier. 2.9. Instruciunea fgetc Prototip: int fgetc(FILE *stream); Exemplu: FILE *fp; int c; ... c=fgetc(fp);

Fiiere

123

Descriere: Citete caracterul de pe poziia curent, dintr-un fiier. Este o instruciune specific fiierelor text. 3. DESFURAREA LUCRRII Se vor edita i apoi executa programele descrise n continuare. Programul nr. 1 S se creeze prin program urmtorul fiier text, ce conine 10 linii a cte 10 numere fiecare. ntre cifrele de pe o linie sunt 2 blank-uri. 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 6 8 9 0 1 2 3 4 5 7 8 9 0 1 2 3 4 5 7 8 9

Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> void main(void) { FILE * fp; int i,j; clrscr( ); fp=fopen("c:\\cifre.txt","wt"); if(fp==NULL){ printf("Nu se poate crea fisierul c:\\cifre.txt !"); getch( ); exit(1);} for(i=0;i<=9;i++){ for(j=1;j<=10;j++)fprintf(fp," %d",i); //trece la linia urmatoare: fprintf(fp,"\n");

124

Fiiere

}//end for i fclose(fp); printf("A fost creat fisierul c:\\cifre.txt . "); getch( ); } Programul nr. 2 S se afle suma numerelor dintr-un fiier text de numere ntregi. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define NUME_F "c:\\numere.txt" //numele fisierului text: void main(void) { FILE * fp; int rez; //rezultatul intors de functia fscanf int nrCrt; int suma; clrscr(); //se deschide fisierul text, pentru citire: fp=fopen(NUME_F,"rt"); if(fp==NULL){ printf("Nu se poate deschide fisier !"); getch(); exit(1);} suma=0; /* SE REPETA se citesc pe rand,toate numerele din fisier, adaugandu-se fiecare numar la suma totala PANA CAND se atinge sfarsitul de fisier */ for(;;){ rez=fscanf(fp,"%d",&nrCrt); if(rez==EOF)break; //s-a atins sfarsit de fisier suma=suma+nrCrt;} printf(Suma=%d,suma); } Programul nr. 3 S se concateneze doua fiiere text, ntr-un al treilea fiier text.

Fiiere Sursa programului: #include <conio.h> #include <stdio.h> #include <stdlib.h> void main() { int c; clrscr(); FILE *fp1=fopen("c:\\a.txt","rt"); if (fp1==NULL) exit(1); FILE *fp2=fopen("c:\\b.txt","rt"); if (fp2==NULL) exit(1); FILE *fp3=fopen("c:\\ab.txt","wt"); if (fp3==NULL) exit(1); //copiem pe primul, in al treilea: for(;;){ c=fgetc(fp1); if (c==EOF) break; fputc(c,fp3);} //copiem pe al doilea, in continuarea celui de-al treilea: for(;;){ c=fgetc(fp2); if (c==EOF) break; fputc(c,fp3);} fclose(fp1); fclose(fp2); fclose(fp3); }

125

Programul nr. 4 Se citesc de la tastatur 20 de numere ntregi care se memoreaz ntr-o matrice A de 4 linii i 5 coloane. S se copieze coninutul matricii ntrun fiier text ce are acelai format ca i matricea (4 linii i 5 coloane ). Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> void main(void) { FILE * fp;

126

Fiiere

int i,j; int A[4][5]; clrscr( ); for(i=0;i<4;i++) for(j=0;j<5;j++){ printf("Numarul %d = ",5*i+j); scanf("%d",&A[i][j]);} fp=fopen("c:\\A_4_5.txt","wt"); if(fp==NULL){ printf("Nu se poate crea fisierul C:\\A_4_5.txt !"); getch( ); exit(1);} for(i=0;i<4;i++){ for(j=0;j<5;j++)fprintf(fp," %d",A[i][j]); //trece la linia urmatoare: fprintf(fp,"\n"); }//end for i fclose(fp); printf("A fost creat fisierul c:\\A_4_5.txt . "); getch( ); } Programul nr. 5 S se creeze prin program, N fiiere text de numere cu valorile 1 sau +1, obinute aleator. Fiecare fiier conine NL linii i NC coloane. Parametrii N, NL i NC se citesc de la tastatur. Primul fiier va avea numele: C:\date1.txt, al doilea: C:\date2.txt, al treilea: C:\date3.txt, .a.m.d. Exemplu: Pentru NL=2 i NC=5 , un fiier tipic creat prin program, este de forma: 1 -1 -1 -1 1 -1 1 -1 -1 -1 Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> void main(void)

Fiiere { int NL;//numarul de linii din fisier int NC;//numarul de coloane din fisier int N;//numarul de fisiere int i,j,k; char numeCrt[81]; char strNrCrt[7]; FILE * fp; clrscr(); printf(N=); scanf(%d,&N); printf(NL=); scanf(%d,&NL); printf(NC=); scanf(%d,&NC); randomize(); //se construiesc cele N fisiere: for(i=1;i<=N;i++){ //obtinerea numelui extern al fisierului numarul i: //conversia valorii intregi i, in string: itoa(i,strNrCrt,10);//al treilea parametru este baza de numeratie //a primului parametru (i) strcpy(numeCrt,"C:\\date"); strcat(numeCrt,strNrCrt); strcat(numeCrt,".txt"); fp=fopen(numeCrt,"wt"); if(fp==NULL){ printf("\n Nu se poate deschide fisierul nr. %d",1); getch(); exit(1);} //scrierea celor NLxNC numere aleatoare in fisierul curent, i: for(j=0;j<NL;j++){ for(k=0;k<NC;k++) if(random(2)==0)fprintf(fp,"-1 "); else fprintf(fp," 1 "); //se trece la urmatoarea linie: fprintf(fp,"\n"); }//end for j //inchiderea fisierului curent: fclose(fp); }//end for i }

127

128

Fiiere

Programul nr. 6 S se creeze prin program un fiier binar ce conine urmtorii 100 de octei: 10 octei de valoare 0, 10 octei de valoare 1, ..., 10 octei de valoare 9. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> void main(void) { FILE * fp; int i,j; clrscr( ); fp=fopen("c:\\cifre.bin","wb"); if(fp==NULL){ printf("Nu se poate crea fisierul c:\\cifre.bin !"); getch( ); exit(1);} for(i=0;i<=9;i++) for(j=1;j<=10;j++)fwrite(&i,1,1,fp); fclose(fp); printf("A fost creat fisierul c:\\cifre.bin . "); getch( ); } Programul nr. 7 S se adauge la sfritul unui fiier existent, un octet de paritate calculat ca suma modulo 2 a tuturor octeilor din fiierul iniial. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> void main(void) { FILE * fp; int i; int L; //lungimea in octeti a fisierului initial unsigned char octetCrt;//octetul curent citit din fisier unsigned char octetCalculat;

Fiiere

129

clrscr( ); fp=fopen("abc.dat","r+b"); if(fp==NULL){ printf("Nu pot deschide fisierul abc.dat !"); getch( ); exit(1);} fseek(fp,0,SEEK_END); L=ftell(fp); fseek(fp,0,SEEK_SET); octetCalculat=0; for(i=0;i<L;i++){ fread(&octetCrt,1,1,fp); octetCalculat=octetCalculat ^ octetCrt; } fseek(fp,0,SEEK_END); //Fara aceasta instructiune, scrie la sfarsitul //fisierului, un octet de alta valoare, nu cel specificat prin fwrite ! //(Nu se poate in modul r+, ca imediat dupa o operatie de read sa // urmeze una de write.) fwrite(&octetCalculat,1,1,fp); fclose(fp); clrscr( ); //Verificarea: fp=fopen("abc.dat","rb"); for(i=0;i<L+1;i++){ fread(&octetCrt,1,1,fp); printf("\n%d",octetCrt);} fclose(fp); getch( ); } Programul nr. 8 Se va crea prin program un fiier binar "ran.bin", ce conine 200 de numere, generate ca numere aleatoare, n gama 0..255 . Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define NUME_F "ran.bin" #define NR_VALORI 200 void main(void)

130

Fiiere

{ FILE * fp; int i; unsigned char nrCrt; clrscr( ); randomize( ); fp=fopen(NUME_F,"wb"); if(fp==NULL){ printf("Nu pot deschide fisier !"); getch( ); exit(1);} for(i=0;i<NR_VALORI;i++){ nrCrt=random(256); fwrite(&nrCrt,sizeof(unsigned char),1,fp);}//for fclose(fp); printf("\n S-a creat fisierul specificat !"); getch( ); } Programul nr. 9 S se calculeze i afieze maximul dintr-un fiier binar de octei. Pentru testare se va folosi fiierul "ran.bin", creat prin programul anterior. Sursa programului: #include <stdio.h> #include <conio.h> #include <stdlib.h> #define NUME_F "ran.bin" void main(void) { FILE * fp; int i; unsigned char nrCrt; int L; clrscr( ); fp=fopen(NUME_F,"rb"); if(fp==NULL){ printf("Nu pot deschide fisier !"); getch( );

Fiiere

131

exit(1);} //afla lungimea fisierului: fseek(fp,0,SEEK_END); L=ftell(fp); if(L==0){ printf("\nFisierul este gol !");getch( );exit(1);} //readuce pointerul de fisier la inceputul fisierului: fseek(fp,0,SEEK_SET); fread(&maxim,1,1,fp);//initializeaza maximul cu primul numar din //fisier //citeste octet cu octet tot fisierul for(i=1;i<L;i++){ fread(&nrCrt,1,1,fp); if(nrCrt > maxim)maxim=nrCrt;} fclose(fp); printf("\n Maximul gasit este: %d",maxim); getch( ); } 4. PROBLEME PROPUSE 1. S se scrie programul prin care un fiierul oarecare este citit i afiat pe ecran, octet cu octet. 2. S se afieze cea mai lung linie dintr-un fiier text. 3. Se d un fiier text de numere ntregi. S se calculeze cel mai mare divizor comun al acestor numere. 4. S se calculeze i afieze numrul de valori nule dintr-un fiier binar de octei. 5. S se creeze un fiier binar, ce are numele C:\elevi.dat, n care sunt copiate datele citite de la tastatur, pentru toi elevii unei clase. Pentru fiecare elev, se citesc urmtoarele informaii: - numele - prenumele - media

S-ar putea să vă placă și

  • PR EA
    PR EA
    Document94 pagini
    PR EA
    sonic8659
    Încă nu există evaluări
  • Automatizari Referate Lab
    Automatizari Referate Lab
    Document19 pagini
    Automatizari Referate Lab
    Daniela Ciucnaru
    Încă nu există evaluări
  • Curs DEP
    Curs DEP
    Document137 pagini
    Curs DEP
    moproescu
    Încă nu există evaluări
  • Format Referat
    Format Referat
    Document1 pagină
    Format Referat
    Daniela Ciucnaru
    Încă nu există evaluări
  • Materiale Pentru Industria Electronic A Si Electrotehnica
    Materiale Pentru Industria Electronic A Si Electrotehnica
    Document113 pagini
    Materiale Pentru Industria Electronic A Si Electrotehnica
    Dan Laptoiu
    Încă nu există evaluări
  • Cvtemplate Ro Ro
    Cvtemplate Ro Ro
    Document3 pagini
    Cvtemplate Ro Ro
    Daniela Ciucnaru
    Încă nu există evaluări
  • Examen IA
    Examen IA
    Document28 pagini
    Examen IA
    Daniela Ciucnaru
    Încă nu există evaluări
  • Monozaharide
    Monozaharide
    Document4 pagini
    Monozaharide
    Daniela Ciucnaru
    Încă nu există evaluări
  • 2 AuTOCAD
    2 AuTOCAD
    Document6 pagini
    2 AuTOCAD
    Daniela Ciucnaru
    Încă nu există evaluări
  • Dacia Literara
    Dacia Literara
    Document3 pagini
    Dacia Literara
    Daniela Ciucnaru
    Încă nu există evaluări
  • Magia Stiintei
    Magia Stiintei
    Document36 pagini
    Magia Stiintei
    Daniela Ciucnaru
    Încă nu există evaluări
  • Clasicism
    Clasicism
    Document2 pagini
    Clasicism
    Daniela Ciucnaru
    Încă nu există evaluări