Вы находитесь на странице: 1из 35

PROGRAMARE IN LIMBAJUL C PROGRAMARE IN LIMBAJUL C 1 1. PROGRAME CU DATE NUMERICE 2 PROBLEME PROPUSE 12 SOLUTII LA PROBLEME PROPUSE 14 2.

PROGRAME CU VECTORI SI MATRICE 21 EXEMPLE DE PROGRAME 21 PROBLEME PROPUSE 24 SOLUTII LA PROBLEME PROPUSE 26 3. DEFINIREA SI UTILIZAREA DE FUNCTII 38 EXEMPLE DE PROGRAME 38 PROBLEME PROPUSE 43 SOLUTII LA PROBLEME PROPUSE 45 4. PROGRAME SI FUNCTII CU SIRURI DE CARACTERE EXEMPLE DE FUNCTII SI PROGRAME 60 PROBLEME PROPUSE 65 SOLUTII LA PROBLEME PROPUSE 67 5. PROGRAME SI FUNCTII CU STRUCTURI 76 EXEMPLE DE PROGRAME SI FUNCTII 76 PROBLEME PROPUSE 82 SOLUTII LA PROBLEME PROPUSE 84 6. PROGRAME CU DATE ALOCATE DINAMIC 93 EXEMPLE DE PROGRAME 93 PROBLEME PROPUSE 97 SOLUTII LA PROBLEME PROPUSE 98

60

1. PROGRAME CU DATE NUMERICE (UTILIZARE INSTRUCTIUNI SI FUNCTII DE I/E) EXEMPLE DE PROGRAME Exemple de afisare pe ecran si citire de la tastatura E1.1 Afisarea unui text constant pe ecran. #include <stdio.h> void main () { printf (" Text afisat pe ecran"); } E1.2 Afisarea valorilor unor variabile intregi #include <stdio.h> void main () { int a=2, b=-3; printf ("%d %d \n", a,b); // printf ("%i %i \n",a,b); // %i este identic cu %d } E1.3 Afisare text constant si valori variabile intregi #include <stdio.h> void main () {

int a=2, b=-3; printf ("a= %d, b= %d \n", a,b); } E1.4 Citire si afisare numar intreg #include <stdio.h> void main () { int n; printf ("n= "); scanf ("%d", &n); printf ("s-a citit %d ", n); } E1.5 Citire si afisare numer intreg lung #include <stdio.h> void main () { long a; scanf ("%ld", &a); printf ("s-a citit %ld ", a); } E1.6 Citire si afisare numar real #include <stdio.h> void main () { float x; printf ("x= "); scanf ("%f", &x); printf ("s-a citit %f ", x); } E1.7 Afisare rezultat functie de tip "double" #include <stdio.h> #include <math.h> void main () { printf (" sqrt(2)=%lf", sqrt(2)); } E1.8 Afisare rezultat functie, dupa conversie la intreg. #include <stdio.h> #include <math.h> void main () { printf (" sqrt(25)=%d", (int) sqrt(25)); } E1.9 Afisare cu o precizie dorita #include <stdio.h> #include <math.h> void main () { printf ("%6.0f", sqrt(25)); } E1.10 Afisarea unor numere pe coloane de dimensiuni egale

#include <stdio.h> void main () { int a,b,c; scanf ("%d%d%d",&a,&b,&c); printf ("%6d%6d%6d \n",a,b,c); } E1.11 Afisare numere reale foarte mari sau foarte mici (cu exponent) #include <stdio.h> #include <math.h> void main () { double x,y ; x=exp(20); y=pow(10,10); printf ("%e %e \n",x,y); } Exemple cu expresii si instructiuni de atribuire E1.12 Calcul arie triunghi cu laturi date #include <stdio.h> #include <math.h> void main () { float a,b,c,p,s; printf("Lungimi laturi:"); scanf ("%f%f%f",&a,&b,&c); p=(a+b+c)/2; s=sqrt(p*(p-a)*p-b)*(p-c)); printf ("%.2f \n", s); // cu 2 zecimale dupa virgula }

E1.13 Calculul unghiuri dintr-un triunghi (in radiani) #include <stdio.h> #include <math.h> void main () { float a,b,c,ua,ub,uc; printf("Lungimi laturi:"); scanf ("%f%f%f",&a,&b,&c); ua = acos ( (b*b+c*c-a*a)/(2*b*c) ); ub = acos ( (a*a+c*c-b*b)/(2*a*c) ); uc = acos ( (b*b+a*a-c*c)/(2*a*b) ); printf ("%6.2f \n",ua+ub+uc); }

// PI=3.14

E1.14 Calcul lungime si panta segment dintre doua puncte date #include <stdio.h> #include <math.h> #include <values.h> void main () { float x1,y1,x2,y2, d,u; printf ("x1,y1: "); scanf("%f%f",&x1,&y1); printf ("x2,y2: "); scanf("%f%f",&x2,&y2);

d= sqrt ( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ); if ( x2 != x1) u = atan ((y2-y1)/(x2-x1)); else u= MAXFLOAT; // verticala (panta infinita) printf ("%e %e \n", d,u); } E1.15 Afisare cat si rest impartire intreaga numere cu semn. #include <stdio.h> void main () { int a=7,b=2; printf ("a=%d printf ("a=%d printf ("a=%d printf ("a=%d } Exemple cu instructiuni "if" si "switch" Directiva "include <stdio.h>" si altele necesare nu mai apar in toate exemplele, dar trebuie adaugate pentru compilarea corecta a programelor. E1.16 Verifica daca un caracter dat este o litera ( fie mare, fie mica) void main () char ch; ch= getchar(); if ( ch >='a' && ch <='z' ch >='A' && ch <='Z' ) printf ("este litera \n"); else printf (" nu este litera \n"); } E1.17 Determinare maxim dintre trei numere intregi void main () { int a,b,c,max; scanf ("%d%d%d",&a,&b,&c); max=a; if (max < b) max=b; if (max < c) max=c; printf("maxim este %d\n", max); } E1.18 Determinare tip triunghi cu laturi date void main () { int a,b,c; printf ("laturi triunghi: "); scanf("%i%i%i",&a,&b,&c); if (a<b+c && b<a+c && c<a+b) if (a==b && b==c) printf ("echilateral \n"); else

b= b= b= b=

%d %d %d %d

c=%d c=%d c=%d c=%d

r=%d r=%d r=%d r=%d

\n", \n", \n", \n",

a, b, a/b, a%b); // c=3 r=1 -a, b, -a/b, -a%b); // c=-3 r=-1 a, -b, a/-b, a%-b); // c=-3 r=1 -a, -b, -a/-b, -a%-b); //c=3 r=-1

if (a==b a==c b==c) printf ("isoscel \n"); else printf("oarecare \n"); else printf ("imposibil \n"); } E1.19 Verifica existenta unui fisier inainte de creare fisier // verifica existenta fisier inainte de crearea lui #include <stdio.h> void main () { FILE *f; char numef[100]; // nume fisier char rasp; // raspuns la intrebare puts (" Creare fisier nou "); puts("Nume fisier:"); gets(numef); f = fopen(numef,"r"); // cauta fisier (prin deschidere in citire) if ( f ) { // daca exista fisier cu acest nume printf ("Fisierul exista deja! Se sterge ? (d/n) "); rasp= getchar(); // citeste raspuns if ( rasp =='n' rasp =='N') return; // terminare program } f=fopen(numef,"w"); // deschide fisier ptr creare fputs (numef,f); // scrie in fisier chiar numele sau fclose(f); } E1.20 Determinare numar de zile dintr-o luna void main () { int zile, luna, an; printf ("an:"); scanf("%d",&an); printf("nr.luna (1-12): "); scanf("%d",&luna); switch (luna) { case 2: if (an%4) zile=28; else zile=29; break; case 4: case 6: case 9: case 11: zile=30; break; default: zile=31; break; } printf ("luna %d are %d zile \n",luna,zile); }

Exemple cu instructiuni "for", "while", "do" E1.21 Citirea unui sir de numere, dupa citirea lungimii sirului. #include <stdio.h> #include <values.h> // afisare valoare maxima dintr-un sir void main () { int n,i, a,amax;

