Sunteți pe pagina 1din 19

Ministeriul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei

Raport
la lucrarea de laborator nr.3
la Programarea Calculatoarelor
Tema: Prelucrarea tablourilor unidimensionale n TP i C

Varianta nr.35

Elaborat: Mazurchevici Ion


Grupa: TI -162
Verificat : Foca Petru

Chiinu 2016
Obiectivele temei:

I. Familiarizarea cu principiile prelucrrii elementelor tablourilor unidimensionale.


II. Algoritmizarea i nsuirea procedeelor stereotipe de declarare, introducere, afiare i formare
prin parcurgere i calcule ale valorilor elementelor tablourilor unidimensionale.
III. nsuirea procedeelor avansate de realizare a structurilor ciclice cu instruciunile for, while i
repeat, aplicnd diverse tehnici de programare.
IV. nsuirea procedeelor de operare n interfaa TP i C la nivelul submeniurilor DEBUG i
BREAK/WATCH (mijloacele de depanare-urmrire a variabilelor i punctele de ntrerupere).

Subiectele temei i ordinea executrii:


I. Studierea principiilor prelucrrii (descrierii, declarrii, formrii, etc.) tablourilor
unidimensionale -- variabilelor cu indici i instruciunilor ciclice n C i recapitularea n TP.
II. Studierea metodelor de introducere i afiare clar a tablourilor unidimensionale.
III. Analizai i rspundei la ntrebrile de autocontrol.
IV. nsuirea tehnicilor fundamentale de programare a nmagazinrii diferitor valori n baza
elementelor: sumei i produsului; determinrii valorilor maxime i minime; diferitor
cutri, rearanjri i transformri ale elementelor tablourilor.
V. Elaborarea algoritmului i programului n C pentru rezolvarea problemei (variantele vezi n
TESTE n C i Anexa L.lab nr.3), asigurnd corectitudinea i universalitatea.
VI. Depanarea programului i verificarea la PC a problemei trasate cu diverse combinaii de date.
VII. Controlul corectitudinei programului cu ajutorul variantei de testare.
VIII. Analiza eficienei programului i soluiei problemei trasate.

Noiuni generale
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 acelai tip. Structura:
Ansamblu omogen de variabile numite componentele tabloului
Toate componentele aparin aceluiai tip
Componentele sunt identificate cu ajutorul indicilor
Tablouri:
Unidimensionale (1 dimensionale)
Bidimensionale (2 dimensionale), etc.
Un ir de elemente de acelai tip se mai numete i vector sau tablou unidimensional. Deci
tabloul este un tip de date compus dintr-un numr precizat de date de acelai 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 alctuite dintr-un grup de elemente de acelai 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
att, deoarece numele tabloului este identificator, asupra lui se rspndete 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 poziia elementului, astfel
tabloul_meu[6] va referi al saptelea element al tabloului tabloul_meu.
Atentie! In C, "numerotarea" elementelor tablourilor ncepe cu poziia 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 locaii consecutive, un tablou ocupnd o zona contigua
de memorie, cu primul element al tabloului aflat la adresa mai mica.
Ex.: int x[8];
Indexii: [0] [1] [2] [3] [4] [5] [6] [7]

23 67
valorile X

Rezult: x[0]=23; ,,,, x[5]=67;


Atentie! O problema legata de tablouri este ca in C nu se face nici o verificare legata de
"marginile" tabloului, astfel ca se pot accesa greit elemente din afara tabloului. De exemplu,
pentru definiia:
int tabloul_meu[100]; daca accesam tabloul_meu[105] nu se va semnala nici o eroare,
returnndu-se valoarea de la o locaie de memorie aflata la o distanta de 5 locaii fa de sfritul
tabloului, fapt ce va duce la comportri "bizare" ale programului. Aceeai situaie, dar fa de
nceputul tabloului, se ntmpla la accesarea tabloul_meu[-5].
int vect[20]; /* declararea tabloului vect, de maximum 20 de elemente, de tipul int.
Elementele tabloului vect sunt : vect[0], vect[1], ., vect[19] - date de tip int*/
double p,q,tab[10]; // declararea variabilelor simple p, q si a vectorului tab, de maximum 10
elemente, tip double
#define MAX 10
char tab[MAX]; /*declararea tabloului tab, de maximum MAX (10) elemente de tip
char*/
Consideram declaratia tabloului v cu maxim 6 elemente de tip int
int v[6];
Elementele tabloului pot fi initializate prin atribuire:
v[0]=100;
v[1]=101;
v[2]=102;
v[3]=103;
v[4]=104;
v[5]=105;
100 101 102 103 104 105
v[0] v[1] v[2] v[3] v[4] v[5]

