Sunteți pe pagina 1din 18

Ministеrul Еducаțiеi, Culturii și Cеrcеtării аl Rеpublicii Mоldоvа

Univеrsitаtеа Tеhnică а Mоldоvеi


Fаcultаtеа Cаlculаtоаrе, Infоrmаtică şi Micrоеlеctrоnică
Dеpаrtаmеntul Ingineria Software și Automatică

RAPORT

Lucrarea de laborator Nr.1


la disciplina Structuri de date și algoritmi

VARIANTA 6

A efectuat: st.gr.TI-192
Ciobanu Ecaterina
A verificat: asist.univ.
Cristina Josan

CHIŞINĂU – 2019
Tema: Analiza eficienţei prelucrării structurilor de date cu pointeri

Obiectivele lucrării:
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). Pentru aprofundarea înţelegerii implementarii pointeriilor
in lucrarea de laborator nr. 2 să se dezvolte algoritmii şi programele cu pointeri pentru condiţiile
problemelor din Anexa1a (Anexa2. De elaborat algoritmul și de scris programul cu pointeri si
POINTERI LA FUNCTII, propuse de profesor) şi să se elaboreze scenariile succinte de soluţionare
prin pointeri cu calculele de verificare şi explicaţii. Rularea programelor în limbajul C cu afişarea tuturor
variabilor de intrare, intermediare şi finale.
3. În raport să fie expuse toate programele şi calculele efectuate. Să se analizeze tehnica programării
eficiente cu pointeri în baza exerciţiilor şi variantelor problemelor efectuate pentru diverse situaţii cu
argumentări.

PARTEA 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.

PARTEA PRACTICĂ
Exercitiul 1: Analizati efectele utilizarii pointerilor la inversarea ordinii de apariţie a elementelor unui şir
Listing-ul programului:
#include<stdio.h>
void main(void)
{ int sir[]={1,2,3,4,5,6,7,8,9}, aux;
int *p_init,*p_fin;
for(p_init=sir,p_fin=sir+sizeof(sir)/sizeof(sir[0])-1;
p_init<p_fin; p_init++,p_fin--){ aux=*p_init; *p_init=*p_fin; *p_fin=aux; }
for(p_init=sir; p_fin=sir+sizeof(sir)/sizeof(sir[0]);
p_init++) printf("\n %d",*p_init);
}

Rezultate obținute:
Concluzie: Acest program demnstrează cum poate fi inversat un șir cu ajutorul pointerilor

Exercitiu 5. Rulaţi, afişaţi şi analizaţi

Listing-ul programului:
#include<stdio.h>
#include<conio.h>

