You are on page 1of 7

Programare Procedurala

Laborator 7

Poineri
Pointer = variabil care reine o adres de memorie:
o adresa unui tip de date: elementar, structura, sir de caractere;
o adresa unei funcii: adresa la care punctul curent de execuie va sri, n cazul n care
acea funcie este apelat;
o adresa la care se afla o adresa de memorie;
o adresa unei zone cu coninut necunoscut (pointer ctre void).

Exemple

1) int x,, *a,b,*c;


x=23;
a=&x; // a primeste adresa lui x
b=*a; // b memoreaza valoarea ce se afla la adresa continuta in a
c=a; // c are acelasi continut cu a, adica o adresa (a lui x).

printf("%d\t%d\t%d",x,*a,*c);
printf("%x %x %x %x %x",&a,&b,&c,c,&x);

c b a x
60ff0c 23 60ff0c 23
0x60fef8 0x60fefc 0x60ff00 0x60ff04 0x60ff08 0x60ff0c

2) int n;

scanf("%d",&n);
printf("%x\t%x",&n,&n+1); // Concluzii?

int *p;
p=p+3; /* se incrementeaza adresa continuta de p
cu 3*sizeof(int); */

3) int x,*a,*b;
x=135;
a=&x;
b=a;
(*a)++; // rezultatul? printf("%d %d", x,*a);
*a++; // precedenta operatorilor?
printf("%d %d %x %p %x %x %x", *a,*b,a,a,b,&a,&b);

Pointeri ctre void:

1) void *p=NULL; // pointer ctre void, iniializat la NULL


2) Un pointer ctre void trebuie convertit la un pointer ctre un tip de date nante de a fi folosit,
utilizand operatorul de cast: (int *)

*p=23; // invalid use of void expression

// Atunci, convertim nti la int:

p = malloc(sizeof(int)); // alocm spaiu pentru un int (va urma)


*((int*)p) = 5;

printf("%d\n",*((int*)p));

3) Dimensiunea unui pointer depinde de arhitectura i sistemul de operare pe care a fost


compilat programul. Dimensiunea se determin cu sizeof(void *) i nu este n mod
necesar egal cu dimensiunea unui tip de date ntreg.

Pointeri la funcii

Capcana apelului fr paranteze:

int Exemplu();

int main()
{
int x;
scanf("%d",&x);
if(Exemplu)
printf("Mesaj 1");
else
printf("Mesaj 2");

return 0;
}

Greeal clasic:

1) int *p, x = 100 ;


*p = x;

De ce? Deoarece pointerului p nu i s-a atribuit iniial nicio adres, el conine una necunoscut.
Deci, la atribuirea *p = x valoarea din x este scris ntr-o locaie de memorie necunoscut. Acest tip de
problem scap de obicei neobservat cnd programul este mic, deoarece cele mai mari anse sunt ca p
s conin o adres sigur una care nu intra n zona de program, de date ori a sistemului de operare.
Dar, pe msur ce programul se mrete, crete i probabilitatea ca p s conin ceva vital. n cele din
urm, programul se va opri.

Aadar, corest este:


int *p, x = 100 ;
p=&x;

Alt exemplu:

char *p;

strcpy(p, "abc");
printf("%s",p);
Soluii

char *p="abc";
sau
char p[20];
strcpy(p, "abc");

Pointeri la structuri
Putem defini pointeri la structuri in acelasi mod in care am defini un pointer la orice alta
variabila.

Declarare:
struct struct_name *struct_pointer;

Pentru a accesa membrii unei structuri prin intermediul pointerilor, folosim operatorul ->
struct_pointer->member_name;

Instructiunea de mai sus este echivalenta cu:


(*struct_pointer).member_name;

Pentru a trimite un pointer la o structura ca argument unei functii, folosim urmatoarea sintaxa:
return_type function_name(struct struct_name *param_name);

Exemplu:

struct Book {
int book_id;
char title[50];
char author[50];
char subject[100];
};
void printBook(struct Book *book);

int main () {
struct Book *book_pointer, book1;
book_pointer = &book1;
//specificatia pentru book1:
book1.book_id = 2000;
strcpy(book1.title, Defence Against the Dark Arts);
strcpy(book1.author, Severus Snape);
strcpy(book1.subject, Defence Against the Dark Arts);

printBook(&book1);
return 0;
}

void printBook(struct Book *book) {


printf(Book title: %s\n, book->title);
printf(Book author: %s\n, book->author);
printf(Book subject: %s\n, book->subject);
printf(Book identifier: %d\n, book->book_id);
}

Putem aduga la structur pointeri la funcii


Exemplu:
struct Book {
int book_id;
char title[50];
char author[50];
char subject[100];

void (*printBook)(struct Book *book);


};

void printBook1(struct Book *book) {


printf("Book title: %s\n", book->title);
printf("Book author: %s\n", book->author);
printf("Book subject: %s\n", book->subject);
printf("Book identifier: %d\n", book->book_id);
}

void printBook2(struct Book *book) {


printf("Details: %s, %s, %s, %d ", book->title, book->author,
book->subject, book->book_id);
}