Iniializarea tablourilor. Deseori e necesar ca elementele tabloului s posede valori chiar la


momentul descrierii tabloului. Procesul de atribuire a valorilor elementelor tabloului n timpul
descrierii lui se numete iniializarea tabloului. Sintaxa de iniializare a unui tablou
unidimensional este:
tip nume[d]={v0,v1,v2,,vn-1};
unde tip este tipul tabloului, nume este numele tabloului, v0,v1,v2,vn-1 valorile respective ale
elementelor nume[0],nume[1] etc. Exemplu:
int x[8]={1,3,15,7,19,11,13,5};
E de menionat faptul, c indicii tabloului se schimb ncepnd dela zero.Adic la descrierea
tabloului valoarea maxim a indicelui tabloului coincide cu numrul de elemente n tablou minus
unu. La iniializarea tabloului nu e numaidect de indicat dimensiunile tabloului.Compilatorul va
determina numrul elementelor dup descrierea tabloului i va forma un tablou cu mrimea
respectiv. De exemplu:
int x[]={1,3,15,7,19,11,13,5};
Variabilele tablou pot fi initializate in momentul declararii:
declaratie_tablou=lista_valori;
La declararea unui vector cu initializarea elementelor sale, numarul maxim de elemente ale
tabloului poate fi omis, caz in care compilatorul determina automat marimea tabloului, in functie
de numarul elementelor initializate. Exemplu:
char tab[]=;

[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 conin elemente cu valorile crora se opereaz n
program. Fiecare element n tablou i are indicele i valoarea sa. n calitate de indice a unui
element se folosete un numr ntreg ce indic numrul de ordine al elementului n tablou.
Enumerarea elementelor n tablou conform numrului de ordine se ncepe de la zero. Deci,
indicele unui element poate avea valori de la 0 pna la d-1, unde d este dimensiunea tabloului.
n calitate de valoare a unui element din tablou poate servi orice numr de tipul indicat la
descrierea tabloului, adica tipul valori atribuit oricrui element din tablou trebuie s fie
compatibil cu tipul tabloului. Sintaxa de acces la orice element a unui tablou este urmtoarea:
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 urmtor: nume[i]; unde nume - numele tabloului, i-
numarul de ordine a elementului n tablou.

2 Instruciunile ciclice i cele adiionale n C


Instruciunile precutate mai sus redau operaii care trebuie efectuate conform algoritmului i
fiecare din ele se ndeplinesc numai odat. n cazul, cnd una i aceiai instruciune trebuie s fie
executat de n ori cu diferite valori ale parametrilor se folosesc instruciunile ciclice. Distingem
3 instruciuni ciclice n C :
1) Instruciunea ciclic cu parametru (FOR)
2) Instruciunea ciclic precedat de condiie (WHILE)
3) Instruciunea ciclic cu postcondiie (DO-WHILE)
Instruciuni de salt
C are 4 instruciuni care execut ramificri necondiionate: return, goto, break i
continue. Dintre acestea, return i goto pot s se gseasc oriunde n program. Instruciunile
break i continue pot fi utilizate mpreun cu oricare din instruciunile de buclare.