typedef int a;
typedef a *pa;
typedef pa *ppa;
typedef ppa v1[2];
struct r1 { v1 y; };
typedef struct r1 *pr1;
typedef pr1 v2[2];
typedef v2 *pv2; a n1,n2,m1,m2;pa pn1,pn2,pm1,pm2; ppa ppn1,ppn2,ppm1,ppm2;
struct r1 art1,art2; v2 vec; pv2 x;
void main()
{

n1=100; n2=101; pn1=&n1; pn2=&n2; ppn1=&pn1; ppn2=&pn2; art1.y[0]=ppn1;


art1.y[1]=ppn2; m1=200; m2=201; pm1=&m1; pm2=&m2; ppm1=&pm1; ppm2=&pm2;
art2.y[0]=ppm1; art2.y[1]=ppm2; vec[0]=&art1; vec[1]=&art2; x=&vec;
for(int i=0;i<2;i++) for(int j=0;j<2;j++) printf("\n **(*(*x)[i]).y[j]=== %d
",i,j,**(*(*x)[i]).y[j]); getch();
}
Rezultate obținute:
Concluzie: În acest program este definit vectorul Y, format din adresele variabilelor a, pa, ppa, n, pn, ppn.
Exercitiu 7. Analizaţi
Listing-ul programului:
#include <stdio.h>

void main()
{
int x=7, y=97, s=0;
int *px, *py;
//Luam adresa variabilelor x si y
px=&x;
py=&y;
//Suma x+y
s=(*px)+(*py);
//Afisarea sumei
printf("\nSuma=%d",s);
getch();
}
Rezultate obținute:

Concluzie: În acest cod x, y se adresează direct la valoarea 7 și respectiv 97. Variabila pointer px se
adresează direct la variabila cu valoarea 7. Analog py se adresează direct la variabila cu valoarea 97.
Operația *, returnează valoarea obiectului la care operandul se pointează : s=7+97.
Exercițiul 11.: Programul de mai jos citeste si afiseaza elementele a doua tablouri, la primul accesul se
face indexat, la al doilea prin pointeri.   Rulaţi, afişaţi şi analizaţi
Listing-ul programului:
#include <stdio.h>
#include <stdlib.h>
#define N 5

int tab1[N], tab2[N];


void citire1(void) //citeste elementele lui tab 1 prin accesarea indexanta a
elementelor
{
int i;
puts("Introduceti elememtele lui tab 1:");
for(i=0;i<N;i++)
{
putchar(':');
scanf("%d", &tab1[i]);

}
}
void tiparire1(void)
{
int i;
puts("Elementele lui tab1:");
for(i=0;i<N;i++)
printf("%d ",tab1[i]);
putchar('\n');
}
void citire2(void)
{
int *pi;
puts("Introduceti elementele lui tab2");
for(pi=tab2;pi<tab2+N;pi++)
{
putchar(':');
scanf("%d",pi);
}
}
void tiparire2(void)
{
int *pi;
puts("Elementele lui tab2:");
for(pi=tab2;pi<tab2+N;pi++)
printf("%d ", *pi);
putchar('\n');
}
void main(void)
{
citire1();
tiparire1();
citire2();
tiparire2();
getche();

Rezultate obținute:
Concluzie: Programul acesta demonstrează două posibilităţi de prelucrare a elementelelor tabloului, unde
accesul prin pointeri este mai eficient. Stilul adecvat de prelucrare a elementelelor tabloului prin pointeri
constă în declararea pointerilor suplimentari pentru a stabili legăturile cu tablourile prin pointeri. şi
parcurgerea, accesul, elementelelor tabloului se face numai prin pointeri, care se mai numeşte “stilul
prelucrării cu pointeri”.

Exemplul 29: Rulaţi, afişaţi şi analizaţi


Listing-ul programului:
include<stdlib.h>
#include<stdio.h>
#include<string.h>

int main()
{
int n, i;
char (*cuvinte_u)[20] = NULL, (*cuvinte)[20]; // un pointer la un sir de
20 caractere
int *aparitii;
scanf("%d\n", &n);
cuvinte = (char (*)[20]) malloc(n * sizeof(char[20]));
i = 0;
while (i < n) { scanf("%s", cuvinte[i]); i++; }
int dim = 4, unice = 0, k; cuvinte_u = (char (*)[20]) malloc(dim *
sizeof(char[20]));
aparitii = (int *) malloc(dim * sizeof(int));
for (i = 0; i < n; i++) { int found = 0; // variabila care va indica
daca am gasit cuvantul in vectorul de aparitii unice
for (k = 0; k < unice; k++) { if (strcmp(cuvinte_u[k], cuvinte[i]) == 0)
{ aparitii[k]++; found = 1;} }
if (found != 1) { //in cazul in care vucantul nu a fost gasit in
vectorul de valori unice
if (unice >= dim) { //in cazul in care dimensiunea vectorului unic nu
a ajuns la limita
dim *= 2; aparitii = (int *) realloc(aparitii, dim * sizeof(int));
cuvinte_u = (char (*)[20]) realloc(cuvinte_u, dim * sizeof(char[20]));
}
strcpy(cuvinte_u[unice], cuvinte[i]); aparitii[unice] = 1; unice+
+; } }
for (i = 0; i < unice; i++) { //afisarea rezultatelor
printf("%s %d\n", cuvinte_u[i], aparitii[i]); } //dealocare
de memorie
free(aparitii); free(cuvinte_u); free(cuvinte);
return 0; }

Rezultate obținute:

Concluzie: Acest program citește un șir de caractere și determină de câte ori un cuvânt se regăsește în acest
șir. Aceasta se realizează prin declararea unui pointer la u șir de caractere, și prin un pointer aparitii care
numără aparițiile unui cuvânt.

Exercitiul 33: Rulați, afișați și analizați.


Listing-ul programului:
#include<stdio.h>
#include<conio.h>

int ***ppp_int; int **pp_int; int *p_int; int intreg=44;


void main()
{ p_int=(int *)malloc(sizeof(int)); pp_int=(int **)malloc(sizeof(int*));
ppp_int=(int ***)malloc(sizeof(int**)); p_int=&intreg; pp_int=&p_int;
ppp_int=&pp_int;
printf(" %d %d ", *p_int ,***ppp_int); getch(); }

Rezultate obținute:
Concluzie: Acest program afișează variabilele *p_int și ***ppp_int de tip pointer, primul pointer are adresa
variabilei de tip integer intreg, al al doilea are adresa primului pointer.

Exercitiul 43: Da-ţi la execuţie şi analizaţi modul de organizare a parcurgerii şi obţinere a rezultatelor prin
pointeri şi indecşi, afişând toate valorile. Face-ţi îmbunătăţiri şi rulaţi din nou.
Listing-ul programului:
#include <stdio.h>
main()
{int a[3][4] = {{ 5, 3, -21, 42},
{44, 15, 0, 6},
{97 , 6, 81, 2}};
int b[4][2] = {{22, 7},
{97, -53},
{45, 0},
{72, 1} };
int c[3][2],i,j,k;
for (i=0; i<3; i++) {
for (j=0; j<2; j++) {
c[i][j] = 0;
for (k=0; k<4; k++)
c[i][j] += a[i][k] * b[k][j];
}
}
for (i=0; i<3; i++) {
for (j=0; j<2; j++) printf("c[%d][%d] = %d ",i,j,c[i][j]);
printf("\n");
}
}

Rezultate obținute:
Concluzie: În acest program sunt declarate 2 matrici a și b. Fiecare element al matricii este egal cu produsul
elementelor de pe locurile i, j din matricile a și b.

Exercitiul 57: Rulaţi, afişaţi şi analizaţi.


Listing-ul programului:
#include <stdio.h>
#include <stdlib.h>
int 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"); } return
0; }
Rezultate obținute

Concluzie: Acest program aloca memorie dinamică pentru un tablou bidimensional. Elementele matricii se
calculează după formula mat[i][j]=n*i+j+1. După execuția programului observăm că el lucrează corect.

Exercitiul 59: Modificaţi programul prin parcurgeri de pointeri şi cu pointeri la pointeri (indirectare
multipla). Apoi Rulaţi, afişaţi şi analizaţi
Listing-ul programului:
#include <conio.h>;
#include <stdio.h>;
#include <stdlib.h>;
void main() { int *p,*a,i,j,n,k,s,l; char ch; printf("Indicati dimensiunea
matricei:"); scanf("%d",&n);
a=(int *) malloc(n*n); //Alocarea dinamica a memoriei
p=a; // pointu p se initializeaza cu pointu a
for(i=0;i<n;i++)
for(j=0;j<n;j++) { printf("a[%d,%d]=",i+1,j+1);
scanf("%d",p++); } //Se introduce valori in pointu p si pointu p intorudce
valorile in pointu a
while(1) {
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' : printf("Elementele matricei sunt:\n"); p=a;
//initializarea pointurului p cu a
for(i=0;i<n;i++) {
for(j=0;j<n;j++)

printf(" %d",*p++); printf("\n"); } // afisharea valorilor din point


printf("Elementele prime ale liniilor impare
sunt:\n");

p=a; // Initializam pointu p cu pointu 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++; //daca valoarea pointului
p la impartire cu k =0
k++; }
if(s==2 || *p==1) //daca cointu p =1
printf(" %d",*p); p++; } // afisharea
valoarea pointului p
p+=n; } getch();break;
case '2' : printf("Elementele maricei sunt:\n");

p=a; //initializam pointu p cu pointu a


for(i=0;i<n;i++) {
for(j=0;j<n;j++)
printf(" %d",*p++); printf("\n"); } //
afisham valorile pointului p
printf("Suma elementele impare ale coloanelor pare
sunt:\n");
s=0; p=a; //Initializam pointu cu poinru a
for(i=0;i<n;i++)
for(j=1;j<n;j+=2)
if(*(p+i*n+j)%2==1) //daca valoarea
p[i][j]/2==1
s+=*(p+i*n+j); //la s se adauga valoarea p[i]
[j]

printf("s=%d",s); getch(); break;

case '3' : printf("Elementele maricei sunt:\


n");
p=a;
for(i=0;i<n;i++) {
for(j=0;j<n;j++)
printf(" %d",*p++); printf("\
n");}//afisez valoarea pointului
printf("Indicati numarul la care doriti sa aflati frecventa:
");
scanf("%d",&k);
s=0; p=a; // initializarea pointului p cu
poitu 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++; //daca pointu p[i][j]=k
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++; //daca pointu p[i][j]=k
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();
}
}
}

Rezultate obținute:

Concluzie: Acest program permite alocarea dinamică a memoriei pentru un tablou bidimensional.
Elementele tabloului sunt citite de la tastatură. Asupra matricii se pot efectu adiferite operații precum:
afișarea elementelor prime, suma elementelor impare, frecvența unui element indicat.
Exercitiul 61: Analizati efectele utilizarii funcţiilor de caractere prin precizarea valorilor care se afiseaza pe
ecran la executia programului.
Listing-ul programului
#include <stdio.h>
int a[5][5]; int b[25]; int i,j;
void f1(void) { int q=0,w=0; printf("introduceti vectorul");
while(i<25){scanf("%d",&b[i]);i++;}
for(i=0;i<25;i++) { a[q][w]=b[i];
if(w<4){w++;} else if(q<4){q+
+;w=0;} }
printf("matricea obţinută din vector este:");
for(i=0;i<5;i++){ printf("\n"); for(j=0;j<5;j++) printf(" %d ",a[i][j]);}
/*exit(); */ }
void f2(void) { int k=0; char t=0;
for(i=0;i<5;i++) for(j=0;j<5;j++) { scanf("%d",&a[i][j]);}
for(i=0;i<5;i++) for(j=0;j<5;j++) { b[k]=a[i][j];
k++; }
printf("vectorul primit din matrice e:");
for(i=0;i<k;i++) printf(" %d \n",b[i]); }
main() {printf("1:matrice->vector\t2:vector->matrice\n");
if(getchar()=='2') {f1();} else f2(); }

Rezultate obținute

Concluzie: Acest program permite convertirea unei matrici într-un vector și al unui vector într-o matrice.
Exercitiul63: Da-ţi la execuţie şi analizaţi modul de organizare a parcurgerii şi obţinere a rezultatelor prin
pointeri şi indecşi, afişând toate valorile.
Listing-ul programului:
#include <stdio.h>
int a[ ] = { 8, 7, 6, 5, 4 };
int *p[ ] = { a, a+1, a+2, a+3, a+4 };
int **pp = p;
main() { printf("*a=%d **p=%d **pp=%d\n", *a, **p, **pp );
pp++; printf("pp-p=%d *pp-a=%d **pp=%d\n", pp-p, *pp-a, **pp );
++*pp; printf("pp-p=%d *pp-a=%d **pp=%d\n", pp-p, *pp-a, **pp );
pp = p; ++**pp; printf("pp-p=%d *pp-a=%d **pp=%d\n", pp-p,
*pp-a, **pp ); }

Rezultate obținute:

Concluzie: Acest program arată cum se execută operațiile simple( în acest caz scăderea) cu elementele
vectorilor, alocați dimanic.
Exercitiul 65: Da-ţi la execuţie şi analizaţi modul de organizare şi obţinere a rezultatelor , afisind fiecare
pas.
Listing-ul programului:
#include<stdio.h>
#include<conio.h>
int a;
int *pa;
int **ppa;
int ***pppa;
int ****ppppa;
int *****pppppa;
void main(){
a=33;
pa=&a;
ppa=&pa;
pppa=&ppa;
ppppa=&pppa;
pppppa=&ppppa;
printf("\n%d",*****pppppa);
getch();
}

Rezultate obținute:

Concluzie: Programul dat afișeză mai mulți un pointer la un pointer. Se regăsește o succesiune de pointeri
cu acceași adresă, în rezultat ultima valoare coincide cu valoarea variabilei a.
Exercitiul 67: Da-ţi la execuţie şi analizaţi modul de organizare şi obţinere a rezultatelor .
Listing-ul programului:
#include<stdio.h>
#include<conio.h>
typedef char* f();
f *a[2][2];//o matrice de pointeri spre functii
char *s;
char *f1(){ return "functia1"; } char* f2(){ return "functia2"; }
char* f3(){ return "functia3"; } char* f4(){ return "functia4"; }
void main(){ a[0][0]=f1; a[0][1]=f2; a[1][0]=f3; a[1][1]=f4;
for(unsigned char i=0;i<2;i++) for(unsigned char j=0;j<2;j++){ s=a[i][j]();
printf("\n %s",s); } getch(); }

Rezultate obținute:

Concluzie: Acest program declară o matrice e pointeri spre funcții.


Exercitiul69 :Rulați, afișați și analizați.
Listing-ul programului:
#include <stdio.h>
#include <math.h>
#define N 50
double f(double x);
double SumaPatrateFunctii (double (*f)(double), double x[], int n);
void main() { double x,tab[50], pas=2 * M_PI/N, s1,s2; int i;
for(i=x=0; i <N ; x+=pas) tab[i++]=x;
s1=SumaPatrateFunctii (sin, tab, N);
s2=SumaPatrateFunctii (f, tab, N);
printf("\nS1=%lf \nS2=%lf", s1,s2); }
//---------------------------------------------------------------
double SumaPatrateFunctii (double (*f)(double), double x[], int n)
{ double sumap=0;
for(n--; n>=0; n--) sumap+= f(x[n]) * (*f)(x[n]); return sumap; }
//----------------------------------------------------------------
double f(double x) { return 1./(x+1); }
Rezultate obținute:

Concluzie: Acest program calculează și afișează suma pătratelor prin intermediul funcțiilor.

Exerciții la care codurile nu se compilează sau nu lucrează corect: 3, 9, 13, 15, 17, 19, 21, 23, 25, 27, 31, 33,
35, 37, 39, 41, 43, 45,47, 49, 51, 53, 55, 65, 71.
CONCLUZIE
Lucrarea de laborator nr 1 face cunoștință studenților cu tipurile dimanice de date, alocarea dinamică
a memoriei și folosirea pointerilor în programe în limbajul de programare C. În lucrare sunt prezentate mai
multe exemple de programe cu pointeri care arată cum se pot utiliza eficient datele dimanice în operații
aritmetice, prelucrarea tablourilor unidimensionale și bidimensionale, folosirea pointerilor la funcții etc.
BIBLIOGRAFIE:
1. Indicațiile metodice
2. "Limbajul de programare C". Brian W.Kernighan. Dennis M.Ritchie.

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