Sunteți pe pagina 1din 8

Universitatea Tehnică a Moldovei

Facultatea Calculatoare Informatică și Microelectronică


Departamentul Ingineria Software și Automatică

RAPORT
la lucrarea de laborator nr. 1

la Structuri de Date și Algoritmi

Tema: Analiza eficienței prelucrării structurilor de date cu pointeri

Varianta 3 72

A efectuat: Chiforiuc Adrian


A verificat: Prijilevschi Dumitru

Chişinău 2020
Scopul lucrării
1. Verificarea corectitudinii scrierii programelor în limbajul de programare C.
2. Corectarea și explicarea erorilor apărute în urma compilării și lansării
programului.
Obiectivele temei
1. De studiat şi însuşit materialul teoretic din lucrarea dată si prin lansarea
exerciţiilor la execuţie pentru analiza şi evidenţierea esenţialului prelucrării
structurilor de date cu pointeri în elaborarea modelelor soluţiei prin explicaţii,
argumentări şi organigrame.
2. In baza materialului teoretic la prima lucrare de laborator efectuati cate 2
exerciţii (unul de la inceput si altul de la alt capat ) şi să se analizeze algoritmii şi si
specificul organizarii programelor cu si fără pointeri (declarări şi parcurgeri cu
pointeri).
Extras Teoretic
Orice program care realizează un produs are nevoie de eficacitate fără să mai
vorbim de driverele la care se lucrează continuu pentru câteva procente de viteză în
plus. Poate că raportată la explozia calculatoarelor, a programelor prietenoase, a
bazelor de date, a paginilor Web, pare în scădere, însă de fapt nevoia de viteză este
din ce în ce mai mare şi mult timp această nevoie nu va dispărea.
Variabilele pot fi statice sau dinamice. Cele statice au o zonă de memorie bine
definită. Structura, locul, tipul acestei zone nu poate fi schimbată în procesul
execuţiei programului. Accesul la variabilele statice se face direct, după nume.
Structurile statice de date au un număr fix de elemente, care nu poate fi modificat.
Alocarea memoriei se face într-un spaţiu strict determinat al memoriei, care
permite adresarea directă.
O altă categorie de variabile, accesibile în limbaje este cea dinamică. Pentru acest
tip de variabile poate fi modificat volumul de memorie rezervat, ceea ce face mai
flexibilă alocarea memoriei în procesul de lucru al programului. Structurile
dinamice pot acumula elemente în procesul de funcţionare al programului, sau pot
lichida elementele ce au devenit neutilizabile. Accesul la aceste variabile şi
declararea lor se face în mod diferit de cel al variabilelor statice. Accesarea
(definirea) este indirectă, prin intermediul unui tip mediator de variabile – tipul
referinţă. Variabile de tip referinţă conţin referiri (adresări indirecte) la variabilele
dinamice. Referirea se realizează prin memorarea în variabila referinţă a adresei
unde e stocată variabila dinamică.Pentru variabilele tip referinţă se alocă un spaţiu
de memorie de 4 octeţi, care conţin adresa variabilei dinamice. Memoria pentru
variabilele dinamice se alocă dintr-o zonă specială, care foloseşte adresarea
indirectă, numită heap. Această zonă este diferită de zona pentru variabilele statice.
Rezolvare

Ex 3
# include “ studio.h”

main ( )