Instruciunea continue
Format:
continue;
Instruciunea continue se folosete numai n corpul unui ciclu i abandoneaz iteraia
curent a ciclului i trece la iteraia urmtoare a lui. Deci instruciunea determin trecerea
controlului la poriunea de continuare a ciclului celei mai interioare instruciuni while, do sau for
care o conine, adic la sfritul ciclului i reluarea urmtoarei iteraii a ciclului. n while i do se
continu cu testul, iar n for se continu cu expresie-3.
Mai precis n fiecare dintre instruciunile:
while (...) { for (...) { do {
... ... ...
continue; continue; continue;
} } } while (...);
dac apare o instruciune continue aceasta este echivalent cu un salt la eticheta continue.
Dup continue urmeaz o instruciune vid.
Poriunea de program din exemplul urmtor prelucreaz numai elementele pozitive ale
unui masiv.
for (i=0; i<n; i++) {
if (a[i]<0) /* sare peste elementele negative */
continue;
... /* prelucreaz elementele pozitive */
}
Instruciunea return
Instruciunea return se folosete pentru a reveni dintr-o funcie. O instruciune return
permite ieirea dintr-o funcie i transmiterea controlului apelantului funciei. O funcie poate
returna valori apelantului su, prin intermediul unei instruciuni return.
Formate:
return;
return expresie;
n primul caz valoarea returnat nu este definit. n al doilea caz valoarea expresiei este
returnat apelantului funciei. Dac se cere, expresia este convertit, ca ntr-o atribuire, la tipul
funciei n care ea apare.
Instruciunea vid
Instruciunea vid este util pentru a introduce o etichet naintea unei acolade drepte,
ntr-o instruciune compus, sau pentru a introduce un corp nul ntr-o instruciune de ciclare care
cere corp al instruciunii, ca de exemplu while sau for.
Exemplu:
for (nc=0; s[nc]!=0; ++nc) ;
Aceast instruciune numr caracterele unui ir. Corpul lui for este vid, deoarece tot lucrul se
face n partea de test i actualizare dar sintaxa lui for cere un corp al instruciunii. Instruciunea
vid satisface acest lucru.
Instruciune de salt Break Pernmite ntreruperea necondiionat a unei secvene i
continuarea programului dintr-un alt punct.

Instruciunea BREAK. Se utilizeaz n dou contexte, pentru a marca ncheierea secvenei de


instruciuni asociate unui selector case, i instruciunea de ciclare, pentru a determina ieirea
forat dintr-un ciclu while, do_while, sau for.
Instructiunea cu etichet GOTO: goto et --identificator. Are ca efect ntreruperea secvenei
curente i continuarea execuiei de la instruciunea cu eticheta identificatorului, ce trebuie s se
afle n aceai funcie.
Totodat, avnd la dispoziie instruciunile goto i if, programatorul poate programa diferite
operaii complicate.
Exemplu :Folosirea instruciunilor if i goto la organizarea ciclurilor. Acest program
calculeaz valoarea lui y care este egal cu _n/(n+5),unde n=1,..,50
#define lim 50
main() {
int n=0; float y=0;
m1: ++n;
if(n<=lim) {
y+=n/(n+50);goto m1;} }

Prima linie a programului e menit preprocesorului, cruia i se indic valoarea constantei


lim=50. Astfel se procedeaz n cazul cnd vom necesita schimbarea limitei de sumare. Pentru
aceasta trebuie schimbat doar directiva #define, iar substituirile corespunztoare n textul
programului preprocesorul le va face fr participarea noastr. Programul const dintr-o singur
funcie main(), corpul creia e definit cu ajutorul acoladelor exterioare. Instruciunea if are aici
forma prescurtat, avnd ca instruciune un bloc, care conine instruciunea goto, ce ne d
posibilitatea calculrii ciclice a sumei. n ncheiere menionm c utilizarea if i goto la
organizarea ciclurilor e un semn de cultura insuficient de programare. Exemplu dat arat numai
cum se poate organiza un ciclu cu ajutorul instruciunilor if i goto, dar n nici un caz nu servete
drept exemplu pentru copiere. La organizarea ciclurilor n limbajul de programare Turbo C se
folosesc alte posibiliti, cu mult mai fine.

ntrebrile de autocontrol:
1. Transcriei exemplul programului din lucrarea de laborator nr.2, utiliznd instruciunile ciclice.
2. Elaborai algoritmul i programul pentru cazul dac suma a trei numere reale cu valori diferite
x,y,z este mai mic dect unitatea, atunci cel mai mic numr din aceste trei, de schimbat cu
semisuma a celorlalte dou, n caz contrar (Cnd suma este mai mare ) de schimbat valoarea
minimal dintre x i y cu semisuma a celorlalte valori rmase.
3. Modificai exemplul 3.2* pentru trei tablouri unidimensionale X, Y, Z i efectuai aceleai
calcule.
4. Elaborai algoritmul i programul pentru cazul cnd sunt date 100 numere ntregi pentru care
trebuie de calculat diferena maxim i minim ntre ele.