printf("n="); scanf("%d",&n); amax=-MAXINT; // cel mai mic intreg for (i=0;i<n;i++) { scanf("%d",&a); if (amax < a) amax=a; } printf("%d\n",amax); } E1.22 Citirea unui sir de numere terminat cu caracterul "End of File" recunoscut de sistem ( Ctrl-Z in DOS si Windows). #include <stdio.h> // suma valorilor dintr-un sir de numere void main () { float a,sum; sum=0; while ( scanf("%f",&a) != EOF) sum=sum+a; printf("%f \n",sum); } E1.23 Citirea mai multor siruri de numere terminate fiecare cu un zero. Sfarsitul datelor este marcat tot cu zero. Exemplu: 1 2 3 0 4 5 0 7 8 9 0 0 #include <stdio.h> // sume valori din mai multe siruri terminate cu zero void main () { float a,sum,m; do { m=sum=0; // m=lungime sir, sum = suma sir do { scanf("%f",&a); // un numar a dintr-un sir if (a==0) break; sum=sum+a; m++; // aduna a la suma si numara } while (a); if (m) // daca sir de lungime nenula printf("%f \n",sum); } while (m); } Obs. Situatia de mai sus apare la verificarea unor programe cu mai multe seturi de date (memorate probabil intr-un fisier), printr-o singura rulare a fiecarui program. E1.24 Afisarea unui numar intreg fara semn in binar folosind extragerea selectiva de biti cu o masca ce contine un singur bit 1. void main () { int n; // un intreg printf("n= "); scanf("%d",&n); unsigned int mask = 1<<15; // bitul 15 =1, ceilalti zero (1 28) while (mask) { printf ("%d", (mask & d) ? 1: 0); mask >>= 1; // deplasare masca la dreapta cu un bit }

printf("\n"); } E1.25 Determina cel mai mare divizor comun a doi intregi (ineficient). void main () { int a,b,d; printf ("a,b: "); scanf("%d%d",&a,&b); d= a< b ? a : b; // d= minim(a,b); while ( a%d b%d ) // cat timp d nu este divizor comun d=d-1; printf ("cmmdc=%d\n",d); } E1.26 Determina cel mai mare divizor comun a doi intregi (alg. lui Euclid). void main () { int a,b,r; printf ("a,b: "); scanf("%d%d",&a,&b); while (r = a%b) { a=b; b=r; } printf ("cmmdc= %d\n", b); }

E1.27 Varianta cu "do-while" pentru algoritmul lui Euclid void main () { int a,b,r; printf ("a,b: "); scanf("%d%d",&a,&b); if ( a%b==0) { printf ("%d \n",b); return; } do { r=a%b; a=b; b=r; } while (r); printf("%d \n",a); } E1.28 Ciclu in ciclu. Numararea numerelor prime mai mici ca un intreg dat n. #include <stdio.h> main () { int n,m,d,np ; printf ("n= "); scanf ("%d",&n); if (n < 4) { printf ("%d\n",n); // primele 3 numere prime return; } np=3; // vor fi cel putin 3 numere prime for (m=5;m<=n;m=m+2) { // incearca numerele impare m for (d=3;d<m;d=d+2) // cu toti divizorii posibili d if (m % d ==0) break;

if (d>=m) np++; } printf ("%d\n",np); }

// daca m este prim // contor de numere prime

E1.29 Suma unei serii definite printr-o relatie de recurenta intre termeni. // suma seriei Taylor pentru void main () { float x,y,t; int k; scanf ("%f",&x); y=0; t=1; k=1; while ( t > 0) { y=y+t; t=t*x/k; k++; } printf ("%15.6f %15.6f } e^x cu precizie maxima permisa de "float"

// suma seriei // t = termen curent // termenii scad cand creste k // aduna termen la suma // calcul termen urmator // rang termen \n",y, exp(x));

