Documente Academic
Documente Profesional
Documente Cultură
FCIM
Departamentul de Informatică și Inginerie Software
RAPORT
la lucrarea de laborator nr.3
la Programarea Calculatoarelor
Varianta 20
Chişinău – 2018
Scopul lucrării: Familiarizarea cu principiile prelucrării elementelor tablourilor unidimensionale.
Algoritmizarea şi însuşirea procedeelor stereotipe de declarare, introducere, afişare şi formare prin parcurgere
şi calcule ale valorilor elementelor tablourilor unidimensionale.
Obiectivele temei:
1. Însuşirea aprofundata a procedeelor avansate de realizare a structurilor ciclice cu instrucţiunile for,
while şi do while, aplicând diverse tehnici de programare.
2. Studierea principiilor prelucrării (descrierii, declarării, formării, etc.) tablourilor unidimensionale --
variabilelor cu indici şi instrucţiunilor ciclice în C.
3. Însuşirea tehnicilor fundamentale de programare a înmagazinării diferitor valori în baza
elementelor: sumei şi produsului; determinării valorilor maxime şi minime; diferitor căutări,
rearanjări şi transformări ale elementelor tablourilor.
4. Elaborarea algoritmului şi programului in C pentru rezolvarea problemei ,asigurând universalitatea.
5. Controlul corectitudinei programului cu ajutorul variantei de testare(simulare numerica).
6. Analiza eficienţei programului şi soluţiei problemei trasate.
Noţiuni generale
1. Tipul tablou (array, masiv).
Numim tablou o colectie (grup, multime ordonata) de date, de acelasi tip, situate intr-o zona de memorie
continua (elementele tabloului se afla la adrese succesive). Tablourile sunt variabile compuse (structurate),
deoarece grupeaza mai multe elemente. Variabilele tablou au nume, iar tipul tabloului este dat de tipul
elementelor sale. Elementele tabloului pot fi referite prin numele tabloului si indicii (numere intregi) care
reprezinta pozitia elementului in cadrul tabloului. Deci este o metodă de organizare a datelor este - t a b l o u
l (tabele) cu şiruri (de o lungime cunoscută) de variabile de acelaşi tip. Structura:
• Ansamblu omogen de variabile numite componentele tabloului
• Toate componentele aparţin aceluiaşi tip
• Componentele sunt identificate cu ajutorul indicilor
• Tablouri:
• Unidimensionale (1 – dimensionale)
• Bidimensionale (2 – dimensionale), etc.
Un şir de elemente de acelaşi tip se mai numeşte şi vector sau tablou unidimensional. Deci tabloul este
un tip de date compus dintr-un număr precizat de date de acelaşi tip. Referirea la elementele tabloului se face
prin numele variabilei tablou urmat de indexul elementului pus între paranteze drepte [ ].
1.1 Tipul tablou şi modurile de declarare în C
In C, tablourile unidimensionale sunt alcătuite dintr-un grup de elemente de acelaşi tip (numit tip de
baza) si referite printr-un nume comun.
Variabilele de tip tablou se definesc in maniera:
tip_de_baza nume_var [dimensiune];
. Deci tabloul se poate caracteriza prin tip, nume şi dimensiune. Formatul comun de descriere a tablourilor
este: tip nume[d1][d1]…[dn]; unde :
- tip este tipul comun pentru toate elementele tabloului, adică tipul tabloului de_baza. Tip al unui tablou
poate fi orice tip de date deja definit: întreg, real, caracterial ş.a. nume este numele tabloului. In calitate
de nume al tabloului este folosit orice identificator. Mai mult ca atât, deoarece numele tabloului este
identificator, asupra lui se răspândeşte totul ce-i indicat în compartimentul ”Nume de variabile
(identificatori)”, d1,d2,dn- dimensiunile tabloului (cifre întregi sau variabile şi atunci trebuie definite
înainte de declararea tablourilor).
- Dimensiunea tabloului indica numarul de elemente prezente in tablou. Dimensiunea tabloului poate fi o
expresie constanta cu rezultat intreg.
Un element al tabloului este accesat folosind ca index poziţia elementului, astfel tabloul_meu[6] va referi
al saptelea element al tabloului “tabloul_meu”.
Atentie! In C, "numerotarea" elementelor tablourilor începe cu poziţia 0, astfel, daca avem definitia:
int tabloul_meu[100]; unde primul element al tabloului va fi tabloul_meu[0], iar ultimul
tabloul_meu[99].
Tablourile sunt stocate in memorie la locaţii consecutive, un tablou ocupând o zona contigua de memorie, cu primul
element al tabloului aflat la adresa mai mica.
Ex.: int x[8];
Indexşii: [0] [1] [2] [3] [4] [5] [6] [7]
valorile X 23 67
[0] [3]
float data[5]=;
[0] [4]
Accesul la elementele tabloului Cu toate că tabloul este un tot întreg, nu se poate vorbi despre valoarea
tabloului întreg. Tablourile conţin elemente cu valorile cărora se operează în program. Fiecare element în
tablou îşi are indicele şi valoarea sa. În calitate de indice a unui element se foloseşte un număr întreg ce
indică numărul de ordine al elementului în tablou. Enumerarea elementelor în tablou conform numărului de
ordine se începe de la zero. Deci, indicele unui element poate avea valori de la 0 pîna la d-1, unde d este
dimensiunea tabloului.
În calitate de valoare a unui element din tablou poate servi orice număr de tipul indicat la descrierea
tabloului, adica tipul valori atribuită oricărui element din tablou trebuie să fie compatibil cu tipul tabloului.
Sintaxa de acces la orice element a unui tablou este următoarea: nume[i1][i2]..[in]. Unde nume este numele
tabloului, i1– indicele elementului în dimensiunea 1, i2-indicele elementului în dimensiunea 2, in - indicele
elementului în dimensiunea n. În cele mai dese cazuri se operează cu massive unidimensionale şi
bidimensionale. Accesul la un element al unui tablou unidimensional se face în felul următor: nume[i]; unde
nume - numele tabloului, i-numarul de ordine a elementului în tablou.
2 Instrucţiunile ciclice şi cele adiţionale în C
Instrucţiunile precăutate mai sus redau operaţii care trebuie efectuate conform algoritmului şi fiecare din
ele se îndeplinesc numai odată. În cazul, când una şi aceiaşi instrucţiune trebuie să fie executată de n ori cu
diferite valori ale parametrilor se folosesc instrucţiunile ciclice. Distingem 3 instrucţiuni ciclice în C :
1) Instrucţiunea ciclică cu parametru (FOR)
2) Instrucţiunea ciclică precedată de condiţie (WHILE)
3) Instrucţiunea ciclică cu postcondiţie (DO-WHILE)
Instrucţiunea while
Format:
while (expresie)
instrucţiune
Instrucţiunea while este o instrucţiune de ciclu condiţionat anterior şi are formatul: while(e1)
instrucţiune; antetul ciclului este while(e1) şi conţine în paranteze expresia e1 care este condiţia de repetare a ciclului.
Corpul ciclului este instrucţiune şi poate fi o instrucţiune simplă sau compusă. Ea conţine acele operaţii care trebuie
repetate în ciclu. Ciclul se execută astfel. Se evaluează e1 şi corpul ciclului se execută de atîtea ori de cîte ori e1 are
valoarea adevăr. Deci, acest ciclu realizează construcţia ciclică următoare:
false
e1
true
corpul ciclului
Instrucţiunea se execută repetat atâta timp cât valoarea expresiei este diferită de zero. Testul are loc
înaintea fiecărei execuţii a instrucţiunii. Prin urmare ciclul este următorul: se testează condiţia din paranteze
dacă ea este adevărată, deci expresia din paranteze are o valoare diferită de zero, se execută corpul
instrucţiunii while, se verifică din nou condiţia, dacă ea este adevărată se execută din nou corpul instrucţiunii.
Când condiţia devine falsă, adică valoarea expresiei din paranteze este zero, se face un salt la instrucţiunea de
după corpul instrucţiunii while, deci instrucţiunea while se termină.
Example:
a)calculează suma componentelor vectorului a de dimensiune m
suma=i=0;
while(++i< m) suma+=a[i];
b)citirea repetată de caractere până la tastarea lui 'Y'
while(getche()!='Y');
c) char *adr; while(*adr!=NULL) { if(*adr=='*')*adr='+';
adr++; };
d) while (*p == ' ') p++;
Instrucţiunea do-while
Ciclul do-while este un ciclu condiţionat posterior şi are formatul: do instrucţiune while(e1); Aici instrucţiune
este corpul ciclului şi conţine acele instrucţiuni care trebuie repetate în ciclu.
Acest ciclu realizează următoarea construcţie ciclică:
corpul ciclului
true
e1
false
Instrucţiunea do-while se execută în felul următor: mai întîi se execută instrucţiune, adică corpul ciclului, apoi
se evaluează expresia e1, care este condiţia de repetare a ciclului. Dacă e1 este adevărat, atunci se repetă execuţia
corpului ciclului. În caz contrar, adică dacă e1 este 0, atunci se termină execuţia ciclului şi se trece la instrucţiunea
următoare după ciclu.
Format:
do instrucţiuni while (expresie);
Instrucţiunea se execută repetat pînă Când valoarea expresiei devine zero. Testul are loc după fiecare
execuţie a instrucţiunii. Example:
i = 1; n = 1;
do {
n *= i;
i++;
} while (i <= factorial);
Instrucţiunea for
Format: for (expresie-1opt; expresie-2opt; expresie-3opt)
instrucţiune
Această instrucţiune este echivalentă cu:
expresie-1;
while (expresie-2) {
instrucţiune;
expresie-3;
}
Expresie-1 constituie iniţializarea ciclului şi se execută o singură dată înaintea ciclului.
Expresie-2 specifică testul care controlează ciclul. El se execută înaintea fiecărei iteraţii. Dacă condiţia
din test este adevărată atunci se execută corpul ciclului,
după care se execută expresie-3, care constă de cele mai multe ori în modificarea valorii variabilei de
control al ciclului. Se revine apoi la reevaluarea condiţiei. Ciclul se termină Când condiţia devine falsă.
Oricare dintre expresiile instrucţiunii for sau chiar toate pot lipsi.
Dacă lipseşte expresie-2, aceasta implică faptul că clauza while este echivalentă cu while (1), ceea ce
înseamnă o condiţie totdeauna adevărată. Alte omisiuni de expresii sînt pur şi simplu eliminate din
expandarea de mai sus.
Instrucţiunile while şi for permit un lucru demn de observat şi anume, ele execută testul de control la
începutul ciclului şi înaintea intrării în corpul instrucţiunii.
Dacă nu este nimic de făcut, nu se face nimic, cu riscul de a nu intra niciodată în corpul instrucţiunii.
Instrucţiunea for este o instrucţiune de ciclu condiţionat anterior şi are formatul:
for(e1; e2; e3)instrucţiune; Aici e1, e2, e3 sunt expresii. e1 este expresia de iniţializare a ciclului;
e2 este expresia care determină condiţia de repetare a ciclului; e3 este expresia de reiniţializare a ciclului.
Toate expresiile sunt poziţionale şi pot lipsi. instrucţiune este corpul ciclului şi poate fi o instrucţiune simplă
sau compusă. Corpul ciclului sunt acele instrucţiuni de prelucrare a datelor care trebuie repetate. Corpul
ciclului poate lipsi. În acest caz ciclul constă numai din antet şi instrucţiunea vidă: for(e1; e2; e3).
Instrucţiunea for se execută în felul următor: se efectuează operaţiile de iniţializare ale ciclului e1, apoi se
evaluează expresia e2. Dacă e2 are o valoare diferită de 0, adică valoarea adevăr, atunci se execută instrucţiune – corpul
ciclului. În caz contrar, atunci cînd e2 are valoarea fals, se termină execuţia ciclului for şi se trece la instrucţiunea
următoare după ciclu. După execuţia corpului, ciclul se reiniţializează – se execută operaţiile definite de e3 şi se revine
iarăşi la verificarea condiţiei de repetare a ciclului e2.
Aşadar, instrucţiunea for realizează următoarea construcţie ciclică:
e1
false
e2
corpul ciclului
e3
Exemple:
In urmatorul program, o bucla for este utilizata pentru a afisa pe ecran numerele de la 1 la 100.
#include<stdio.h>
void main ()
{ int x;
for(x=1; x<=100; x++)
printf(„%d”, x);
}
Variabila i este utilizata pe post de “contor” al instructiunii for, numarand la a cata iteratie s-a ajuns.
Executia instructiunii for se incheie atunci cand numarul de iteratii devine egal cu n, (100).
Initializarea lui i cu 1 se realizeaza o singura data, la inceput; i<=100 este conditia de continuare a
executiei;
i++ se efectueaza dupa fiecare executie a ciclului (postincrementare).
Instrucţiunea continue
Format:
continue;
Instrucţiunea continue se foloseşte numai în corpul unui ciclu şi abandonează iteraţia curentă a
ciclului şi trece la iteraţia următoare a lui. Deci instrucţiunea determină trecerea controlului la porţiunea de
continuare a ciclului celei mai interioare instrucţiuni while, do sau for care o conţine, adică la sfîrşitul ciclului
şi reluarea următoarei iteraţii a ciclului. În while şi do se continuă cu testul, iar în for se continuă cu expresie-
3.
Mai precis în fiecare dintre instrucţiunile:
while (...) { for (...) { do {
... ... ...
continue; continue; continue;
} } } while (...);
dacă apare o instrucţiune continue aceasta este echivalentă cu un salt la eticheta continue. După continue
urmează o instrucţiune vidă.
Porţiunea de program din exemplul următor prelucrează numai elementele pozitive ale unui masiv.
for (i=0; i<n; i++) {
if (a[i]<0) /* sare peste elementele negative */
continue;
……………………………………
1.2 Structura unui program în C:
Orice program in C conţine:
Introduc
lungimea vectorului
Introduc
Valorile vectorului
i=0
S=0
P=1
Max=v[1]
nu
i< i=0
da n
nu
S=s+v[i] i<
n
P=p*v[i]
da
i=i+1 nu
V[i]>ma
x
da
Max=v[i]
i=i+1
x=1/n
Ma=s/n
Mg=pow(p,x)
Afiseaza
Max, s, p, Ma, Mg
Stop
Analiza corectudinii algoritmului prin simulare numerica:
Start:
lungimea vectorului:5
elementele vectorului:
v[0]=4
v[1]=7
v[2]=6
v[3]=2
v[4]=8
Maximul=8
Suma=27
Produsul=2688
Media aritmetica=5.40
Media geometrica=4.85
stop.
4. Listing-ul programului:
#include <stdio.h> //am declarat bibliotecile
#include <stdlib.h>
int main()
{
int v[100],n,i,p=1; //declar variabilele de tip intregi
float ma,mg,s=0; //declar variabilele de tip real
printf("Dati lungimea vectorului V:");
scanf("%d",&n); //introduce lungimea vectorului
printf("Introduceti elementele vectorului:");
int max=v[1];
for(i=0;i<n;i++)
{
printf("\nv[%d]=",i);
scanf("%d",&v[i]); //introduc valorile vectorului
printf("\nMaximul=%d\nSuma=%.0f\nProdusul=%d\nMedia aritmetica=%.2f\nMedia
geometrica=%.2f",max,s,p,ma,mg); //se afiseaza rezultatele programului
}
5. După execuţia programului am obţinut următorul rezultat
pe ecran:
v[1]=3
v[2]=8
v[3]=7
Maximul=8
Suma=23
Produsul=840
Media aritmetica=5.75
Media geometrica=5.38
6. Analiza rezultatului:
1.Verificarea ne arata ca rezultatele obtinute sunt corecte si programul lucreaza
corect.
2.Algoritmii cu structura ciclica pot fi folosite pentru calcularea expresiilor
matematice.
7. Concluzii:
In urma efectuarii acestei lucrari de laborator am acumulat cunostinte si deprinderi
de efectuare a programelor in limbajul C cu structura ciclica.
Programul respectiv l-am executat prin intermediul compilatorului Code::Block.
Compilatorul Code::Block are butonul “Build & Run” care da in executie programul
elaborat. In partea de jos avem bara care ne arata pe ce linie avem eroare in cod.
Eroarea ne este comunicata intre ghilimele. Dupa lichidarea acesteia este necesar de
apasat butonul “Build & Run” pentru executia programului. Programul se salveaza
intr-un fisier cu extensia “.c”.
Am ales acest compilator deoarece este usor de utilizat si anume usureaza procesul de
vizualizare a rezultatului programului.
8. Bibliografia
Indicatii metodice nr. 2 si 3
//TEST6
#include <iostream.h>
void main()
{
int n; //numarul de elemente
int a[50]; //se defineste o variabila de tip tablou cu maxim 50 de elemente,
//deci n va trebui sa fie mai mic decat 50
int min; //variabila ce va memora minimul
int i; //contor in instructiunea for
cout<<”n=”;
cin>>n;
/* se citesc elementele sirului */
for(i=0;i<n;i++)
{
cout<<”a[“<<i<<”]=”;
cin>>a[i];
}
// se calculeaza minimul
min=a[0]; //initializam minimul cu primul element din sir
for(i=1;i<n;i++)
if (a[i]<min) min=a[i];
//afisare minim
cout<<”Minimul este=”<<min;
}
//TEST 7
#include <stdio.h>
#include <conio.h>
//#include <iostream.h> il utilizati cand folositi cout si cin
void main()
{
float a[40],suma=0,med;
int lung,i,cont=0;
printf("Introduceti lungimea vectorului :");
scanf("%d",&lung);
//cout << "Introduceti lungimea vectorului :";
//cin >> lung;
for (i=0;i<lung;i++) //parcurgerea vectorului
{
printf("a[%d]: ",i+1);
scanf("%f",&a[i]); //citirea vectorului
/*cout << "a["<<i+1<<"]: ";
cin >> a[i];*/
}
for (i=0;i<lung;i++) //parcurgerea vectorului
if (a[i]>0) //cautarea doar a numerelor pozitive
{
suma+=a[i]; //suma numerelor pozitive
cont++; //contorizator al numerelor pozitive
}
n
Xi / Yi , dacă k<=10;
F[k] = i=1
n
Xi / ec/yi , dacă k>10;
i=1
unde valorile elementelor tablourilor unidimensionale X=(x1,x2,...,xN) şi Y=(y1,y2,...,yN) sunt
reale şi se întroduc de la tastatură, n<=20; k<=20.
o Listing-ul programulu;
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
main()
{ int k,i,n,c=6; float f[256],y[256],x[256],s,p;
et1:printf("Cititm dimensiunile tablourilor x si y,trebuie sa fie mai mici de 20\n");
scanf("%d",&n);
if(n>20) goto et1;
printf("Citim valorile tabloului x\n");
for(i=1;i<=n;i++) scanf("%f",&x[i]);
printf("Citim valorile tabloului y\n");
for(i=1;i<=n;i++) scanf("%f",&y[i]);
et2:printf("\nCititm dimensiunile tablourilor f,trebuie sa fie mai mici de 20\n"); scanf("%d",&k);
if(k>20) goto et2;
if(k<=10) { for(i=1;i<k;i++) s=x[i]/y[i]; f[i]=s; }
else { p=1; for(i=1;i<k;i++) p*=x[i]/exp(c/y[i]); f[i]=p; }
printf("Tabloul F are urmatoarele valori:\n");
for(i=1;i<k;i++) printf("%f\n",f[i]);
}
Exemplul.Program care citeste doi vectori neordonati de numere distincte si verifica daca ei contin aceleasi
numere, indiferent de ordine (fara ordonarea lor). Se poate folosi programul scris si pentru vectori cu
elemente repetate diferit in cei doi vectori ? (Ex: {2,1,2,3}, {3,2,1,3})
// comparatie de vectori neordonati
#include <stdio.h>
void main () {
int n, a[]={3,1,4,2,5}, b[]={1,5,3,2,4};
int egale, este, i,j;
egale=1; // presupunem ca sunt egali
n=sizeof(a)/sizeof(a[0]); // dimensiune vector a
for (i=0;i<n;i++) {
este = 0;
for (j=0;j<n;j++) // cauta pe a[i] in vectorul b
if (a[i] == b[j])
este =1; // daca a[i] este in b
if ( ! este ) {
egale=0; break; // daca a[i] nu este in b vectori diferiti
}
}
printf (egale ? "egale\n":"diferite\n");
}
Obs. Programul se simplifica daca se defineste o functie de cautare a unui numar intr-un vector.
Exemplul. Program pentru interclasarea a doi vectori ordonati intr-un singur vector ordonat, care se
va afisa. Exemplu de date : a={2,4,6,7}, b={1,3,9,11};
Rezultat: 1,2,3,4,6,7,9,11
Veți parcurge cei 2 vectori in paralel și veți construi un nou vector, la care veți adăuga, pe rând, câte un element din
primul sau din al doilea vector (în funcție de care dintre ele este mai mic).
Intrare Ieşire
56
2 4 9 12 14 1 2 3 4 5 8 9 9 11 12 14
1 3 5 8 9 11
// interclasare vectori ordonati
void main () {
int a[100], b[100], c[200];
int na, nb, nc, ia, ib, ic, k;
// citire vectori si verificare ordonare
...
// interclasare
ia=ib=ic=1;
while ( ia <= na && ib <= nb) { // cat timp exista elem in a si in b
if ( a[ia] < b[ib] )
c[ic++]=a[ia++]; // scoate in c pe minim (a[i],b[j])
else
c[ic++]=b[ib++];
}
// copiaza in c elem. ramase in a sau in b
for (k=ia;k<=na;k++)
c[ic++]=a[k];
for (k=ib;k<=nb;k++)
c[ic++]=b[k];
nc=--ic; // dimensiune vector rezultat
// afisare vector rezultat
for (k=1;k<=nc;k++)
printf ("%d ",c[k]);
}