5. Elaborai algoritmul i programul pentru determinarea. dac un numr natural e perfect, adic
care este egal cu suma tuturor divizorilor.(de exemplu 6=1+2+3).

Problema propus:
S se elaboreze algoritmul i programul pentru urmtoarele: Sa se ordoneze un vector astfel
incat elementele de pe pozitiile impare vor fi ordonate crescator iar cele de pe pozitiile pare sa
fie ordonate descrecator.
Elaborarea schemei logice:

A
Start

i=1
"introdu n\n" j=n
k=1

"%d",&n

"introdu elementele vectorului\n" Nu


k<=n

Da
i=1;i<=n;i++
b[k]=a[i]
b[k+1]=a[j]
k=k+2
"%d",&a[i]

i++

i=1;i<=n-1;i++ j--

j=i;j<=n;j++

Da i=1;i<=n;i++
a[i]>a[j]

Nu " %d",b[i]
q=a[i]
a[i]=a[j]
a[j]=q
Sfrit

Elaborarea programului propriuzis:


#include<stdio.h>
#include<math.h>
main(){
int a[100],b[100],i,j,q,n,k;
printf("introdu n\n");
scanf("%d",&n);
printf("introdu elementele vectorului\n");
for (i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for (i=1;i<=n-1;i++){
for (j=i;j<=n;j++){
if (a[i]>a[j]){
q=a[i];
a[i]=a[j];
a[j]=q;
}
}
}
i=1;j=n; k=1;
while (k<=n){
b[k]=a[i];
b[k+1]=a[j];
k=k+2;
i++;j--;
}
for(i=1;i<=n;i++){
printf(" %d",b[i]);
}
}
1) Transcriei exemplul programului din lucrarea de laborator nr.2, utiliznd instruciunile ciclice.
Elaborarea schemei logice:

Start

q=1.01
r=0.2
s=1.3
e=2.71828

Nu
r<1.0

D
a
w=(s-sin(r*r))+pow(log(r/q),3)
ff=(pow(e,-w)* pow(abs(r-w),(1/2)))/s*s

"w=%f ff=%f\n",w,ff

r=r+0.1

Sfrit

Elaborarea programului propriuzis:


#include<stdio.h>
#include<math.h>
int main(){
float q,s,w,r,ff,e;
q=1.01;
r=0.2;
s=1.3;
e=2.71828;
while (r<1.0){
w=(s-sin(r*r))+pow(log(r/q),3);
ff=(pow(e,-w)* pow(abs(r-w),(1/2)))/s*s;
printf("w=%f ff=%f\n",w,ff);
r=r+0.1;
}
}

2) Elaborai algoritmul i programul pentru cazul dac suma a trei numere reale cu valori diferite
x,y,z este mai mic dect unitatea, atunci cel mai mic numr din aceste trei, de schimbat cu
semisuma a celorlalte dou, n caz contrar (Cnd suma este mai mare ) de schimbat valoarea
minimal dintre x i y cu semisuma a celorlalte valori rmase.
Elaborarea programului propriuzis:
#include<stdio.h>
#include<math.h>
int main(){
float x,y,z,k;
printf("introdu x \n");
scanf("%f",&x );
printf("introdu y \n");
scanf("%f",&y );
printf("introdu z \n");
scanf("%f",&z );
k=0;
if (x+y+z<1){
if ( x<y && x<z && k==0 ){
x=(y+z)/2; k++;
}
if ( y<x && y<z && k==0 ){
y=(x+z)/2; k++;
}
if ( z<x && z<y && k==0 ){
z=(x+y)/2; k++;
}
}
else {
if (x<y){
x=(y+z)/2;
}
else{
y=(x+z)/2;
}
}
printf("x=%f, y=%f, z=%f",x,y,z);
}

Elaborarea schemei logice:


Start

"introdu x \n"

"%f",&x

"introdu y \n"

"%f",&y

"introdu z \n"

"%f",&z

k=0

Nu Da
x+y+z<1

Da
Nu Da x<y && x<z && k==0
x<y

Nu
y=(x+z)/2 x=(y+z)/2 x=(y+z)/2

k++

Da
y<x && y<z && k==0

Nu
y=(x+z)/2

k++

Da
z<x && z<y && k==0

Nu
z=(x+y)/2