// varianta cu instructiunea "for" void main () { float x,y,t; int k; scanf ("%f",&x); y=0; // suma seriei for (k=1,t=1; t> 0; k++) { y=y+t; // aduna termen la suma t=t*x/k; // calcul termen urmator } printf ("%15.6f %15.6f \n",y, exp(x)); } E1.30 Program care afiseaza un meniu de optiuni si trateaza fiecare optiune #include <stdio.h> #include <conio.h> void main () { int a,b; char opt; // cod optiune (un caracter) do { // afisare meniu clrscr(); // sterge ecran printf ("\n\t A = Adunare \n\t S = Scadere \n\t M = inmultire"); printf("\n\t D = Impartire \n\t \n\t X = Iesire \n\n"); printf ("\t Optiune: "); // citire si tratare optiune fflush(stdin); opt=getchar(); if (opt=='x' opt=='X') return; printf ("\n\t Doi intregi: "); scanf("%d%d",&a,&b); printf("\n\t Rezultat="); switch (opt) { case 'a': case 'A': printf (" %d", a+b); break; case 's': case 'S': printf (" %d", a-b); break; case 'm': case 'M': printf (" %d", a*b); break; case 'd': case 'D': printf (" %d", a/b); break; } fflush(stdin); getchar(); } while (1);

} E1.31 Afisarea in hexazecimal a octetilor din mai multe numere de tip "float" void main () { float f; char *p; int i; // afisare octeti in hexa (float) for ( f=0; f<10;f=f+0.5) { printf ("%6.2f\t",f); // afisare numar p=(char*) &f; // adresa primului octet for (i=0;i<sizeof(f);i++) // afisare octeti printf("%02x ", *p++); // pe cate 2 cifre hexa, cu spatii intre ei printf("\n"); } } PROBLEME PROPUSE P1.1 Program care citeste coordonatele (x,y) ale unui punct din plan si afiseaza numarul cadranului in care se afla (1,2,3,4). Se vor verifica succesiv semnele valorilor x si y. S-ar putea folosi instructiunea "switch"? P1.2 Program pentru calculul sumei a doua intervale de timp exprimate in ore, minute si secunde, cu si fara instructiunea 'if'. (rezultatul este exprimat tot in ore, minute, secunde). Exemplu : h1:m1:s1 = 02:49:48 ; h2:m2:s2 = 10:17:35 rezultat = 13:07:23 P1.3 Program pentru calculul timpului scurs intre doua momente de timp exprimate in ore, minute si secunde (cu si fara "if"). Exemplu : h1:m1:s1 = 13:07:23 ; h2:m2:s2 = 02:49:48 rezultat = 10:17:35 P1.4 Program pentru determinarea celui mai mare intreg pentru care se mai poate calcula corect factorialul sau, succesiv pentru tipurile "int", "long", "float" si "double". Indicatie: Se compara k!/k cu (k-1)! si daca difera se afiseaza k. P1.5 Program care aduna valoarea x de n ori, ca "float" si ca "double", si afiseaza sumele sx si sy. sx este de tip "float",iar sy de tip "double". Se vor lua pe r nd : x=0.1 n=100 x=0.01 n=1000 x=0.001 n=10000 Se vor afisa sumele partiale la fiecare n/10 termeni adunati, cu pauza dupa fiecare 10 linii afisate ( pauza realizata cu functia "getchar"). P1.6 Program pentru calculul combinarilor de n luate cite m , pentru n=10 si m intre 1 si 10, prin doua metode : (a) Folosind relatia de recurenta: C(n,k) = C(n,k-1) * (n-k+1)/k ptr. k=1,m si C(n,0)=1 (b) Folosind relatia de calcul: C(n,m) = n!/ (m!*(n-m)!) P1.7 Program pentru afisarea echivalentului binar al unui numar natural (intreg cu semn) dat. Exemple: 11=1011, 25 =1001, 23= 10111.

Algoritm: Se repeta impartirea la puteri descrescatoare ale lui 2, iar caturile sunt cifrele binare. Restul impartirii devine noul deimpartit. Varianta: se foloseste o masca binara cu un singur bit 1 (deplasat mereu la dreapta), cu care se extrag biti succesivi din numar. P1.8 Program pentru calculul si afisarea radacinii patrate a unor numere folosind urmatoarea relatie de recurenta intre doua aproximatii succesive r1 si r2 ale radacinii lui x : r2 = ( r1 + x/r1)/2 . Aproximatia initiala r1 poate fi orice valoare ( se va lua r1=x/2). Relatia de recurenta se aplica atata timp cat r1 este diferit de r2. Se va afisa pentru verificare si rezultatul functiei sqrt(x), pentru primele 20 de numere pare. P1.9 Program pentru afisarea tuturor numerelor naturale de 2 cifre care au cel putin 7 divizori nebanali (altii decit 1 si numarul respectiv). P1.10 Program pentru afisarea numarului maxim de divizori ai unui numar natural de n cifre ( n<=5 sau n<=10). Se va completa programul cu afisarea celui mai mare (celui mai mic) numar cu numar maxim de divizori. P1.11 Program pentru afisarea tuturor descompunerilor unui numar natural dat prin sume de numere naturale consecutive. Exemplu: 15 = 1+2+3+4+5 = 4+5+6 = 7+ 8 P1.12 Program pentru afisarea numerelor perfecte mai mici ca o valoare data. (Un numar perfect este un numar egal cu suma tuturor divizorilor sai). P1.13 Program care calculeaza valoarea functiilor sin(x) si cos(x) ca suma a seriei de puteri si afisare alaturi de rezultatul functiilor de biblioteca. sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ... cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + ... Se vor insuma toti termenii mai mari ca zero in valoare absoluta. Observati ce se afiseaza pentru valori mari ale lui x si de ce este necesara reducerea unghiului x la o valoare mai mica ca 2*PI. P1.14 Program care determina numarul de zerouri cu care se termina produsul a n numere naturale date (fara a efectua produsul si fara vectori). Indicatie: Numarul de zerouri terminale este dat de numarul produselor 2*5 din produsul celor n numere, deci de minimul dintre numarul de cifre 2 si numarul de cifre 5 care apar in produs. Se vor aduna puterile lui 2 si lui 5 din fiecare numar dat si se determina minimul dintre ele. Exemplu: n=3, a=15, b=12, c=25 nr cifre 2 = 0 + 2 + 0 = 2 nr cifre 5 = 1 + 0 + 2 = 3 min (2,3)=2 deci produsul a*b*c are 2 zerouri la sfirsit (este 4500) P1.15 Program pentru descompunerea unui numar natural dat in factori primi. Se vor afisa factorii primi si puterile (exponentii) lor. Exemplu: 60 = 2^2 * 3 ^1 * 5^1

2. PROGRAME CU VECTORI SI MATRICE EXEMPLE DE PROGRAME E2.1 Citire-scriere vector cu numerotare componente de la zero

// Citirea si afisarea unui vector de numere intregi #include <stdio.h> void main () { int a[100],n,i; printf("n="); scanf("%d",&n); // dimensiune vector printf ("%d numere intregi:\n",n); // citire vector for (i=0;i<n;i++) scanf("%d",&a[i]); // afisare vector for (i=0;i<n;i++) printf ("%d ",a[i]); printf("\n"); } E2.2 Vectori cu numerotare de la 1 a elementelor // Citirea coordonatelor a n puncte din plan // (x[1],y[1]),...(x[n],y[n]) #define M 100 // nr maxim de puncte void main() { float x[M+1],y[M+1]; // max 100 de puncte int n,k; printf("nr.puncte:"); scanf("%d",&n); printf ("Coordonate puncte: \n"); for (i=1;i<=n;i++) scanf ("%f%f",&x[i],&y[i]); ... }

E2.3 Initializare partiala vector // Generare vector cu primele n numere Fibonacci #include <stdio.h> void main () { long fib[100]={1,1}; // celelalte elemente sunt zero int n,i; printf ("n="); scanf("%d",&n); for (i=2; i<=n && fib[i]>0 ;i++) fib[i]=fib[i-1]+fib[i-2]; for (i=0; i<=n;i++) printf ("%ld ",fib[i]); } E2.4 Cautare secventiala intr-un vector (prima si ultima aparitie a numarului cautat). # include <stdio.h> void main () { int a[] ={ 3,5,2,6,8,1,7,4,2,4,5,3} ; // un sir de intregi int n,i,i1,i2, b; // b= valoare cautata // repeta citire b si cautare in a n=sizeof(a)/sizeof(a[0]); //lungime vector initializat while ( scanf("%d",&b) ==1) { // cauta prima aparitie i1=-1; for (i=0; i<n && a[i] != b ;i++)

; if (i<n) i1=i; // cauta ultima aparitie i2=-1; for (i=n-1; i>=0 && b!=a[i];i--) ; if (i>=0) i2=i; // scrie rezultate if ( i1<0 i2<0) printf ("%d negasit \n",b); else printf ("prima= %d, ultima=%d \n", i1,i2); } } Obs. In expresia (i<n && b!=a[i]) ordinea celor 2 conditii este esentiala ! E2.5 Declarare si utilizare matrice // Generare matrice unitate #define M 20 // nr maxim de linii si de coloane void main () { float unit[M][M]; int i,j,n; printf("nr.linii/coloane: "); scanf("%d",&n); if (n > M) return; for (i=0;i<n;i++) for (j=0;j<n;j++) if (i !=j ) unit[i][j]=1; else unit[i][j]=0; ... } E2.6 Initializare matrice cu zerouri // Generare matrice unitate #define M 20 // nr maxim de linii si de coloane void main () { float u[M][M]={0}; int i,j,n; printf("nr.linii/coloane: "); scanf("%d",&n); for (i=0;i<n;i++) u[i][i]=1; ... } E2.7 Citire-scriere matrice de reali void main () { int nl,nc,i,j; float a[20][20]; // citire matrice printf("nr.linii: "); scanf("%d",&nl); printf("nr.coloane: "); scanf("%d",&nc); if (nl >20 nc >20) { printf("Eroare: dimensiuni > 20 \n"); return; } for (i=0;i<nl;i++)

for (j=0;j<nc;j++) scnaf ("%f", &a[i][j]); // afisare matrice for (i=0;i<nl;i++) { for (j=0;j<nc;j++) printf ("%f ",a[i][j]); printf ("\n"); } }

PROBLEME PROPUSE P2.1 Program care citeste un sir de note si calculeaza media notelor de trecere ( >= 5) si ponderea notelor sub 5 in totalul notelor (procentual). P2.2 Program care citeste un sir de note (intre 0 si 10) si calculeaza procentul de note din fiecare valoare posibila ( se afiseaza 10 procente a caror suma este 100). P2.3 Program care citeste n numere reale X si m+1 numere intregi A si afiseaza numarul de valori X situat in fiecare din cele m intervale delimitate de valorile din A. Se verifica daca valorile A sunt introduse in ordine crescatoare si in caz contrar programul se opreste. P2.4 Program care citeste doi vectori neordonati de numere distincte si verifica daca ei contin aceleasi numere, indiferent de ordine (fara ordonarea lor). Se poate folosi programul scris si pentru vectori cu elemente repetate diferit in cei doi vectori ? (Ex: {2,1,2,3}, {3,2,1,3}) P2.5 Program pentru interclasarea a doi vectori ordonati intr-un singur vector ordonat, care se va afisa. Exemplu de date : a={2,4,6,7}, b={1,3,9,11}; Rezultat: 1,2,3,4,6,7,9,11 P2.6 Program pentru citirea unui vector de intregi si extragerea elementelor distincte intr-un al doilea vector, care se va afisa. P2.7 Program pentru ordonarea unui vector de numere intregi prin metoda bulelor: se compara elemente vecine din vector (a[i] si a[i+1] ) si, daca este necesar, se schimba intre ele pentru ca a[i] <= a[i+1]. In general sunt necesare mai multe treceri prin vector pentru ordonarea sa. Variante: (a) Numarul de treceri este egal cu dimensiune vector minus 1. (b) Se fac atatea treceri cate sunt necesare pentru ordonarea vectorului (se memoreaza daca au fost necesare schimbari de elemente in vector si se opreste repetarea cand nu a mai fost necesara nici o schimbare). (c) O trecere prin vector se face de la prima la ultima pereche (d) O trecere prin vector se face de la ultima pereche catre prima pereche P2.8 Program de sortare prin selectie: se compara fiecare element cu toate elementele urmatoare si se fac schimbarile necesare. Se repeta acest proces pentru un numar de elemente care scade progresiv. In aceasta varianta se aduce minimul in prima pozitie din (sub)vector si se mareste indicele primului element la trecerea urmatoare. P2.9 Program de sortare prin selectie: se compara fiecare element (pornind cu ultimul) cu toate elementele precedente si se fac schimbarile necesare. Se repeta acest proces pentru un numar de elemente care scade progresiv. In aceasta varianta se aduce maximul in ultima pozitie din (sub)vector si

se scade indicele ultimului element la trecerea urmatoare. P2.10 Program de sortare prin numarare : se compara fiecare element cu toate celelalte din vector si se creeaza un vector auxiliar care contine in pozitia k numarul elemente din vectorul a mai mici decat a[k]. P2.11 Program pentru calculul valorii unui polinom cu coeficienti dati, prin mai multe metode cu urmatoarea numerotare a coeficientilor: P(x) = c[0]*x^n + c[1]*x^(n-1) + ... + c[n-1]*x + c[n] Datele initiale : x, n, c[0],..c[n] (a) Ca suma de termeni calculati separat (cu functia "pow") (b) Ca suma de termeni calculati unul din altul (fara ridicare la putere) (c) Printr-o relatie de recurenta de forma P(x,k)=P(x,k-1)*x + c[k] si P(x,0)=c[0]. P2.12 Program care calculeaza valoarea polinomului de interpolare Newton cu coeficienti dati, ptr o valoare data xx : P(xx) = c[0] + c[1]*(xx-x[1]) + c[2]*(xx-x[1])*(xx-x[2]) + ... + c[n]*(xx-x[1])*(xx-x[2])* ... *(xx-x[n]) Date: n, xx, Vectorul c, Vectorul x, Obs. Produsele din fiecare termen se pot calcula unele din altele. P2.13 Program pentru calculul normei pe linii a unei matrice de numere reale. Norma este valoarea maxima dintre sumele valorilor absolute ale elementelor din fiecare linie. P2.14 Program pentru determinarea valorii minime dintre toate valorile maxime pe liniile unei matrice de numere reale (punct in "sa"). P2.15 Program pentru afisarea celei mai lungi secvente ordonate de elemente consecutive dintr-un vector dat. Exemplu de date: 5 3 6 2 4 6 8 4 1 Rezultat: 2 4 6 8 Sa se verifice programul si pentru un vector ordonat descrescator.

P2.16 Un graf (orientat sau neorientat) este reprezentat printr-o matrice de adiacente "a", in care a[i][j]=1 daca exista muchie (arc) de la nodul "i" la nodul "j" si a[i][j]=0 daca nu exista arcul (i,j). Program pentru citirea numarului de varfuri dintr-un graf neorientat si listei de muchii si afisarea varfului cu numar maxim de vecini (de arce incidente). P2.17 Un graf orientat poate fi reprezentat prin doi vectori de noduri " v" si "w", in care v[k]=i si w[k]=j daca exista muchie (arc) de la nodul "i" la nodul "j". Program pentru citirea numarului de noduri din graf si listei de arce si afisarea succesorilor si predecesorilor fiecarui nod. Exemplu de date : 1 3 / 1 4 / 2 4 / 3 2 / 4 3 / 4 1 / Liste de succesori: 1: 3,4 / 2: 4 / 3: 2 / 4: 3,1 Liste de predecesori: 1: 4 / 2: 3 / 3: 1,4 / 4: 1,2 P2.18 Program care citeste mai multe relatii de echivalenta intre perechi de numere intregi si afiseaza clasele de echivalenta ce se pot forma cu toate numerele citite. Exemplu de date: 3 6 / 5 7 / 2 5 / 1 3 / 1 6 / 4 8 Clasele de echivalenta sunt: {1,3,6}, {2,5,7}, {4,8} Se va folosi o matrice patratica cu atatea linii si coloane cate numere sunt in total. O linie corespunde unei clase de echivalente. Exemplu: 1 2 3 4 5 6 7 8 Clasa 1 1 0 1 0 0 1 0 0 Clasa 2 0 1 0 0 1 0 1 0

Clasa 3

P2.19 Program care citeste mai multe relatii de echivalenta intre perechi de numere intregi si afiseaza clasele de echivalenta ce se pot forma cu toate numerele citite. Exemplu de date: 3 6 / 5 7 / 2 5 / 1 3 / 1 6 / 4 8 Clasele de echivalenta sunt: {1,3,6}, {2,5,7}, {4,8} Se vor folosi doi vectori: un vector cu elementele clasificate si un vector cu numarul clasei de care apartine un element. Exemplu: Elem. 1 2 3 4 5 6 7 8 Clasa 1 2 1 3 2 1 2 3 Obs. Clasele de echivalenta corespund unor grafuri neorientate conexe.

SOLUTII LA PROBLEME PROPUSE

3. DEFINIREA SI UTILIZAREA DE FUNCTII EXEMPLE DE PROGRAME E3.1a Functie fara argumente si fara rezultat asociat numelui sau. // Stergere ecran in mod text, #include <stdio.h> // definire functie void clear() { int i; for (i=0;i<24;i++) putchar('\n'); } // utilizare functie void main () { clear(); printf ("text in prima linie } prin defilare

// ptr un ecran de 25 de linii // sau printf ("\n");

// sterge ecran de jos \n");

Observatii: - Functia "clrscr()" nu este standard in limbajul C, dupa cum nici fisierul antet CONIO.H nu este standard (dar ele exista in Borland-C). - Dupa stergere ecran cu "clrscr" cursorul este in prima linie de sus si ecranul trece in mod pagina (implicit este in modul defilare). E3.1b Aceeasi functie de la 3.1a, dar plasata dupa programul principal #include <stdio.h> void clear(); // declarare functie (prototip) // utilizare functie void main () { clear(); printf ("text in linia de jos\n"); } // definire functie (cu declaratie ca in C++) void clear() { for (int i=0;i<24;i++) // ptr un ecran de 25 de linii putchar('\n'); // sau printf ("\n"); }

E3.2 Functie de tip "void" cu un argument #include <stdio.h> // Desenarea unei bare orizontale compuse din void bar (int n) { int i; for (i=0;i<n;i++) putchar('#'); putchar('\n'); } // Desenare histograma pe baza unui vector de void main () { int a[24]={5,10,15,10,5},n=5,k; clear(); for (k=0;k<n;k++) bar (a[k]); ngime a[k] } n caractere

intregi // sterge ecran // desenare bara k de lu

E3.3 Functie de tip "void" cu doua argumente de tipuri diferite // Desenarea unei bare orizontale din n caractere ch void bar1 (int n, char ch) { int i; for (i=0;i<n;i++) putchar(ch); putchar('\n'); } E3.4 Functie de tip "void" cu argument de tip vector // Desenare histograma pe baza unui vector de intregi void hist (int a[], int n) { int i; for (i=0;i<n;i++) bar(a[i]); } E3.5 Functie cu rezultat si argument de tip vector // Determinare valoare minima dintr-un vector dat float minim (float x[], int n) { float xmin=x[0]; for (i=1;i<n;i++) if ( xmin > x[i]) xmin=x[i]; return xmin; } // utilizare functie void main () { float t[]={3,7,1,2,8,4}, tmin; printf ("%f \n", minim(t,6)); } E3.6 Functie care verifica satisfacerea unei conditii // Verifica daca un caracter dat este un spatiu alb int isspace (char ch) { return (ch==' ' ch=='\n' ch='\t'); // blanc,new line, tab }

Obs. - In C exista functii standard pentru verificarea tipului unui caracter dat (isspace, isalpha,isdigit,...), declarate in CTYPE.H. E3.7 Functie care verifica respectarea unei conditii de catre toate elementele unui vector dat. // Verifica daca un vector este ordonat crescator sau nu int sorted (int a[], int n) { int i; for (i=0;i<n-1;i++) if (a[i] > a[i+1]) return 0; // vector neordonat return 1; // vector ordonat } E3.8 Functie cu doua rezultate (cu argumente de tip pointer) // Determinare minim si maxim dintr-un vector void minmax ( float x[],int n,float* pmin, float* pmax) { float xmin,xmax; int i; xmin=xmax=x[0]; for (i=1;i<n;i++) { if (xmin > x[i]) xmin=x[i]; if (xmax=x[i]) xmax=x[i]); } *pmin=xmin; *pmax=xmax; } // utilizare functie void main () { float a[]={3,7,1,2,8,4}; float a1,a2; minmax (a,6,&a1,&a2); printf("%f %f \n",a1,a2); } Obs.: Este preferabila scrierea a doua functii separate care transmit prin numele functiei valoarea minima sau maxima. E3.9 Functie cu argument vector apelata pentru o linie dintr-o matrice // Determinare valoare minima dintr-o matrice float minim (float x[],int n); // prototip functie void main () { float a[30][30],am[30],min; int i,nl,nc; //nl=nr.linii, nc=nr.coloane ... // citire date min = minim (a[0],nc); for (i=0;i<n;i++) am[i]=minim(a[i],nc); // minim din fiecare linie min= minim(am,nl); // cel mai mic minim din linii ... } E3.10 Functie cu argument matrice (cu numar impus de coloane) // Generare matrice unitate

void matrunit (float u[][30], int n) { int i,j; for (i=0;i<n;i++) { for (j=0;j<n;j++) u[i][j]=0; u[i,i]=1; } } // afisare matrice patratica (cu 30 de coloane declarate) void scrmatr (float a[][30], int n) { int i,j; for (i=0;i<n;i++) { for (j=0;j<n;j++) printf ("%4.0f",a[i][j]); printf("\n"); } } // utilizare void main () { float x[30][30]; int n; for (n=2;n<=10;n++) { matrunit(x,n); scrmatr(x,n); getchar(); } }

// asteapta tasta "Enter"

E3.11 Functie recursiva pentru ridicarea unui numar la o putere intreaga pe baza relatiei de recurenta x^k = x * x^(k-1) si cu x^0=1 double power (double x, int n) { if (n==0) return 1. ; return x * power(x,n-1); } E3.12 Functie recursiva pentru ridicarea unui numar la o putere intreaga cu numar redus de inmultiri, pe baza relatiei de recurenta x^k = x^(k/2) * x^(k/2) daca k este par si x^k= x * x^(k-1) daca k impar double power (double x, int n) { double y; if (n==0) return 1; if ( n %2 ==0) { y=power(x,n/2); return ( y*y); } else return (x * power (x,n-1)); } PROBLEME PROPUSE P3.1 Functie pentru determinarea numarului de cifre al unui numar dat (de

orice tip intreg). Program pentru citirea unui intreg n si afisarea a n numere aleatoare intre 0 si n, cu determinare numar de coloane in functie de valorile afisate. ( nr de coloane = 80/(nr.cifre+2) ) Se va utiliza functia "random" declarata in <math.h> P3.2 Functie care verifica daca un numar dat este prim sau nu. Program pentru afisarea descompunerilor numerelor pare mai mici ca un intreg dat in sume de doua numere prime (Ipoteza lui Goldbach = orice numar par se poate scrie ca suma a doua numere prime). P3.3 Functie care primeste doi intregi a intregi k si c astfel ca a = c * b^k ( b k este ordinul de multiplicitate, c este repetate a lui a prin b). Program pentru factori primi (cu puterile lor) folosind 360 = 2^3 * 3^2 * 5^1 si b si determina alti doi este un divizor posibil al lui a, numarul ramas dupa k impartiri descompunerea unui numar dat in functia. Exemplu:

P3.4 Functie care determina pozitia valorii maxime intr-un vector. Program pentru ordonarea unui vector de numere prin determinarea repetata a valorii maxime dintr-un vector si schimbarea cu ultimul element din vector. P3.5 Functie care determina semnul unui numar intreg ("sign") si are rezultat 0 (valoare zero), -1 (numar negativ) sau +1 (numar pozitiv). Functie care determina numarul cadranului in care se afla un punct de coordonate intregi date x,y; rezultatul este 0 daca punctul se afla pe una din axe sau la intersectia axelor. Indicatie: Se face o selectie ("switch") dupa valoarea 3*sign(x)+sign(y). Program de verificare. P3.6 Functie pentru cautare binara intr-un vector ordonat in doua moduri: iterativ si recursiv. Cautarea binara se face prin compararea valorii cautate cu valoarea din mijlocul vectorului cercetat si alegerea primei sau ultimei jumatati din vector pentru pasul urmator, in functie de rezultatul comparatiei. Procesul de injumatatire a vectorului se opreste fie la gasirea valorii cautate, fie la reducerea dimensiunii pana la 1. Functia primeste ca argumente valoarea cautata, adresa vectorului si indicii (pozitiile) din vector intre care se cauta. P3.7 Functii pentru operatii cu multimi de 256 intregi realizate printr-un sir de 256 de biti (16 intregi fara semn sau 32 de octeti). Bitul k din sir este 1 daca multimea contine elementul cu valoarea k si este zero daca multimea nu contine valoarea k. Bitul k din sir se afla in bitul cu numarul k%16 din intregul k/16 din vectorul de 16 intregi. Operatii (functii): initializare multime vida, adaugare intreg la multime, verifica apartenenta unui numar la o multime, afisare multime (intre acolade), reuniune, intersectie si diferenta de multimi. Program pentru verificarea acestor functii P3.8 Functii pentru operatii cu multimi de numere intregi reprezentate prin vectori neordonati de lungime fixa, in care elementele multimii sunt grupate la inceputul vectorului, dupa care urmeaza zerouri. Operatii: initializare multime vida, verificare apartenenta la o multime, adaugare element la o multime (daca nu exista deja), afisare multime (intre acolade), reuniune, intersectie si diferenta de multimi. Program pentru verificarea acestor functii. P3.9 Functie pentru determinarea divizorilor unui numar intreg dat. Functie pentru calculul valorii unui polinom cu coeficienti intregi. P(x)= a[0]*x^n+a[1]*x^(n-1)+ ... +a[n-1]*x + a[n] Functie pentru determinarea coeficientilor polinomului cat ("b") al

impartirii unui polinom (dat prin coeficientii "a") prin (x-r). Se vor folosi relatiile de recurenta urmatoare: b[0]=a[0]; b[k]=a[k]+b[k-1]*r k=1,n-1 Program care determina si afiseaza radacinile unei ecuatii polinomiale cu coeficienti intregi, aflate printre divizorii termenului liber; se vor afisa divizorii (cu valori pozitive sau negative) care anuleaza valoarea polinomului dat. exemplu: x^3+3x^2+2x+6 are ca radacina x=-3 (dar nu are radacinile 2,-2,3). Coeficientul puterii maxime a lui x va fi 1. P3.10 Functie pentru calculul valorii polinomului de interpolare Lagrange pentru o valoare data xx folosind relatia : yy = Suma (y[k]*Prod((xx-x[i])/(x[k]-x[i]) ) Suma pentru k=1,n. Produs pentru i=1,n si i!=k Program pentru citirea a 2 vectori x si y ce definesc o functie prin n puncte si calculeaza valorile functiei la mijlocul intervalelor de pe axa X prin interpolare Lagrange. Se vor afisa coordonatele celor n-1 puncte astfel determinate. P3.11 Functie pentru inmultirea unui polinom cu coeficienti dati cu un binom de forma (x+c). Program pentru calculul coeficientilor polinomului care are ca radacini numerele intregi c[1],c[2],...c[n] (citite ca date initiale). (Termenul liber trebuie sa fie egal cu produsul r[1]*r[2]*..., iar coeficientul lui x^(n-1) sa fie egal cu suma r[1]+r[2]+...r[n]) Pentru c[1]=c[2]=..=c[n]=1 coeficientii afisati sunt coeficientii puterii n a binomului (x+1) P3.12 Functie recursiva pentru determinarea celui mai mare divizor comun a 2 intregi, pe baza relatiei cmmdc(a,b) = cmmdc (b,a%b) daca a%b != 0 si cmmdc(a,b) =b daca a%b==0. P3.13 Functie recursiva pentru afisare in binar a unui intreg primit ca argument. Algoritm: echivalentul binar al lui m se obtine din echivalentul binar al lui m/2 urmat de cifra binara m%2. Scrieti si o forma iterativa pentru acest algoritm de impartiri succesive la 2 si afisare de resturi in ordinea inversa obtinerii lor. P3.14 Functie recursiva pentru cautarea secventiala intr-un vector a unei valori date, cu rezultat pozitia in vector a numarului cautat sau -1 daca negasit. Rezultatul cautarii intr-un vector a cu n elemente este fie a[n-1] fie egal cu rezultatul cautarii in primele n-1 elemente (daca n>0). P3.15 Functie pentru inmultirea a doua matrice patratice cu acelasi numar de linii si coloane. Functie pentru ridicarea unei matrice patratice la o putere intreaga, prin inmultiri repetate (folosind prima functie). Program pentru verificare pe o matrice unitate. P3.16 Functie care schimba intre ele doua linii i si j dintr-o matrice patratica. Program care foloseste functia pentru a aduce pe diagonala principala numai elemente nenule (daca este posibil). Se va afisa matricea obtinuta prin schimbari de linii.

SOLUTII LA PROBLEME PROPUSE 4. PROGRAME SI FUNCTII CU SIRURI DE CARACTERE EXEMPLE DE FUNCTII SI PROGRAME

E4.1 Program pentru citirea si afisarea unor linii la consola #include <stdio.h> void main () { char linie[80]; // aici se citeste o linie while ( gets (linie) != NULL) puts(linie); // scrie linia citita } E4.2 Program pentru citirea unui text in memorie, cu pastrarea caracterelor terminator de linie. #include <stdio.h> #include <string.h> void main () { char linie[80]; // aici char text[30000]={0}; while ( gets (linie) != strcat (linie,"\n"); strcat(text,linie); } puts(text); }

se citeste o linie // aici se memoreaza toate liniile NULL) { // "gets" elimina car. '\n' // adauga la text linia citita // afisare text citit, pe linii

Obs: O forma mai compacta pentru ciclul de citire, adaugare la text: while ( gets (linie) != NULL) strcat (text, strcat(linie,"\n")); E4.3 Program pentru citirea de siruri separate prin spatii albe intre ele (se pot introduce mai multe siruri intr-o linie): #include <stdio.h> #include <string.h> void main () { char word[30]; // lungime maxima cuvant=30 while (scanf("%s",word) !=EOF) printf("%s(%d)\n",word,strlen(word)); // un cuvant si lungimea sa } Obs.: Toate programele de mai sus pot fi folosite cu fisiere text de intrare si de iesire prin redirectarea fisierelor standard stdin si stdout. E4.4 Functie pentru insertia unui caracter la o adresa dintr-un sir. Functie pentru insertia unui sir s la o adresa data din alt sir d. // insertie caracter intr-un sir void chins (char *d, char ch) { char *p; for (p=d+strlen(d); p>=d;p--) * (p+1) = *p; *d = ch; } // insertie sir s la adresa d void strins (char *d, char *s) { char *p; int ls=strlen(s); for (p=s+ls-1; p >=s;p--) chins(d,*p); }

E4.5 Functie echivalenta ca efect cu functia "strstr" #include <stdio.h> #include <string.h> // cauta un sir in alt sir char * strstr ( char * s1, char* s2) { while ( strlen (s1) >= strlen(s2) ) if ( strncmp(s1,s2,strlen(s2)) ==0 ) return s1; else ++ s1; return NULL; } // verificare functie void main () { char s1[30], s2[30]; while ( scanf ("%s %s", s1,s2) != EOF) printf ("%s\n",strstr(s1,s2)); } E4.6 Functie echivalenta ca efect cu functia "strtok" : //extrage din sir atomi separati prin caractere specificate char *strtok (char * sir,char *separ) { static char *p; char * r; if (sir) p=sir; /* ignora separatori intre atomi */ while (strchr(separ,*p) && *p ) p++; if (*p=='\0') return NULL; r=p; while (strchr(separ,*p)==NULL && *p) p++; if (p==r) return NULL; else { *p++='\0'; return r; } } E4.7 Program pentru numararea liniilor si cuvintelor dintr-un fisier text, al carui nume se da in linia de comanda. Cuvintele sunt siruri de orice caractere separate intre ele prin (oricate) spatii albe. Se va folosi functia de biblioteca "strtok". #include <stdio.h> #include <string.h> // numarare linii si cuvinte dintr-un fisier text void main ( int argc, char *argv[] ) { char linie [200], *p, *sep="\t \r\n" ; FILE * f; int nl=0, nc=0; // nr linii, nr cuvinte if (argc < 2) { printf("Lipseste numele fisierului din comanda \n"); return; } if( (f = fopen (argv[1],"r")) == NULL) { printf(" fisier negasit \n"); return ; }

while ( fgets (linie,200,f) != NULL) { nl++; p=linie; while ( (p= strtok (p,sep)) != NULL) { ++nc; p=p+strlen(p)+1; } } printf ("\n %d linii %d cuvinte",nl,nc); // si alte operatii cu linia citi ta fclose(f); } E4.8 Program pentru numararea liniilor si cuvintelor dintr-un fisier text, al carui nume se da in linia de comanda. Cuvintele sunt siruri de orice caractere separate intre ele prin (oricate) spatii albe. Nu se vor folosi functii pe siruri de caractere din <string.h>. #include <stdio.h> #include <ctype.h> // numarare linii si cuvinte dintr-un fisier text void main ( int argc, char *argv[] ) { char linie [200], *p ; FILE * f; int nl=0, nc=0; // nr linii, nr cuvinte // aici se pot face verificari asupra datelor primite f=fopen(argv[1],"r"); while ( fgets (linie,200,f) != NULL) { nl++; p=linie; while (*p) { while ( *p && isspace(*p) ) // ignora spatii dintre cuvinte p++; if (*p =='\0') // daca s-a term inat linia curenta break; // cites te alta linie nc ++; while (*p && ! isspace(*p) ) // cauta sfarsit de cuvant p++; } } printf ("%d linii %d cuvinte",nl,nc); // si alte operatii cu linia citita fclose(f); } E4.9 Program pentru citirea unui fisier de numere (reprezentate prin siruri de caractere separate prin spatii albe) si crearea unui alt fisier cu aceleasi numere ordonate crescator. Numele celor doua fisiere se dau in linia de comanda. // ordonare fisier de numere #include <stdio.h> #include <stdlib.h> // compara doi intregi (ptr qsort)] int intcmp (const void* a , const void * b) { return *(int*)a - *(int*)b; }

// program de ordonare fisier de numere int main (int na, char ** arg) { int num[1000]; // vector pentru numere citite din fisier int n,i,j; FILE * f1, * f2; if (na < 3) { printf ("Eroare! Utilizare corecta: nume infile outfile \n"); return -1; } // citire fisier de date if ( (f1=fopen (arg[1],"rt"))==0) { printf ("Eroare: Fisier de date negasit! \n"); return -2; } i=0; while ( fscanf(f1,"%d",&num[i]) != EOF) i++; n=i; // lungime vector // ordonare vector cu functia "qsort" qsort (num,n,sizeof(int), intcmp); // scrie vector ordonat in fisier f2=fopen(arg[2],"wt"); for (i=0;i<n;i++) fprintf(f2,"%d ",num[i]); fclose(f2); } Obs: Nu era posibila ordonarea numerelor ca siruri de caractere (fara conversie in binar), deoarece sirul "7" este superior sirului "123", dar numarul 7 este inferior numarului 123. E4.10 Program pentru citirea unui fisier text creat in Unix (in care fiecare linie se termina cu un singur caracter '\n' ) si crearea unui alt fisier cu acelasi continut, dar in care liniile se termina cu doua caractere: "\r\n". In final se sterge fisierul initial si se schimba numele noului fisier in numele fisierului initial. Functia "fputs" adauga caracterul '\r' inaintea caracterului '\n'. #include <stdio.h> #include <string.h> void main () { char nume1[80], nume2[80]; // nume fisiere char line[200]; // aici se citeste o linie char *point ; FILE * f1, * f2; puts("Nume fisier text:"); gets(nume1); if( (f1 = fopen (nume1,"r")) == NULL) { printf(" fisier negasit \n"); return ; } strcpy(nume2,nume1); point = strchr (nume2,'.'); if (point==0) point=nume2+strlen(nume2); strcpy(point+1,"$$$"); f2 =fopen (nume2,"w"); while ( fgets (line,200,f1) != 0) fputs (line,f2); if (fclose(f1)<0 fclose(f2)<0) { puts("Erori la fisiere \n"); return; }

remove(nume1); rename(nume2,nume1); } PROBLEME PROPUSE

// schimba nume1.$$$ in nume1.*

P4.1 Functii echivalente ca efect cu functiile de biblioteca strlen, strcpy, strcat, strcmp, strchr, strrchr P4.2 Functii echivalente ca efect cu functiile de biblioteca strncpy, strncat, strncmp. P4.3 Functie pentru eliminarea unui subsir de lungime data dintr-un sir dat prin adresa sa (si terminat cu zero). Functie pentru inserarea unui sir dat la o adresa dintr-un sir terminat cu zero. P4.4 Program care inlocuieste toate aparitiile unui sir dat printr-un alt sir (de lungime diferita), intr-un text aflat in memorie. Se pot folosi functiile din programul anterior. P4.5 Functie care primeste o data calendaristica ca un sir de forma "DD-MM-YY" si produce un vector cu 3 intregi ce corespund numarului zilei (DD), lunii(MM) si anului(YY). Se pot folosi functii de biblioteca (sscanf, atoi, strtok, strchr etc.). Program ptr verificare functie. P4.6 Program pentru numararea si afisarea cuvintelor separate prin spatii albe (dintr-un text) in doua variante : (a) folosind functia de biblioteca "strtok". (b) folosind functia de biblioteca "sscanf" P4.7 Sa se rescrie functia "strtok" astfel ca primul argument sa reprezinte adresa din sir de unde incepe cautarea, la fiecare apel (fara variabila statica). Se adauga un al treilea argument unde functia depune atomul extras din text, iar rezultatul functiei este adresa urmatoare atomului gasit. Sa se modifice si programul care foloseste functia modificata. P4.8 Functie care extrage urmatorul sir de litere de la o adresa data (se ignora caracterele dinainte care nu sunt litere). Rezultatul este adresa imediat urmatoare sirului gasit sau NULL daca nu s-a gasit nici un sir de litere. P4.9 Program pentru citirea unui text sursa C in memorie si afisarea frecventei de aparitie a urmatoarelor cuvinte cheie in text: if, for, do, while, switch, break. P4.10 Program pentru ordonarea unui fisier text dupa cuvantul numarul k din fiecare linie (k=0,1,..n-1). Fiecare linie contine n cuvinte separate prin spatii albe. Numele fisierului si intregul k se transmit prin linia de comanda ( exemplu: sort linii 1). P4.11 Program pentru afisarea frecventei de aparitie a cuvintelor folosite de mai multe ori intr-un fisier text. Nu se vor afisa cuvintele folosite o singura data. P4.12 Program pentru citirea unui fisier text si crearea unui alt fisier text cu linii de o lungime maxima impusa, fara a desparti cuvintele la trecerea de pe o linie pe alta. Cuvintele sunt siruri separate prin unul sau mai multe spatii albe.

P4.13 Program pentru citirea unui fisier text si scrierea unui alt fisier (cu acelasi numar de linii) in care fiecare linie se termina cu un caracter diferit de spatiu alb, prin inserarea de blancuri intre cuvinte cat mai uniform posibil. In fisierul de iesire toate liniile au aceeasi lungime, specificata in linia de comanda, dupa numele fisierului de intrare. P4.14 Program pentru citirea unui fisier sursa C si afisarea textului dupa eliminarea comentariilor din text. Se vor elimina ambele tipuri de comentarii: cele care incep prin "//" si cele delimitate de "/*" si "*/". Un comentariu nu poate contine nici un alt comentariu. Perechile de caractere //,/* si */ intr-o constanta sir nu semnifica comentarii. P4.15 Program care inlocuieste toate aparitiile unui sir dat printr-un alt sir (de lungime diferita), intr-un fisier text. Se va crea un alt fisier text (cu acelasi nume dar cu extensia "$$$"). In final se schimba extensia fisierului initial in "BAK" si fisierul creat primeste extensia fisierului initial. P4.16 Program care citeste un fisier HTML si creeaza un fisier text (ASCII) dupa eliminarea tuturor marcajelor din text. Un marcaj ("tag") incepe prin caracterul '<' si se termina cu caracterul '>', poate contine oricite caractere si se poate extinde pe mai multe linii. Programul va verifica daca primele caractere diferite de blanc din fisierul de intrare sunt <HTML ...> sau <!DOCTYPE HTML ...>. SOLUTII LA PROBLEME PROPUSE 5. PROGRAME SI FUNCTII CU STRUCTURI EXEMPLE DE PROGRAME SI FUNCTII E5.1 Functii pentru operatii cu structuri (fara pointeri, cu rezultat structura). typedef struct { float re, im; } Complex; // citire numar complex Complex cit_cx () { Complex c; scanf ("%f %f", &c.re, &c.im); return c; } // scriere numar complex void scr_cx (Complex c) { printf ("(%f,%f) ",c.re,c.im); } // adunare numere complexe (cu 2 argumente) Complex plus_cx (Complex c1, Complex c2) { Complex c3; c3.re=c1.re+c2.re; c3.im=c1.im+c2.im; return c3; } // verificare functii main () { Complex c1={3,4},c2, c3; c2=cit_cx (); scr_cx(c2); c3=ad_cx(c1,c2); scr_cx(c3); }

E5.2 Operatii cu structuri realizate prin functii "void" (cu pointeri) typedef struct { float re, im; } Complex; // citire numar complex void cit_cx (Complex * px) { Complex c; scanf ("%f %f", &c.re, &c.im); *px=c; } // adunare numere complexe void ad_cx (Complex c1, Complex c2, Complex * pc3) { Complex c3; c3.re=c1.re+c2.re; c3.im=c1.im+c2.im; *pc3=c3; } main () { Complex c1={3,4},c2, c3; cit_cx (&c2); scr_cx(c2); ad_cx(c1,c2,&c3); scr_cx(c3); } E5.3 Ordonare vector de structuri cu functie de comparare structuri #include <stdio.h> typedef struct { // o data calendaristica int zi,luna,an; } Date; // comparare de date int cmpdat ( Date d1, Date d2) { int da,dl; if ( da= (d1.an - d2.an)) return da; // < 0 sau > 0 if ( dl= (d1.luna - d2.luna)) return dl; return d1.zi-d2.zi; // < 0, ==0, > 0 } // ordonare vector de date void sort (Date a[], int n) { int i,j,gata; Date aux; do { gata=1; for (i=0;i<n-1;i++) if (cmpdat(a[i],a[i+1]) > 0 ) { aux=a[i]; a[i]=a[i+1]; a[i+1]=aux; gata=0; } } while ( ! gata); } // verificare void main () { Date d[30], dd; int n,i; i=0; while (scanf ("%d%d%d",&dd.zi,&dd.luna,&dd.an)!=EOF) d[i++]=dd;

n=i; sort(d,n); for (i=0;i<n;i++) printf("%d-%d-%d\n",d[i].zi,d[i].luna,d[i].an); } E5.4 Utilizare structuri pentru reducere numar de argumente la functii // vectori reprezentati prin structuri #include <stdio.h> #define M 100 typedef struct sv { int vec[M]; int dim; } Vector; // citire vector Vector citvec ( ) { int i,n; Vector v; printf ("\n dimensiune vector: "); scanf ("%d",&n); v.dim=n; printf ("\n componente vector: \n"); for (i=0;i<n;i++) scanf ("%d", &v.vec[i]); return v; } // afisare vector void scrvec (Vector v) { int i; for (i=0;i<v.dim;i++) printf ("%d ",v.vec[i]); printf ("\n"); } // extrage elemente comune din doi vectori Vector comun(Vector a, Vector b) { Vector c; int i,j,k=0; for (i=0;i<a.dim;i++) for (j=0;j<b.dim;j++) if (a.vec[i]==b.vec[j]) c.vec[k++]=a.vec[i]; c.dim=k; return c; } // verificare functii void main () { Vector x,y,z ; x=citvec (); y=citvec (); z=comun(x,y); scrvec (z); } E5.5 Structuri cu continut variabil in timp (uniuni) #include <stdio.h> // numar de orice tip struct number { char tipn; union { int ival; long lval;