{ int i, *pi, **ppi; /* se declara un intreg , un pointer la int. si un pointer la pointer la


int. */

pi = & i ; /* initializarea pointerului pi cu adresa lui i */

ppi = & pi; /* initializarea lui ppi cu adresa lui pi */

printf ( “ pi = %p ppi = %p \ n” , pi, ppi) ;

*pi = 7; /*Echivalent cu i = 7 */

printf (“ i = %d \ n “, i );

i = *pi – 3 ; / * Echivalent cu i = i - 3 ; */

printf ( “ i = % d \ n “, i) ;

*pi = **ppi*2; /* Echivalent cu i = i* 2 ; */

printf ( “ i = % d \ n “, i) ;

Erori:
 Funcția main nu contine tipul in fața denumirii.
 Funcțiile „printf” nu lucreaza deoarece nu a fost încărcată corect bibliuteca <stdio.h>
 Erori cauzate din cauza unor greseli sintactice a programului

Programul corectat :
#include <stdio.h>
int main (void)
{ int i, *pi, **ppi; /*se declara un intreg, un pointer la int. si un pointer la pointer
la int. */
pi= &i ; /* initializarea pointerului pi cu adresa lui i */
ppi= &pi; /* initializarea lui ppi cu adresa lui pi */
printf ("pi = %p ppi = %p \n" , pi, ppi) ;
*pi = 7; /*Echivalent cu i = 7 */
printf ("i = %d \n", i );
i = *pi-3 ; /* Echivalent i = i - 3 ; */
printf ("i = % d \n", i) ;
*pi = **ppi*2; /* Echivalent cu i = i* 2 ; */
printf ("i = % d \n", i) ;
}

Ex 72
#include <conio.h>;
#include <stdio.h>;
#include <stdlib.h>;
void main() { int *p,*a,i,j,n,k,s,l; char ch;
//clrscr();
printf("Indicati dimensiunea matricei:"); scanf("%d",&n);
a=(int *) malloc(n*n); p=a;
for(i=0;i<n;i++) for(j=0;j<n;j++) { printf("a[%d,%d]=",i+1,j+1); scanf("%d",p+
+); }
while(1)
{ //clrscr();
printf("1 - afisarea elementelor prime\n"); printf("2 - suma elementelor impare\n");
printf("3 - frecventa elementului indicat\n"); printf("4 - iesire\n"); ch=getche();
switch (ch) {
case '1' : //clrscr();
printf("Elementele matricei sunt:\n"); p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) printf(" %d",*p++); printf("\n"); }
printf("Elementele prime ale liniilor impare sunt:\n");
p=a;
for(i=0;i<n;i+=2) {
for(j=0;j<n;j++) { k=1;s=0;
while(k<=*p && *p!=0) { if(*p%k==0) s++; k++; }
if(s==2 || *p==1) printf(" %d",*p); p++; } p+=n; }
getch();break;
case '2' : //clrscr();
printf("Elementele maricei sunt:\n"); p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) printf(" %d",*p++); printf("\n"); }
printf("Suma elementele impare ale coloanelor pare
sunt:\n"); s=0; p=a;
for(i=0;i<n;i++)
for(j=1;j<n;j+=2) if(*(p+i*n+j)%2==1) s+=*(p+i*n+j);
printf("s=%d",s); getch(); break;
case '3' : //clrscr();
printf("Elementele maricei sunt:\n"); p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) printf(" %d",*p++); printf("\n"); }
printf("Indicati numarul la care doriti sa aflati frecventa: "); scanf("%d",&k);
s=0; p=a;
if(n%2==0) l=n/2-1; else l=n/2;
for(i=0;i<l;i++) for(j=i+1;j<n-i-1;j++)
if(*(p+i*n+j)==k) s++; printf("\n Frecventa in cadranul 1 este:
%d",s);
s=0; for(i=n/2+1;i<n;i++)for(j=i-1;j>=n-i;j--)
if(*(p+i*n+j)==k) s++;
printf("\n Frecventa in cadranul 3 este: %d",s); getch();
break;
case '4' : getch(); exit(1); break;
default: printf("\nTastati intre 1 si 3 !\n");
getch();
}
}
}
Erori :
 În liniile 1, 2 și 3 după conectarea bibliotecilor, este plasat semnul „ ; ”(punct și
virgulă) chiar daca nu este necisitate și creaza erori.
 În linia 12, funcția getch() este apelată greșit ch=getche().