k++

"x=%f, y=%f, z=%f",x,y,z

Sfrit
3) Modificai exemplul 3.2* pentru trei tablouri unidimensionale X, Y, Z i efectuai aceleai
calcule.
Elaborarea programului propriuzis:
#include<stdio.h>
#include<math.h>
int main(){
float x[100],y[100],z[100]; int n,i,k;
printf("introdu n \n");
scanf("%d",&n);
printf("introdu %d elemente ale tabloului x \n",n);
for (i=1;i<=n;i++){
scanf("%f",&x[i]);
}
printf("introdu %d elemente ale tabloului y \n",n);
for (i=1;i<=n;i++){
scanf("%f",&y[i]);
}
printf("introdu %d elemente ale tabloului z \n",n);
for (i=1;i<=n;i++){
scanf("%f",&z[i]);
}

for (i=1;i<=n;i++){
k=0;
if (x[i]+y[i]+z[i]<1){
if ( x[i]<y[i] && x[i]<z[i] && k==0 ){
x[i]=(y[i]+z[i])/2; k++;
}
if ( y[i]<x[i] && y[i]<z[i] && k==0 ){
y[i]=(x[i]+z[i])/2; k++;
}
if ( z[i]<x[i] && z[i]<y[i] && k==0 ){
z[i]=(x[i]+y[i])/2; k++;
}
}
else {
if (x[i]<y[i]){
x[i]=(y[i]+z[i])/2;
}
else{
y[i]=(x[i]+z[i])/2;
}
}
}
printf("\ntabloul x: ");
for (i=1;i<=n;i++){
printf( "%.2f ", x[i]);
}
printf("\ntabloul y: ");
for (i=1;i<=n;i++){
printf( "%.2f ", y[i]);
}
printf("\ntabloul z: ");
for (i=1;i<=n;i++){
printf( "%.2f ", z[i]);
}
}
4) Elaborai algoritmul i programul pentru cazul cnd sunt date 100 numere ntregi pentru care
trebuie de calculat diferena maxim i minim ntre ele.

Elaborarea schemei logice:

Start

int a[100],i,j,min,max,n

"introdu n \n"

"%d",&n

"introdu %d elemente ale tabloului \n",n

i=1;i<=n;i++

"%d",&a[i]

min=a[1]-a[2]
max=a[1]-a[2]

i=1;i<=n;i++

j=1;j<=n;j++

Da
a[i]-a[j]<min && i!=j

Nu
min=a[i]-a[j]

Da
a[i]-a[j]>max && i!=j

Nu
max=a[i]-a[j]

"diferenta minima si maxima sunt %d, %d", min, max

Sfrit
Elaborarea programului propriuzis:
#include<stdio.h>
#include<math.h>
int main(){
int a[100],i,j,min,max,n;
printf("introdu n \n");
scanf("%d",&n);
printf("introdu %d elemente ale tabloului \n",n);
for (i=1;i<=n;i++){
scanf("%d",&a[i]);
}
min=a[1]-a[2];
max=a[1]-a[2];
for (i=1;i<=n;i++){
for (j=1;j<=n;j++){
if (a[i]-a[j]<min && i!=j){
min=a[i]-a[j];
}
if (a[i]-a[j]>max && i!=j){
max=a[i]-a[j];
}
}
}
printf("diferenta minima si maxima sunt %d, %d", min, max);
}
5) Elaborai algoritmul i programul pentru determinarea. dac un numr natural e perfect, adic
care este egal cu suma tuturor divizorilor.(de exemplu 6=1+2+3).
Elaborarea schemei logice:

Start

"introdu n\n"

"%d",&n

sum=0

i=1;i<=n; i++

Da
n%i==0 && n!=i

Nu
sum=sum+i

Nu Da
n==sum

"%d nu este numar perfect",n "%d este numar perfect",n

Sfrit

Elaborarea programului propriuzis:


#include<stdio.h>
#include<math.h>
main(){
int n,i,sum;
printf("introdu n\n");
scanf("%d",&n);
sum=0;
for (i=1;i<=n; i++){
if (n%i==0 && n!=i){
sum=sum+i;
}
}
if (n==sum){
printf("%d este numar perfect",n);
}
else {
printf("%d nu este numar perfect",n);
}
}

Concluzie

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