float fval; double dval; } v; }; typedef struct number Num; // afisare numar void write (Num n) { switch (n.tipn) { case 'I': printf ("%d ",n.v.ival);break; case 'L': printf ("%ld ",n.v.lval);break; case 'F': printf ("%f ",n.v.fval);break; case 'D': printf ("%.15lf ",n.v.dval);break; } } // citire numar Num read (char tip) { Num n; n.tipn=tip; switch (tip) { case 'I': scanf ("%d", &n.v.ival);break; case 'L': scanf ("%ld",&n.v.lval);break; case 'F': scanf ("%f",&n.v.fval); break; case 'D': scanf ("%lf",&n.v.dval); break; } return n; } // verificare functii void main () { Num a,b,c,d; a = read('I'); b=read('L'); c = read('F'); d=read('D'); write(a); write(b); write(c); write(d); } Obs. Memorarea unor date de tipuri diferite la o aceeasi adresa se poate realiza si fara tipul "union", folosind pointeri de tip "void *". E5.6 Crearea si afisarea unui fisier de articole ce corespund unor structuri din memorie (cu numele si mediile unor elevi). // structura articole din fisier typedef struct { char nume[25]; float medie; } Elev; // creare - afisare fisier de articole void main () { FILE * f; Elev e; char numef[80]; // aici se pune nume fisier puts("Nume fisier:"); gets (numef); // creare fisier f=fopen(numef,"wb"); // creare de fisier binar assert (f != NULL); printf (" nume si medie ptr. fiecare student : \n\n"); while (scanf ("%s %f ",e.nume, &e.medie) != EOF) fwrite(&e,sizeof(e),1,f); fclose (f); // listare fisier f=fopen(numef,"rb"); // citire fisier binar

