Documente Academic
Documente Profesional
Documente Cultură
FCIM
Departamentul Informatică și Ingineria Sistemelor
RAPORT
la lucrarea de laborator nr. 1,2
Chişinău – 2019
Sarcina şi obiectivele:
• 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.
• 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.
• Î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.
Fiecare temă conţine cate două probleme care vor fi rezolvare cu mijloacele limbajului C (diferite
modele de date şi obiecte). Temele se iau în conformitate compartimentele propuse.
Lucrarea se consideră efecutată după ce studenţii demonstrează profesorului funcţionarea corectă a
programelor la calculator şi apoi prezintă darea de seamă cu analiza rezultatelor. Darea de seamă include:
foaia de titlu şi pentru fiecare lucrare să se descrie algoritmul de rezolvare a problemei, listingul
programului cu srinshot-urile, dotat cu comentariile de rigoare, Datele de intrare şi rezultatele să fie folosite
în simularea numerică şi să fie analizate în comparaţie cu rezultatele obţinute, concluzia şi bibliografia
studiată.
1. Î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, elaborind algoritmii.
INTREBĂRI ŞI EXERCIŢII
Chestiuni teoretice in mod deosebit
1. În ce constă operaţia de incrementare a pointerilor?
Exemple de incrementare:
*p++ operatorul ++ incrementeaza pointerul
(*p)++ operatorul ++ incrementeaza continutul pointerului
*++p operatorul ++ incrementeaza pointerul
++(*p) operatorul ++ incrementeaza continutul pointerului.
2. Tablouri de pointeri.
Numele unui tablou x:
este un pointer, deoarece are ca valoare adresa de memorie a primului sau element, adica
x=&x0
este un pointer constant, lui nu i se poate atribui o alta valoare (adresa).
Daca p este un pointer spre tip si t este un tablou având elemente de tipul tip, atunci
o atribuire de forma p=t este corecta, p va pointa spre primul element al tabloului
o atribuire de forma t=p este incorecta, deoarece se încearca modificarea unui pointer
constant
În consecinta, urmatoarele declaratii sunt echivalente
char a10 si char *s;
int i10 si int *i;
double d1010 si double **d;
Programul dat:
#include<stdio.h>
void main(void)
int *p_init,*p_fin;
for(p_init=sir,p_fin=sir+sizeof(sir)/sizeof(sir[0])-1;
printf("\n %d",*p_init);
}
Programul modificat:
1. #include<stdio.h>
2. void main(void)
3. { int sir[]={1,2,3,4,5,6,7,8,9}, aux;
4. int *p_init,*p_fin;
5. for(
6. p_init=sir ,p_fin=sir+sizeof(sir)/sizeof(sir[0])-1;
7. p_init<p_fin;
8. p_init++,p_fin--
9. )
10. {
11. aux=*p_init;
12. *p_init=*p_fin;
13. *p_fin=aux;
14. }
15. for(p_init = sir; p_init<sir+sizeof(sir)/sizeof(sir[0]);p_init++)
16. printf("\n %d",*p_init);
17. }
Explicație :
Programul inițial avea doar o singură erroare, el nu afișa cum trebuie elementele, condiția din
ciclul for nu era logică, eu am corectat- o, în linia (15) am pus p_init< , și acum pointerul prelua
adresa primului element al tabloului, și in fiecare iterație prelua adresa următoare al elementului,
atâta timp cât p_init este mai mic decât adresa ultimului element.
În liniile 11 – 13 avea loc așa numita sortare ,,bubble – sort,, dar cu pointeri.
Exercitiul .30: Da-ţi la execuţie pentru a înţelege principiile principale. Analizaţi definiţiile funcţiilor, modul de
organizare a apelurilor şi obţinere a rezultatelor prin antetul funcţiilor. Face-ţi îmbunătăţiri şi rulaţi din nou. Comparaţi.
Programul modificat:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdbool.h>
void SimetricPare(char*);
void SimetricImpare(char*);
void Transpune(char*);
char* Trim(char*);
void EnterProp(char*);
void SimetricImpare(char*);
void Calculate(char*);
int countPare = -1, countImpare = 50, probels = 0, len;
char *cMaiLung, *cMaiScurt, *cuvintele[10];
bool bPar = false, bImpar = false, entered = false;
int main(void)
{
char cPropozitia[125];
int i=0, j, mi;
printf("Menu:\n----------\n");
printf("1. Introducerea propozitiei\n");
printf("2. Calcule\n");
printf("3. Simetric lung pe poz.pare\n");
printf("4. Simetric scurt pe poz.impare\n");
printf("5. Transpusa\n");
printf("6. Iesire\n");
printf("\n-=Alegeti un punct al meniului=-:\n");
mi = getch();
while(mi!=(int)'6')
{ switch(mi)
{
case (int)'1': EnterProp(cPropozitia); break;
case (int)'2': if(!entered){printf("Introd. propozitia!"); break;}Calculate(cPropozitia);
break;
case (int)'3': if(!entered){printf("Introd. propozitia!");
break;}if(bPar)printf("\nSimetric Lung de pe pare: %s\n", cMaiLung);else printf("\n\nSimetric Lung pe pare
nu a fost gasit\n"); break;
case (int)'4': if(!entered){printf("Introd. propozitia!");
break;}if(bImpar)printf("\nSimetric Scurt de pe impare: %s\n", cMaiScurt);else printf("\n\nSimetric Scurt pe
impare nu a fost gasit\n"); break;
case (int)'5':
{ if(!entered){printf("Introd. propozitia!"); break;}
for(i=0; i<probels+1; i+=2)
{ Transpune(cuvintele[i]); }
if(!bPar || !bImpar)
{
puts("Propozitia transpusa: ");
for(int i=0; i<len; i++) printf("%c", cPropozitia[i]);
}
else printf("Cuvinte transpuse nu sunt\n");
}
break;
default: printf("Comanda necunoscuta\n"); break;
}
mi = getch();
}
return 0;
}
void EnterProp(char* c)
{ printf("Introduceti propozitia: ");
gets(c);
c = Trim(c);
entered = true;
return;
}
void Calculate(char* c)
{ int i, j;
len = strlen(c);
for(i=0; i<strlen(c); i++)
if(c[i]==' ')probels++;
/* SPLIT */
cuvintele[0] = strtok(c, " ");
for(i=0; i<probels; i++)
cuvintele[i+1] = strtok(NULL, " ");
/* *** */
for(i=0, j=1; i<probels+1; i+=2, j+=2) //j-pare, i-impare
{
SimetricImpare(cuvintele[i]);
if(j<probels+1)SimetricPare(cuvintele[j]);
}
printf("\nCalcule si operatii cu propozitia au fost efectuate\n");
return;
}
void SimetricPare(char* c)
{ int j=strlen(c)-1, i;
for(i=0; i<strlen(c)/2; i++, j--)
if(c[i]!=c[j])return;
bPar = true;
if(countPare<(int)strlen(c))
{ cMaiLung = c;
countPare = strlen(c);
}
return;
}
void SimetricImpare(char* c)
{ int j=strlen(c)-1, i;
for(i=0; i<strlen(c)/2; i++, j--)
if(c[i]!=c[j])return;
bImpar = true;
if(countImpare>(int)strlen(c))
{
cMaiScurt = c;
countImpare = strlen(c);
}
return;
}
void Transpune(char* cuvintul)
{ int i, j=strlen(cuvintul)-1;
char c;
for(i=0; i<strlen(cuvintul)/2; i++, j--)
{
c = cuvintul[i];
cuvintul[i] = cuvintul[j];
cuvintul[j] = c;
}
return;
}
char* Trim(char* c)
{ int index, i, j;
char* str2trim;
str2trim = c;
index = strlen(str2trim);
for(i=0, j=0; i<strlen(str2trim); i++)
{
if(str2trim[i]==' ' && str2trim[i+1]==' '){ index--; continue; }
str2trim[j] = str2trim[i];
j++;
}
str2trim[index] = '\0';
printf("%s",str2trim);
return str2trim;
}
Analiza-
*cMaiLung – In caz ca s-a gasit cuvint palindrom pe pozitie para , pointerul *cMaiLung va
lua din tabloul de pointeri cuvintele[10] cuvintul palindrome.
Sarcini laborator 2
1. Scrieţi un program cu pointeri care generează o mie de seturi de cinci numere aleatoare cuprinse între
1 şi 40, în final afişând frecvenţa cu care a fost generat fiecare număr.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int i,c,s=0;
int *p_a;
p_a = (int*) calloc(41,sizeof(int)); // alocam memorie, si o umplem cu 0
for(i=0;i<5000;i++)
{
if(i%5==0) printf("\n");
c=rand()%40+1;
printf("%3.d ",c);
p_a[c]++;
}
for(i=1;i<=40;i++){
printf("\nnumarul %d s-a intilnit de %d ori",i,p_a[i]);s+=p_a[i];}
free(p_a);
printf("\n\ns=%d",s);
}
Analiză: Inițial am alocat memorie pentru tabelul. Am alocat 41 de locuri dar nu 40 deoarece
programa lucreaza dupa principiul: cand se intilneste elementul X, elementul cu indicele X al
tabloului primeste +1, deci pointerul dat avea nevoie de 41 de locuri, caci 0 tot intra in ele, desi nu il
foloseam in program.
La fel pentru a controla corectitudinea programului am introdus variabila s, care reprezinta suma
numarului de intilniri a tuturor numerelor [1 – 40], si asa cum s –a cerut o mie de seturi a cate 5
numere, am primit s = 5000
83. (a)Functie care schimba intre ele doua linii i si j dintr-o matrice patratica.
(b)Program care foloseste functia pentru a aduce pe diagonal principala numai elemente nenule (daca este
posibil). Se va afisa matricea obtinuta prin schimbari de linii.
(a)
#include <stdio.h>
#include <stdlib.h>
void afisare(int **pt,int n);
void citire(int **pt,int n);
void schimb(int **pt,int z, int x,int n);
void main() {
//creare pointer la functie
void(*fooint)(int **pt,int n);
int **t = NULL;
int i,j,n;
printf("Introdu dimensiunile matricii:\n");
scanf("%d",&n);
// alocam memorie pentru matrice
t = (int**) calloc(n,sizeof(int*));
for (int i = 0; i < n; i++)
{
t[i] = (int*) calloc(n,sizeof(int));
}
// fooint pointer la fun. citire
fooint = citire;
fooint(&*t, n);
schimb(&*t,i-1,j-1,n);
(b)
#include <stdio.h>
#include <stdlib.h>
void afisare(int **pt,int n);
void citire(int **pt,int n);
void inloc(int **pt,int i,int n);
void main() {
//creare pointer la functie
void(*fooint)(int **pt,int n);
int **t = NULL;
int i,j,n;
printf("Introdu dimensiunile matricii:\n");
scanf("%d",&n);
// alocam memorie pentru matrice
t = (int**) calloc(n,sizeof(int*));
for (int i = 0; i < n; i++)
{
t[i] = (int*) calloc(n,sizeof(int));
}
// fooint pointer la fun. citire
fooint = citire;
fooint(&*t, n);
for(i = 0;i < n; i++)
if (t[i][i] == 0)
{
inloc(&*t,i,n);
}
// fooint pointer la fun. afisare
fooint = afisare;
fooint(&*t, n);
// golirea memoriei
for (i = 0; i < n; i++) {
free(t[i]);
}
free(t);
}
void citire(int **pt,int n){
printf("Introduceti elementele matricii:\n\n");
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d",&pt[i][j]);
}
void afisare(int **pt,int n){
printf("\nMatricea modificata:\n\n");
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
printf("%d ",pt[i][j]);
printf("\n");
}
}
void inloc(int **pt,int i,int n)
{
for(int j = 0;j < n; j++)
if (pt[i][j]!=0){
pt[i][i] = pt[i][j];
pt[i][j] = 0;
break;
}
}
Analiza: Pointerii ne –au dat noi posibilitati in programare de a modifica matrici, si nu doar una,
cu ajutorul pointerilor, in programul dat am folosit pointeri la functia de citire si de afisare.
In program am alocat memorie pentr n*n elemente de tip int (cu ajutorul calloc –ului) si massivul
cu marimea n*n are toate elementele egale cu 0.
Concluzie: In lucrarea data de laborator am exersat lucrul cu pointerii, am utilizat functia random.
Am folosit pointeri la functie, desi se putea si fara ei, dar asa cere conditia, si in unele cazuri ele
sunt foarte comode. In decursul acestei lucrari de laborator am invatat cum mai eficient sa folosesc
pointerii