Documente Academic
Documente Profesional
Documente Cultură
Exmeplu:
int i,*p;
i=20;
p=&i; //referentiere - atribuim pointerului p adresa variabilei i
printf("%d", *p); //dereferentiere - afisez continului zonei de memorie a carei adresa este memorata in p
(valoarea 20), fara * langa p, se va afisa ceva de genul 2686788
c) incrementare si decrementare pointeri operatori folositi: --, ++
- micsoreaza/maresc adresa memorata in pointer cu numarul de octeti
necesari pentru a memora o data de tipul de baza al pointerului (sizeof (tip)).
- exp:
int * p; p++; //adresa memorata in p se mareste cu 2
octeti=sizeof (int)
char *p; p--; //adresa memorata se micsoreaza cu 1
(sizeof(char));
d) adunarea/scaderea dintre un pointer si un numar intreg ex. p-n, p+n
- adresa memorata in pointer se micsoreaza sau
mareste cu n*sizeof(tip).
p+n => indica al n-lea element de tipul de baza al pointerului care urmeaza dupa adresa p;
p-n => indica al n-lea element de tipul de baza al pointerului care precede elementul de la adresa p.
Legatura dintre pointeri si tablouri
Numele unui tablou este un pointer constant care are ca valoare adresa primului element din tablou.
a) Vectori pentru tip v[LungMax];, avem expresiile care sunt echivalente:
Forma 1
v
v+i
*v
*(v+i)
v++
Forma 2
&v[0]
&v[i]
v[0]
v[i]
v[1]
Comentariu
Adresa primului element din vector
Adresa elementului de pe pozitia i din vector
Primul element din vector
Elementul de pe pozitia i din vector
Elementul de pe pozitia 1
Forma 2
&mat[0]
& mat [i]
mat [0]
mat [i]
Forma 3
&mat[0][0]
&mat[i][0]
mat[i][j]
Comentariu
Adresa primei linii din matrice
Adresa liniei i din matrice
Adresa primului element de pe linia 0
Adresa primului element de pe linia i
Elementul de pe pozitia i si coloana j
II.
1. Scriei un program C care s nmuleasc o valoare cu un vector i apoi cu o matrice. Se vor realiza
subprograme pentru:
- alocare memorie vector
- alocare memorie matrice
- dezalocare memorie pentru matrice
- citire vector
- citire matrice
- afisare vector
- afisare matrice
- inmultire scalar cu vector
- inmultire scalar cu matrice
Exemplu:
Dati scalarul:2
Dati dimens vector:3
p[0]=1
p[1]=2
p[2]=3
Rezultat:
p[0]=2
p[1]=4
p[2]=6
Indicatii:
1. biblioteci: stdio.h, conio.h, malloc.h.
2. functie pentru alocare memorie vector: int *alocareV (int m) { . . . }
3. functie pentru alocare memorie matrice: int **alocareM (int m, int n) { . . . }
4. functie pentru dezalocare memorie matrice: void dezalocMDinamic(int **m1, int m) {. . .}
5. functie pentru citire vector: void citireV (int *p, int m) { . . . }
6. functie pentru citire matrice: void citireMDinamic (int **m1, int m, int n) { . . . }
7. functie pentru afisare vector: void afisareV (int *p, int m) { . . . }
8. functie pentru afisare matrice: void afisareMDinamic (int **m1, int m, int n) { . . . }
9. functie pentru inmultire scalar cu vector:
void inmCuVectDinamic (int *p, int m, int val, int *q)
{ int i;
for (i=0;i<m; i++)
*(q+i)= val * *(p+i);
}
10. functie pentru inmultire scalar cu matrice:
void inmCuMatrDinamic (int **m1, int m, int n, int val, int **m2)
{ int i,j;
for (i=0;i<m; i++)
for (j=0;j<n; j++)
*(*(m2+i)+j)= val * *(*(m1+i)+j);
}
11. in functia main:
se
se
se
se
2. Scrieti programul C care elimina o coloana dintr-o matrice alocata dinamic (numarul coloanei este citit de la tastatura).
Programul va contine subprograme pentru:
- alocare memorie pentru matrice
- dezalocare memorie pentru matrice
- citire matrice
- afisare matrice
- stergere coloana din matrice
Exemplu:
Dati dimens linii:3
Dati dimens col:3
Dati numarul coloanei de sters:1
matrice alocata dinamic
p[0][0]=1
p[0][1]=2
p[0][2]=3
p[1][0]=4
p[1][1]=5
p[1][2]=6
p[2][0]=7
p[2][1]=8
p[2][2]=9
p[0][0]=1
p[1][0]=4
p[2][0]=7
p[0][1]=2 p[0][2]=3
p[1][1]=5 p[1][2]=6
p[2][1]=8 p[2][2]=9
Rezultat
p[0][0]=1 p[0][1]=3
p[1][0]=4 p[1][1]=6
p[2][0]=7 p[2][1]=9
Indicatii:
1.biblioteci
2.functie de alocare memorie pentru matrice: int **alocareM (int m, int n) { . . . }
3.functie pentru dezalocare memorie: void dezalocM (int **mat, int m) { . . . }
4.functie pentru citire matrice: void citireM (int **m1, int m, int n) { . . . }
5.functie pentru afisare matrice : void afisareM (int **m1, int m, int n) { . . . }
6.functie pentru stergere coloana din matrice:
//IN: matricea m1, dimensiunile m si n, nr coloanei de sters nrCDeSters
//OUT: void stergColoanaMatriceDinamic (int **m1, int m, int *n, int nrCDeSters)
{ int i,j;
for (i=0;i<m;i++)
for (j=nrCDeSters;j<(*n)-1;j++)
*(*(m1+i)+j)= *(*(m1+i)+j+1);
(*n)--;
}
6.in functia main :
- declarari de tip intreg: **matr1, m, n, nrC;
- se citesc dimensiunile matricei - m si n;
- se citeste numarul de coloana care se va sterge - nrC
- se aloca memorie pentru matrice:
matr1=alocareM(m,n);
- se citeste matricea:
citireM(matr1,m,n);
- se afiseaza matricea (pentru cotrol):
afisareM (matr1,m,n);
- se sterge coloana dorita:
stergColoanaMatriceDinamic(matr1, m, &n, nrC) ;
- se afiseaza matricea modificata:
afisareM (matr1,m,n);
- se dezaloca memoria pentru matrice
dezalocM (matr1,m);
3. Scrieti programul C care sa identifice care dintre liniile unui masiv bidimensional alocat dinamic sunt egale cu un
vector dat. Se vor folosi subprograme pentru:
- alocare memorie vector si matrice
- dezalocare memorie matrice
- citire vector si matrice
- afisare vector si matrice
- indentificare linii egale cu un vector
Exemplu:
Dati dimens linii:3
Dati dimens col:3
p[0][0]= 1
p[0][1]= 2
p[0][2]= 3
p[1][0]= 4
p[1][1]= 5
p[1][2]= 6
p[2][0]= 1
p[2][1]= 2
p[2][2]= 3
Citire vector
p[0]= 1
p[1]= 2
p[2]= 3
Rezultat:
p[0]= 0
p[1]= 2
Indicatii:
1. biblioteci
2. functie pentru alocare vector: int *alocareV (int m) { . . . }
3. functie pentru alocare matrice: int **alocareM (int m, int n) { . . . }
4.functie pentru citire vector: void citireV (int *p, int m ) { . . . }
5.functie pentru citire matrice: void citireM (int **m1, int m, int n) { . . .}
6.functie pentru afisare vector: void afisareV (int *p, int m) { . . . }
7. functie pentru afisare matrice : void afisareM (int **m1, int m, int n) { . . . }
8. functie pentru verificare daca doi vectori sunt egali. Intoarce 1 daca cei doi vectori sunt egali, sau 0 daca nu
sunt egali.
//IN: vectorii p1 si p2, dimensiunea m
//OUT: b = 1 daca cei doi vectori sunt egali si 0 daca nu sunt egali
int VerifVectoriEgali (int *p1, int *p2, int m) //intoarce 1 daca cei doi vectori sunt egali, 0 daca nu
{
int i, b=1;
for (i=0;i<m;i++)
if (*(p1+i)!=*(p2+i))
{b=0;
break;
}
return b;
}
9. functia care verifica daca liniile unei matrice sunt egale cu un vector:
//IN: matricea (m1) si dimensiunile sale (m si n), vectorul v;
//OUT: vectorul rez si dimensiunea sa dim_rez. In acest vector se vor pastra valorile acelor linii //egale cu
vectorul dat.
void VerifLiniiMatriceEgalVector (int **m1, int m, int n, int *v, int **rez, int *dim_rez)//rez e un vector cu
numarul liniilor gasite egale cu vectorul dat
{ int i,j;
*dim_rez=0;
*rez = alocareV(m);
for (i=0;i<m; i++)
if (VerifVectoriEgali(*(m1+i),v,m)==1)
{ *((*rez)+*dim_rez)= i;
(*dim_rez)++;
}
}
10. in functia main :
- declarari de tip intreg : *rez1, **matr1, m, n, dim_rez1, *vect;
- se citesc dimensiunile matricei m si n;
- se aloca memorie pentru matrice:
matr1=alocareM(m,n);
- se citeste matrice:
citireM(matr1,m,n);
- se aloca memoria pentru vector:
vect=alocareV(m);
- se citeste vectorul:
printf("Citire vector \n");
citireV (vect,m);
- se verifica ce linii sunt identice cu vectorul citit:
VerifLiniiMatriceEgalVector (matr1, m, n, vect, &rez1, &dim_rez1);
- se afiseaza rezultatul:
printf("Rezultat: \n");
afisareV(rez1, dim_rez1);
III.
x=(*nume)(lista_parametrilor_actuali);
}
unde nume este parametrul formal de tip procedural.
c) apelul functiei cu parametri procedurali:
tip_rezultat nume_functie(lista_parametri_formali)
{ }
void main ()
{
f(, nume_functie, );
}
7
Atentie: a nu se confunda:
- un pointer la o functie: tip_returnat (*pointer_f) ([parametri] )
- cu o functie care are ca rezultat un pointer: tip_returnat *pointer_f ([parametri])
2. Exemple
a) Exemplu cu vectori
Enunt - Fie o functie care efectueaza o prelucrare asupra unui vector. Nu se cunoaste apriori tipul
prelucrarii, aceasta fiind descrisa de o alta functie primita ca parametru. Pot exista mai multe functii care
descriu prelucrari diferite asupra unui vector si oricare din ele poate fi transmisa ca paramteru.
Tipul prelucrarii va consta in:
- suma elementelor unui vector
- media elementelor vectorului
Exemplu numeric
Numarul de elemente(<10):5
a[0]=1
a[1]=2
a[2]=3
a[3]=4
a[4]=5
Suma elementelor:
Rezultatul prelucrarii este: 15.00
Media elementelor:
Rezultatul prelucrarii este: 3.00
Indicatii
1. Se includ bibliotecile: stdio.h, conio.h
2. Se scriu functiile de prelucrare:
- Suma elementelor unui vector:
float suma(float *v, int n)
{int i;
float s=0;
return (s);}
- Media elementelor vectorului
float media (float *v, int n)
{int i;
float m=0;
return (m);}
3. Functia functie foloseste parametrul procedural
8
10
- exemplu numeric pentru functia f(x)= x*x*x-3*x+14. Pentru solutia gasita mai jos f(-2.822266) este
aprox. -0.013072
Introduceti limitele intervalului:
-10
10
Eroarea admisa: 0.01
Numarul de iteratii: 1000
Solutia aproximativa este: -2.822266
Indicatii program
1. Biblioteci - stdio.h, conio.h, math.h
2. Prototipuri functii (bisectie si functie pentru care se aplica metoda bisectiei)
//prototipul functiei bisectie
void bisectie (float, float, float (*f)(float), float, long, int*, float *);
/*prototipul functiei pentru care se aplica metoda bisectiei*/
float fct (float);
3. In functia main:
- Se declara: float a,b,eps,x; int cod; long n;
float (*functie)(float);
- Se citesc de la tastatura: limitele intervalului (a si b), eroarea admisa (eps),
numarul de iteratii (n, ex: scanf ("%li", &n);)
- Variabila functie primeste valoare functiei fct de analizat.
functie=fct;
-
if((*f)(*x)*(*f)(a)<0)
b=*x;
else a=*x;
}
*cod=gata;
}
S se scrie funcia pentru aproximarea valorii soluiei unei ecuaii algebrice transcendente
prin metoda tangentei.
Indicatii:
Una dintre cele mai cunoscute si mai folosite tehnici de rezolvare a ecuatiilor neliniare este metoda
Newton, denumita uneori si metoda Newton-Raphson sau metoda tangentelor. Ea se deosebeste de alte
metode de aproximatii succesive prin faptul ca pentru fiecare punct din sirul aproximatiilor este necesara
atat evaluarea functiei f(x) ce defineste ecuatia, cat si a derivatei acesteia f '(x).
12
METODA NEWTON-RAPHSON
Condiia de convergen a irului, spre soluia ecuaiei, este dat de relaia
Pentru convergena metodei Newton - Raphson este necesar ca
13
Funcia are ca parametri de intrare soluia iniial (x0), numrul maxim de iteraii (n), precizia cerut (eps),
valoarea minim a tangentei (eps2), funcia asociat ecuaiei (f), derivata funciei asociate ecuaiei (fd),
derivata funciei de iteraie (gd) i adresa unde se va nscrie soluia. Funcia returneaz prin numele su un
cod cu urmtoarea semnificaie: 0 nu s-a gsit soluie datorit numrului prea mic de iteraii;
1 nu s-a gsit soluie datorit anulrii derivatei funciei asociate ecuaiei;
2 nu s-a gsit soluie deoarece metoda nu este convergent pentru datele primite;
3 s-a gsit soluie aproximativ.
int tangenta(float x0, int n, float eps, float eps2, float (*f)(float), float (*fd)(float), float(*gd)(float), float *x)
{ int cod=0;
while((n) && (!cod))
{if(fabs((*fd)(x0))<eps2) cod=1;
else if(fabs((*gd)(x0))>1) cod=2;
else {*x=x0-(*f)(x0)/(*fd)(x0);
if(fabs(*x-x0)<eps1) cod=3;
else {x0=*x; n--;}
}
}
return cod;}
Indicatie:
Pentru rezolvare se determina o diviziune a intervalului [a,b]. Considerand punctele determinate de
punctele diviziunii si valorile functiei f in acestea, se obtine o serie de trapeze dreptunghiulare alaturate.
Suma ariilor acestor trapeze aproximeaza suprafata dintre graficul functiei si axa reala, deci valoarea
integralei. Aria unui trapez dreptunghic este jumatate din produsul dintre inaltinmea trapezului si suma
bazelor.
14
Apel:
double int_a_b;
int n;
double a,b;
Int_a_b = integrala_aprox(a,b,f,n);
15