assert (f != NULL); while (fread (&e,sizeof(e),1,f)==1) printf ("%-25s %6.2f \n",e.nume, e.medie); fclose (f); } E5.7 Cautarea si modificarea unor articole dintr-un fisier de articole. // structura articole din fisier typedef struct { char nume[25]; float medie; } Elev; // adaugare articole la sfarsit de fisier void adaugare (char * numef) { FILE * f; Elev e; f=fopen(numef,"ab"); assert (f != NULL); printf (" nume si medie ptr. fiecare student : \n\n"); while (scanf ("%s %f ",e.nume, &e.medie) != EOF) fwrite(&e,sizeof(e),1,f); fclose (f); } // cautare si modificare articole void modificare (char * numef) { FILE * f; Elev e; char nume[25]; long pos; int eof; f=fopen(numef,"rb+"); assert (f != NULL); do { printf ("Nume cautat: "); eof=scanf ("%s",nume); if (eof==EOF) break; // cauta "nume" in fisier fseek(f,0,0); // repozitionare pe inceput de fisier pos=-1L; // pozitia unde va fi sau nu gasit numele cautat while (fread (&e,sizeof(e),1,f)==1) if (strcmp (e.nume, nume)==0) { pos= ftell(f)-sizeof(e); break; } if ( pos < 0) break; printf ("noua medie: "); scanf ("%f", &e.medie); fseek (f,pos,0); // pozitionare pe inceput de articol gas it fwrite(&e,sizeof(e),1,f); // rescrie articol modificat } while (eof!=EOF); fclose (f); } // actualizare fisier existent void main () { FILE * f; Elev e; char c, numef[80]; // aici se pune nume fisier puts("Nume fisier:"); gets (numef); puts("Operatie (A=adaugare, M=modificare):"); c=getchar(); if (c=='a' c=='A') adaugare(numef); else if (c=='m' c=='M') modificare(numef); }