int main () {

/* declaratii, initalizari, citiri */

int x;
scanf("%d",&x);

switch(x)
{
case 1:
book1.printBook=&printBook1;
break;
default:
book1.printBook=&printBook2;
}

book1.printBook(&book1);

return 0;
}

Accesarea membrilor structurilor prin intermediul pointerilor utilizand alocarea


dinamica:
Putem aloca memorie dinamic utilizand functia malloc()din header-ul stdlib.h
Sintaxa:
ptr = (cast_type*)malloc(byte_size);

Exemplu:
int main() {
struct Book *book_ptr;
int i, n;
printf(Enter number of books: );
scanf(%d, &n);

//alocam memorie pentru n structuri Book cu book_ptr //indicand


spre adresa de baza
book_ptr = (struct Book*)malloc(n * sizeof(struct Book));

for(i = 0; i < n; ++i) {


printf(Enter book id, title, author and subject);
scanf(%d, &(book_ptr+i)->book_id);
scanf(%s, &(book_ptr+i)->title);
scanf(%s, &(book_ptr+i)->author);
scanf(%s, &(book_ptr+i)->subject);
}
//afisam informatiile despre cartile citite anterior
for(i = 0; i < n; ++i) {
printBook1(book_ptr+i);
}

return 0;
}
Probleme

1. Folosii un tablou de pointeri la funcii pentru a afia radicalul, inversul i sinusul unui
numr real citit de la tastatur. Toate funciile vor fi scrise ntr-un fiier de tip header..

2. Se citesc de la tastur un numr natural n ce reprezint dimensiunea unei matrice ptratice i


elementele unei matrice ptratice. Folosind pointeri, s se afieze elementele matricei,
elementul de la intersecia diagonalelor (pentru n impar), iar apoi elementele de pe cele dou
diagonale.

3. Creati structura student cu campurile: nr_legitimatie, nume, prenume,


medie_admitere. Construiti un fisier de tip header care sa contina functiile necesare rezolvarii
subpunctelor a) si b).

a)Folosind pointeri la structura memorati informatiile pentru n student (n citit) de la tastatura.


Informatiile despre studenti se vor citi din fisierul date.txt sub forma de stringuri, pe fiecare
rand aflandu-se cate o informatie despre student.
Date.txt are forma:
B312424
Popescu
Ion
9.50
a) Afisati cei n studenti in ordine descrescatoare dupa medie in fisierul date_out.txt. Cei
care au aceeasi medie de admitere, se vor ordona crescator dupa nume, iar pentru
coincidenta de nume se va folosi pentru sortare si campul prenume.

4. Biblioteci pentru caractere/siruri de caractere:


http://www.cplusplus.com/reference/cctype/
http://www.cplusplus.com/reference/cstring/

Autor problema: Silviu Candale, sursa: www.pbinfo.ro:

Studentii din grupa 143 s-au implicat n strngerea de cadouri pentru Crciun. Fiecare student a
adus mai multe cadouri, i a trimis prin email efului grupei o urare, nsoit de lista cadourilor.
Fiecare email are forma:
urare lista_cadouri
urare este un text care nu conine cifre. Lista cadourilor const ntr-o enumerare a cadourilor:
numar_cadouri denumire_cadou
(numar_cadouri este un numr natural, iar denumire_cadou este un cuvnt scris cu litere mici
ale alfabetului englez; numar_cadouri i denumire_cadou sunt separate prin cel puin un spaiu),
cadourile din list fiind separate prin spaii i/sau diverse semne de punctuaie.

eful grupei trebuie s centralizeze listele primite. Ajutai-l s construiasc o list a care s conin
denumirea fiecrui cadou i numrul total de cadouri de acel tip (cantitatea). Lista va fi ordonat
descresctor dup cantitate.

Date de intrare
Numrul n de studenti din grupa 1001; fiecare dintre urmtoarele n linii, conine cte un email.
Date de ieire
Pe prima linie numrul de cadouri diferite C; urmtoarele C linii vor conine cte un cadou i cantitatea
total, separate prin exact un spaiu. Lista cadouri va fi ordonat descresctor dup cantitate. Dac exist
mai multe cadouri cu aceeai cantitate, se va afia mai nti cadoul cu denumirea mai mic din punct de
vedere lexicografic.

Restricii i precizri

1 n 100
fiecare linie a fiierului de intrare conine cel mult 255 caractere
sunt cel mult 500 de cadouri diferite cu denumirea de cel mult 20 de litere ale afabetului englez
cantitatea din fiecare cadou este cel mult 100.000

Exemplu

3
La multi ani! 4 carti, 15 ciocolate , 20 bratari, 1 ceasuri.
Sarbatori fericite :) ! 3 ciocolate , 10 esarfe, 5 carti
Salut. 2 ciocolate , 1 carti. 1 ciocolate!

5
ciocolate 21
bratari 20
carti 10
esarfe 10
ceasuri 1

Indicatii:
- creem o structura cu campurile obiect si cantitate;
- folosim functia strtok pentru separarea cuvintelor / numerelor;
- odata cu separarea cuvintelor le memoram inntr-un pointer la structura;
- ordonam dupa obiect;
- parcurgem pentru a aduna cantitatile corespunzatoare obiectelor identice.

You might also like