Programul corectat:
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
int main() { int *p,*a,i,j,n,k,s,l; char ch;
//clrscr();
printf("Indicati dimensiunea matricei:"); scanf("%d",&n);
a=(int *) malloc(n*n); p=a;
for(i=0;i<n;i++) for(j=0;j<n;j++) { printf("a[%d,%d]=",i+1,j+1); scanf("%d",p+
+); }
while(1)
{ //clrscr();
printf("1 - afisarea elementelor prime\n"); printf("2 - suma elementelor impare\n");
printf("3 - frecventa elementului indicat\n"); printf("4 - iesire\n"); ch=getch();
switch (ch) {
case '1' : //clrscr();
printf("Elementele matricei sunt:\n"); p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) printf(" %d",*p++); printf("\n");}
printf("Elementele prime ale liniilor impare sunt:\n");
p=a;
for(i=0;i<n;i+=2) {
for(j=0;j<n;j++) { k=1;s=0;
while(k<=*p && *p!=0) { if(*p%k==0) s++; k++; }
if(s==2 || *p==1) printf(" %d",*p); p++; } p+=n; }
getch();break;
case '2' : //clrscr();
printf("Elementele maricei sunt:\n"); p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) printf(" %d",*p++); printf("\n"); }
printf("Suma elementele impare ale coloanelor pare
sunt:\n"); s=0; p=a;
for(i=0;i<n;i++)
for(j=1;j<n;j+=2) if(*(p+i*n+j)%2==1) s+=*(p+i*n+j);
printf("s=%d",s); getch(); break;
case '3' : //clrscr();
printf("Elementele maricei sunt:\n"); p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) printf(" %d",*p++); printf("\n");}
printf("Indicati numarul la care doriti sa aflati frecventa: ");
scanf("%d",&k); s=0; p=a;
if(n%2==0) l=n/2-1; else l=n/2;
for(i=0;i<l;i++) for(j=i+1;j<n-i-1;j++)
if(*(p+i*n+j)==k) s++; printf("\n Frecventa in cadranul 1
este: %d",s);
s=0; for(i=n/2+1;i<n;i++) for(j=i-1;j>=n-i;j--)
if(*(p+i*n+j)==k) s++;
printf("\n Frecventa in cadranul 3 este: %d",s);
getch(); break;
case '4' : getch(); exit(1); break;
default: printf("\nTastati intre 1 si 3 !\n");
getch();
}
}
}

Întrebări de autocontrol:
1. Operațiunea de incrementare a pointerilor constă în marirea adresei pointerului cu
numărul de octeți al tipului pointerului (int, char...) , astfel valoarea expresiei devine
ptr+sizeof(tip).
2. Tablourile sau array-urile care se creează cu ajutorul pointerilor, de obicei se creează
cu ajutorul unui dublu-pointer (**ptr) care reprezintă un array ce conține în sine adresele
la o mulțime definită de array-uri(tablou bidimensional).
3. La declararea pointerilor generici ( void nume; ) nu se specifica un tip, deci unui
pointer void i se pot atribui adrese de memorie care pot contine date de diferite tipuri:
int, float, char, etc. Acesti pointeri pot fi folositi cu mai multe tipuri de date, de aceea
este necesara folosirea conversiilor explicite prin expresii de tip cast, pentru a preciza
tipul datei spre care pointeaza la un moment dat pointerul generic.
4. Operații cu pointeri:
 Atribuire
 Adunare
 Scadere
 Comparare
 Incrementare
 Decrementare
5. În limbajele C/C++ exista o strânsa legatura între pointeri si tablouri, deoarece
numele unui tablou este un pointer (constant!) care are ca valoare adresa primului
element din tablou. Diferenta dintre numele unui tablou si o variabila pointer este aceea
ca unei variabile de tip pointer i se pot atribui valori la executie, lucru imposibil pentru
numele unui tablou. Acesta are tot timpul, ca valoare, adresa primului sau element. De
aceea, se spune ca numele unui tablou este un pointer constant (valoarea lui nu poate
fi schimbata). Numele unui tablou este considerat ca fiind un rvalue (right value-valoare
dreapta), deci nu poate apare decât în partea dreapta a unei expresii de atribuire.
Numele unui pointer (în exemplul urmator, ptr) este considerat ca fiind un lvalue (left
value-valoare stânga), deci poate fi folosit atât pentru a obtine valoarea obiectului, cât si
pentru a o modifica printr-o operatie de atribuire.
6. Variabile de tip Int, char, float(double).
7. Doar tipul Int.
8. Da
9. Numele unui tablou este un pointer constant care are ca valoare adresa primului
element din tablou.
10. Deoarece acesta poate fi folosit atât pentru a obtine valoarea obiectului, cât si
pentru a o modifica printr-o operatie de atribuire.

Concluzie: În această lucrare de laborator am analizat structurile de date cu pointeri


prin lansarea și corectarea greșelilor în programele din documentul laboratorului, astfel
am obținut o experiență necesară care are drept scop minimizarea greșelilor în lucrul cu
pointeri și funcții. De asemenea am studiat și analizat materialul teoretic din lucrarea
dată, lansând la execuție pentru analiza și evidențierea esențialului prelucrării
structurilor de date cu pointeri și elaborarea metodelor de soluționare și explicare a
problemelor apărute în decursul elaborării programelor cu ajutorul pointerilor.

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