PROBLEME PROPUSE P5.1 Functii pentru inmultirea a doua numere complexe si pentru ridicarea la o putere intreaga a unui numar complex prin inmultiri repetate. Program pentru calculul valorii (complexe) a unui polinom de variabila complexa, cu coeficienti numere complexe. P5.2 Sa se defineasca o structura "Time" care grupeaza 3 intregi ce reprezinta ora, minut si secunda pentru un moment (sau un interval) de timp. Functii pentru citire, scriere si comparare de structuri "Time". Functia de comparare dupa modelul functiei "strcmp". Program pentru verificarea functiilor. P5.3 Program pentru ordonarea cronologica a unor momente de timp si afisarea listei ordonate, folosind functii din programul anterior. P5.4 Sa se defineasca o structura "Punct" pentru un punct din plan ( cu doua coordonate x,y de tip "float") si o structura "Poligon" pentru un poligon definit prin numarul de varfuri si un vector de coordonate ale varfurilor (de tip "Punct"). Functie pentru calculul distantei dintre doua puncte din plan. Functie pentru calculul perimetrului unui poligon. Program pentru calculul perimetrului unui triunghi si unui patrulater. P5.5 Sa se defineasca o structura "Vector" pentru un vector alocat dinamic si extensibil, care contine dimensiunea maxima si dimensiunea efectiva a vectorului. Functii pentru initializarea unui vector, pentru adaugarea unui element (cu extindere daca este necesara) si pentru afisarea unui vector de tip "Vector". Tipul elementelor T este neprecizat si poate fi orice tip predefinit sau definit de utilizator. Program care foloseste functiile. P5.6 Sa se defineasca o structura "Per" pentru o pereche cuvant- numar si o structura "Dic" pentru un dictionar ca vector de perechi "Per". Program pentru afisarea frecventei de aparitie a unor cuvinte (citite de la consola) si care foloseste un dictionar de cuvinte si numar de aparitii. Se va defini si folosi o functie pentru cautarea unui cuvant in dictionar si adaugarea unei perechi cuvant-numar la dictionar (daca cuvant negasit) sau modificarea numarului de aparitii (daca cuvant gasit). P5.7 Sa se defineasca o structura "Dic" pentru un dictionar compus din doi vectori: un vector de cuvinte (siruri) si un vector de intregi, plus dimensiunea lor comuna (vectori cu dimensiune fixa). Program pentru afisarea frecventei de aparitie a unor cuvinte (citite de la consola) care foloseste un dictionar de cuvinte si numar de aparitii. Se vor defini functii pentru adaugarea unei prechi cuvant-numar la dictionar si respectiv pentru cautarea unui cuvant in dictionar, cu rezultat numar de aparitii sau -1 daca negasit. P5.8 Sa se defineasca un tip "Set" ca pointer la o structura ce reuneste adresa, dimensiunea alocata si dimensiunea efectiva pentru un vector alocat si realocat dinamic prin care se reprezinta o multime de numere intregi. Multimea vida are dimensiunea zero. Functii pentru creare multime vida, adaugare numar la multime, test apartenenta la multime, afisare multime, comparatie la egalitate, reuniune, intersectie si diferenta de multimi. Functiile au argumente de tip "Set". Program pentru verificarea acestor functii. P5.9 Sa se reuneasca operatiile cu fisierul de elevi din exemplele anterioare intr-un singur program cu mai multe functii si un meniu de alegere a operatiei afisat pe ecran dupa fiecare operatie. Optiuni meniu: creare, listare, adaugare la sfarsit, modificare continut, terminare (iesire).

P5.10 Sa se defineasca o structura "Bon" pentru un bon de vanzare ce contine numele unui produs (max 30 caractere), cantitatea (un intreg) si valoarea unei vanzari (un numar neintreg). Program pentru urmatoarele operatii cu acest fisier: adaugare la sfarsit fisier (cu creare daca nu exista), afisare integrala fisier, afisare bonuri pentru un produs specificat, cu totalizare valoare bonuri pe acel produs. SOLUTII LA PROBLEME PROPUSE 6. PROGRAME CU DATE ALOCATE DINAMIC EXEMPLE DE PROGRAME E6.1 Functie echivalenta cu functia de biblioteca "strdup" #include <string.h> #include <alloc.h> // alocare memorie si copiere sir char * strdup ( char * adr) { int len=strlen(adr); char * rez = (char*) malloc(len); strcpy(rez,adr); return adr; } // utilizare "strdup" #include <stdio.h> void main () { char s[80], * d; do { if (gets(s)==0) break; d= strdup(s); puts(d); } while (1); } E6.2 Vector alocat dinamic (cu dimensiune cunoscuta la eexecutie) #include <stdio.h> #include <stdlib.h> void main () { int n,i; int * a; // adresa vector printf("n="); scanf("%d",&n); // dimensiune vector a=(int*) malloc (n*sizeof(int)); printf("componente vector: \n"); for (i=0;i<n;i++) // citire vector scanf("%d", &a[i]); for (i=0;i<n;i++) // afisare vector printf("%d ", a[i]); } E6.3 Vector realocat dinamic (cu dimensiune necunoscuta) #include <stdio.h> #include <conio.h> #include <stdlib.h> #define INCR 4

void main() { int n,i,m ; float x, * v; n=INCR; i=0; v=(float *)malloc (n*sizeof(float)); while (scanf("%f",&x) !=EOF){ if (i == n) { n= n+ INCR; v=(float *) realloc (v,n*sizeof(float)); } v[i++]=x; } m=i; for (i=0;i<m;i++) printf ("%.2f ",v[i]); } E6.4 Matrice alocata dinamic (cu dimensiuni cunoscute la executie) #include <stdio.h> #include <stdlib.h> void main () { int n,i,j; int ** mat; // adresa matrice // citire dimensiuni matrice printf("n="); scanf("%d",&n); // alocare memorie ptr matrice mat=(int **) malloc (n*sizeof (int*)); for (i=0;i<n;i++) mat[i] =(int*) calloc (n,sizeof (int)); // completare matrice for (i=0;i<n;i++) for (j=0;j<n;j++) mat[i][j]= n*i+j+1; // afisare matrice for (i=0;i<n;i++) { for (j=0;j<n;j++) printf ("%6d ",mat[i][j]); printf ("\n"); } } E6.5 Vector de pointeri la siruri alocate dinamic /* Creare/ afisare vector de pointeri la siruri */ #include <stdio.h> #include <stdlib.h> #include <string.h> // afisare siruri reunite n vector de pointeri void printstr ( char * vp[], int n) { int i; for(i=0;i<n;i++) printf ("%s\n",vp[i]); } // ordonare vector de pointeri la siruri void sort ( char * vp[],int n) { int i,j; char * tmp; for (j=1;j<n;j++)

for (i=0;i<n-1;i++) if ( strcmp (vp[i],vp[i+1])>0) { tmp=vp[i]; vp[i]=vp[i+1]; vp[i+1]=tmp; } } // citire siruri si creare vector de pointeri int readstr (char * vp[]) { int n=0; char * p, sir[80]; while ( scanf ("%s", sir) == 1) { p= (char*) malloc (strlen(sir)+1); strcpy( p,sir); vp[n]=p; ++n; } return n; } void main () { int n; char * vp[1000]; // vector de pointeri, cu dimens. fixa n=readstr(vp); // citire siruri si creare vector sort ( vp,n); // ordonare vector printstr (vp,n); // afisare siruri } E6.6 Structuri alocate dinamic si legate prin pointeri (liste inlantuite) // creare si afisare lista simplu inlantuita #include <stdio.h> #include <stdlib.h> // definire tip nod de lista typedef struct snod { int val; // valoare nod struct snod * leg; // legatura la nodul urmator } nod; void main () { nod * list, *nou, *p; // lst = adresa primului nod int x; // citire numere si creare lista list=NULL; // lista initial vida while (scanf ("%d",&x) > 0) { nou= (nod*) malloc(sizeof(nod)); // creare nod nou nou->val=x; nou->leg=list; list=nou; // adauga noul nod la inceputul listei } // afisare lista p=list; while ( p != NULL) { // cat timp mai sunt noduri in lista printf ("%d ", p->val); // afisare valoare din nodul cu adresa p p=p->leg; // avans la nodul urmator } } PROBLEME PROPUSE P6.1 Program care citeste mai multe linii de text de la tastatura si le memoreaza intr-un vector de caractere alocat si realocat dinamic (textul va fi terminat cu zero si va rezulta prin concatenare de linii).

P6.2 Program care citeste mai multe linii de text de la tastatura, aloca dinamic memorie pentru fiecare linie si pune adresa liniei intr-un vector de pointeri (vector alocat si realocat dinamic) P6.3 Program pentru crearea si afisarea unei liste inlantuite de pointeri la siruri alocate dinamic. P6.4 Sa se scrie o functie pentru alocarea unor matrice patratice cu dimensiuni date de reali (de tip "double"). Sa se scrie un program care citeste si afiseaza valori in/din matricea astfel alocata (dimensiunea se citeste in programul principal). P6.5 Functii pentru operatii cu multimi realizate ca vectori de biti alocati dinamic. Se va defini un tip "Set" ca pointer la o structura care reuneste adresa si dimensiunea vectorului multime. Functii pentru afisare multime, creare multime vida, adaugare numar la multime, copiere multime, test de apartenenta, reuniune si intersectie de multimi. Valoarea k este in multime daca este 1 bitul k%16 din intregul aflat in pozitia k/16 in vector. Dimensiunea multimii (ca numar de biti) se da la creare multime vida si nu mai poate creste prin adaugare de elemente. P6.6 Functie pentru adunarea a doua numere intregi fara semn cu maxim 254 cifre zecimale, reprezentate prin vectori de cifre zecimale (cate o cifra pe un octet), precedate de lungimea lor . Numerele pot avea lungimi diferite, iar prima cifra este cea mai putin semnificativa (cifra unitatilor). Functii pentru conversia din sir de caractere in numere reprezentate ca vectori de cifre si pentru conversia inversa. Memoria se aloca dinamic pentru fiecare sir de cifre. Program pentru verificarea functiilor prin citire, adunare si afisare suma de intregi foarte lungi. Exemplu de adunare: 567089 + 432 = 567521 P6.7 Functii pentru operatii cu liste inlantuite de numere: initializare lista vida, adaugare la sfarsit de lista, afisare lista. Program pentru creare si afisare lista folosind aceste functii. P6.8 Functii pentru operatii cu liste ce contin la inceput un nod fara date (element santinela creat la initializarea listei). Program pentru crearea si afisarea unei liste de numere. P6.9 Functie pentru adaugare la o lista ordonata de numere, cu pastrarea ordinii. Program pentru crearea si afisarea unei liste ordonate de numere.

SOLUTII LA PROBLEME PROPUSE

Вам также может понравиться